-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #26 from dapper91/dev
- asyncpg connection manager added.
- Loading branch information
Showing
15 changed files
with
158 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import asyncio | ||
|
||
import asyncpg | ||
|
||
from generic_connection_pool.asyncio import ConnectionPool | ||
from generic_connection_pool.contrib.asyncpg import DbConnectionManager | ||
|
||
Endpoint = str | ||
Connection = asyncpg.Connection | ||
|
||
|
||
async def main() -> None: | ||
dsn_params = dict(database='postgres', user='postgres', password='secret') | ||
|
||
pg_pool = ConnectionPool[Endpoint, 'Connection[asyncpg.Record]']( | ||
DbConnectionManager[asyncpg.Record]( | ||
dsn_params={ | ||
'master': dict(dsn_params, host='db-master.local'), | ||
'replica-1': dict(dsn_params, host='db-replica-1.local'), | ||
'replica-2': dict(dsn_params, host='db-replica-2.local'), | ||
}, | ||
), | ||
acquire_timeout=2.0, | ||
idle_timeout=60.0, | ||
max_lifetime=600.0, | ||
min_idle=3, | ||
max_size=10, | ||
total_max_size=15, | ||
background_collector=True, | ||
) | ||
|
||
try: | ||
# connection opened | ||
async with pg_pool.connection(endpoint='master') as conn: | ||
result = await conn.fetchval("SELECT inet_server_addr()") | ||
print(result) | ||
|
||
# connection opened | ||
async with pg_pool.connection(endpoint='replica-1') as conn: | ||
result = await conn.fetchval("SELECT inet_server_addr()") | ||
print(result) | ||
|
||
# connection reused | ||
async with pg_pool.connection(endpoint='master') as conn: | ||
result = await conn.fetchval("SELECT inet_server_addr()") | ||
print(result) | ||
|
||
finally: | ||
await pg_pool.close() | ||
|
||
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
""" | ||
Postgres asyncpg connection manager implementation. | ||
""" | ||
|
||
from typing import Generic, Mapping, Optional, TypeVar | ||
|
||
import asyncpg | ||
|
||
from generic_connection_pool.asyncio import BaseConnectionManager | ||
|
||
DbEndpoint = str | ||
Connection = asyncpg.Connection | ||
DsnParameters = Mapping[DbEndpoint, Mapping[str, str]] | ||
|
||
RecordT = TypeVar('RecordT', bound=asyncpg.Record) | ||
|
||
|
||
class DbConnectionManager(BaseConnectionManager[DbEndpoint, 'Connection[RecordT]'], Generic[RecordT]): | ||
""" | ||
Psycopg2 based postgres connection manager. | ||
:param dsn_params: databases dsn parameters | ||
""" | ||
|
||
def __init__(self, dsn_params: DsnParameters): | ||
self._dsn_params = dsn_params | ||
|
||
async def create( | ||
self, | ||
endpoint: DbEndpoint, | ||
timeout: Optional[float] = None, | ||
) -> 'Connection[RecordT]': | ||
return await asyncpg.connect(**self._dsn_params[endpoint]) # type: ignore[call-overload] | ||
|
||
async def dispose( | ||
self, | ||
endpoint: DbEndpoint, | ||
conn: 'Connection[RecordT]', | ||
timeout: Optional[float] = None, | ||
) -> None: | ||
await conn.close(timeout=timeout) | ||
|
||
async def check_aliveness( | ||
self, | ||
endpoint: DbEndpoint, | ||
conn: 'Connection[RecordT]', | ||
timeout: Optional[float] = None, | ||
) -> bool: | ||
return conn.is_closed() | ||
|
||
async def on_acquire(self, endpoint: DbEndpoint, conn: 'Connection[RecordT]') -> None: | ||
await self._rollback_uncommitted(conn) | ||
|
||
async def on_release(self, endpoint: DbEndpoint, conn: 'Connection[RecordT]') -> None: | ||
await self._rollback_uncommitted(conn) | ||
|
||
async def _rollback_uncommitted(self, conn: 'Connection[RecordT]') -> None: | ||
if conn.is_in_transaction(): | ||
await conn.execute('ROLLBACK') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[tool.poetry] | ||
name = "generic-connection-pool" | ||
version = "0.6.1" | ||
version = "0.7.0" | ||
description = "generic connection pool" | ||
authors = ["Dmitry Pershin <[email protected]>"] | ||
license = "Unlicense" | ||
|
@@ -30,6 +30,7 @@ classifiers = [ | |
[tool.poetry.dependencies] | ||
python = ">=3.9" | ||
psycopg2 = {version = ">=2.9.5", optional = true} | ||
asyncpg = {version = "^0.29.0", optional = true} | ||
|
||
furo = {version = "^2023.7.26", optional = true} | ||
Sphinx = {version = "^6.2.1", optional = true} | ||
|
@@ -39,6 +40,7 @@ sphinx-copybutton = {version = "^0.5.2", optional = true} | |
|
||
[tool.poetry.extras] | ||
psycopg2 = ["psycopg2"] | ||
asyncpg = ["asyncpg"] | ||
docs = ['Sphinx', 'sphinx_design', 'sphinx-copybutton', 'furo', 'toml'] | ||
|
||
[tool.poetry.dev-dependencies] | ||
|
@@ -50,6 +52,8 @@ pytest-mock = "^3.11.1" | |
pytest-cov = "^4.1.0" | ||
types-psycopg2 = "^2.9.21" | ||
pytest-timeout = "^2.1.0" | ||
asyncpg-stubs = {version = "^0.29.0", python = ">=3.9,<4.0"} | ||
|
||
|
||
[build-system] | ||
requires = ["poetry-core>=1.0.0"] | ||
|