Skip to content

Commit 0561ada

Browse files
authored
Merge pull request #26 from dapper91/dev
- asyncpg connection manager added.
2 parents 0167e97 + 431f2b4 commit 0561ada

File tree

15 files changed

+158
-28
lines changed

15 files changed

+158
-28
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,6 @@ repos:
7171
name: mypy
7272
pass_filenames: false
7373
additional_dependencies:
74-
- types-psycopg2
74+
- types-psycopg2>=2.9.5
75+
- asyncpg-stubs>=0.29.0
7576
args: ["--package", "generic_connection_pool"]

CHANGELOG.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Changelog
22
=========
33

4+
0.7.0 (2023-12-09)
5+
------------------
6+
7+
- asyncpg connection manager added.
8+
9+
410
0.6.1 (2023-10-06)
511
------------------
612

README.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ The following example illustrates how to create https pool:
110110
111111
112112
try:
113-
fetch('https://en.wikipedia.org/wiki/HTTP') # http connection is opened
114-
fetch('https://en.wikipedia.org/wiki/Python_(programming_language)') # http connection is reused
113+
fetch('https://en.wikipedia.org/wiki/HTTP') # http connection opened
114+
fetch('https://en.wikipedia.org/wiki/Python_(programming_language)') # http connection reused
115115
finally:
116116
http_pool.close()
117117
@@ -148,19 +148,19 @@ The following example illustrates how to create https pool:
148148
)
149149
150150
try:
151-
# connection is opened
151+
# connection opened
152152
with pg_pool.connection(endpoint='master') as conn:
153153
cur = conn.cursor()
154154
cur.execute("SELECT * FROM pg_stats;")
155155
print(cur.fetchone())
156156
157-
# connection is opened
157+
# connection opened
158158
with pg_pool.connection(endpoint='replica-1') as conn:
159159
cur = conn.cursor()
160160
cur.execute("SELECT * FROM pg_stats;")
161161
print(cur.fetchone())
162162
163-
# connection is reused
163+
# connection reused
164164
with pg_pool.connection(endpoint='master') as conn:
165165
cur = conn.cursor()
166166
cur.execute("SELECT * FROM pg_stats;")

docs/source/pages/api.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ _______
3030
.. automodule:: generic_connection_pool.contrib.socket_async
3131
:members:
3232

33-
.. automodule:: generic_connection_pool.contrib.psycopg2
34-
:members:
35-
3633
.. automodule:: generic_connection_pool.contrib.unix
3734
:members:
3835

3936
.. automodule:: generic_connection_pool.contrib.unix_async
4037
:members:
38+
39+
.. automodule:: generic_connection_pool.contrib.psycopg2
40+
:members:
41+
42+
.. automodule:: generic_connection_pool.contrib.asyncpg
43+
:members:

docs/source/pages/quickstart.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ ____________________
7373

7474
After the pool is instantiated a connection can be acquired using :py:meth:`~generic_connection_pool.threading.ConnectionPool.acquire`
7575
and released using :py:meth:`~generic_connection_pool.threading.ConnectionPool.release`.
76-
To get rid of boilerplate code the connection manager supports automated acquiring using
76+
To get rid of boilerplate code the connection pool supports automated connection acquiring using
7777
:py:meth:`~generic_connection_pool.threading.ConnectionPool.connection` returning a context manager:
7878

7979

@@ -87,7 +87,7 @@ To get rid of boilerplate code the connection manager supports automated acquiri
8787
Connection aliveness checks
8888
___________________________
8989

90-
Connection manager provides an api for connection aliveness checks.
90+
Connection manager provides the api for connection aliveness checks.
9191
To implement that override method :py:meth:`~generic_connection_pool.threading.BaseConnectionManager.check_aliveness`.
9292
The method must return ``True`` if connection is alive and ``False`` otherwise:
9393

examples/async_pg_pool.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import asyncio
2+
3+
import asyncpg
4+
5+
from generic_connection_pool.asyncio import ConnectionPool
6+
from generic_connection_pool.contrib.asyncpg import DbConnectionManager
7+
8+
Endpoint = str
9+
Connection = asyncpg.Connection
10+
11+
12+
async def main() -> None:
13+
dsn_params = dict(database='postgres', user='postgres', password='secret')
14+
15+
pg_pool = ConnectionPool[Endpoint, 'Connection[asyncpg.Record]'](
16+
DbConnectionManager[asyncpg.Record](
17+
dsn_params={
18+
'master': dict(dsn_params, host='db-master.local'),
19+
'replica-1': dict(dsn_params, host='db-replica-1.local'),
20+
'replica-2': dict(dsn_params, host='db-replica-2.local'),
21+
},
22+
),
23+
acquire_timeout=2.0,
24+
idle_timeout=60.0,
25+
max_lifetime=600.0,
26+
min_idle=3,
27+
max_size=10,
28+
total_max_size=15,
29+
background_collector=True,
30+
)
31+
32+
try:
33+
# connection opened
34+
async with pg_pool.connection(endpoint='master') as conn:
35+
result = await conn.fetchval("SELECT inet_server_addr()")
36+
print(result)
37+
38+
# connection opened
39+
async with pg_pool.connection(endpoint='replica-1') as conn:
40+
result = await conn.fetchval("SELECT inet_server_addr()")
41+
print(result)
42+
43+
# connection reused
44+
async with pg_pool.connection(endpoint='master') as conn:
45+
result = await conn.fetchval("SELECT inet_server_addr()")
46+
print(result)
47+
48+
finally:
49+
await pg_pool.close()
50+
51+
asyncio.run(main())

examples/async_pool.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ async def main() -> None:
2424

2525
async def fetch(url: str, timeout: float = 5.0) -> None:
2626
url = urllib.parse.urlsplit(url)
27+
if url.hostname is None:
28+
raise ValueError
29+
2730
port = url.port or 443 if url.scheme == 'https' else 80
2831

2932
async with http_pool.connection(endpoint=(url.hostname, port), timeout=timeout) as (reader, writer):
@@ -56,8 +59,8 @@ async def fetch(url: str, timeout: float = 5.0) -> None:
5659
print(b''.join(chunks))
5760

5861
try:
59-
await fetch('https://en.wikipedia.org/wiki/HTTP') # http connection is opened
60-
await fetch('https://en.wikipedia.org/wiki/Python_(programming_language)') # http connection is reused
62+
await fetch('https://en.wikipedia.org/wiki/HTTP') # http connection opened
63+
await fetch('https://en.wikipedia.org/wiki/Python_(programming_language)') # http connection reused
6164
finally:
6265
await http_pool.close()
6366

examples/custom_manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def command(addr: IPv4Address, port: int, cmd: str) -> None:
6969

7070

7171
try:
72-
command(IPv4Address('127.0.0.1'), 6379, 'CLIENT ID') # tcp connection is opened
73-
command(IPv4Address('127.0.0.1'), 6379, 'CLIENT INFO') # tcp connection is reused
72+
command(IPv4Address('127.0.0.1'), 6379, 'CLIENT ID') # tcp connection opened
73+
command(IPv4Address('127.0.0.1'), 6379, 'CLIENT INFO') # tcp connection reused
7474
finally:
7575
redis_pool.close()

examples/pg_pool.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,22 @@
2727
)
2828

2929
try:
30-
# connection is opened
30+
# connection opened
3131
with pg_pool.connection(endpoint='master') as conn:
3232
cur = conn.cursor()
33-
cur.execute("SELECT * FROM pg_stats;")
33+
cur.execute("SELECT inet_server_addr()")
3434
print(cur.fetchone())
3535

36-
# connection is opened
36+
# connection opened
3737
with pg_pool.connection(endpoint='replica-1') as conn:
3838
cur = conn.cursor()
39-
cur.execute("SELECT * FROM pg_stats;")
39+
cur.execute("SELECT inet_server_addr()")
4040
print(cur.fetchone())
4141

42-
# connection is reused
42+
# connection reused
4343
with pg_pool.connection(endpoint='master') as conn:
4444
cur = conn.cursor()
45-
cur.execute("SELECT * FROM pg_stats;")
45+
cur.execute("SELECT inet_server_addr()")
4646
print(cur.fetchone())
4747

4848
finally:

examples/ssl_pool.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525

2626
def fetch(url: str, timeout: float = 5.0) -> None:
2727
url = urllib.parse.urlsplit(url)
28+
if url.hostname is None:
29+
raise ValueError
30+
2831
port = url.port or 443 if url.scheme == 'https' else 80
2932

3033
with http_pool.connection(endpoint=(url.hostname, port), timeout=timeout) as sock:
@@ -46,7 +49,7 @@ def fetch(url: str, timeout: float = 5.0) -> None:
4649

4750

4851
try:
49-
fetch('https://en.wikipedia.org/wiki/HTTP') # http connection is opened
50-
fetch('https://en.wikipedia.org/wiki/Python_(programming_language)') # http connection is reused
52+
fetch('https://en.wikipedia.org/wiki/HTTP') # http connection opened
53+
fetch('https://en.wikipedia.org/wiki/Python_(programming_language)') # http connection reused
5154
finally:
5255
http_pool.close()

0 commit comments

Comments
 (0)