connect() built the pool with `await asyncpg.create_pool(...)` outside the
try that wraps SELECT-1 validation - with the default min_size=1 the pool
connects eagerly, so a bad host/auth propagated with no log.exception line,
breaking the documented "every method logs then re-raises" contract.
create_pool() now sits inside the same try/log/re-raise as validation, and
either failure point tears down a partially-built pool before re-raising.
close() didn't take _connect_lock while connect() did, so a close() racing
an in-flight connect() would see _pool is None and no-op as success while
connect() went on to install a live pool - a shutdown handler racing a
reconnect could "close" the instance while real connections stayed open.
close() now takes the same lock via a shared _close_locked() helper.
Signed-off-by: disqualifier <dev@disqualifier.me>
- close() sets self._pool = None (in a finally, even on driver-error close) so a closed
instance reports not-connected instead of masquerading as still-connected against a
dead pool (the pool property now raises RuntimeError post-close as intended).
- connect() is now guarded by an internal asyncio.Lock: concurrent connect() calls
serialize instead of each racing to build + orphan its own live pool. Twin fix with
mysql at the same Layer-1 signature level.
- docstrings tightened (module header lifecycle/dsn notes, __init__ dsn note) with zero
behavior change; re-verified against a real embedded postgres.
verified against pixeltable-pgserver (test-only): 8 concurrent connect() calls now leave
0 orphaned pools + exactly 1 live pool (old: 7 orphaned, 8 live simultaneously); close()
now flips the connected-check to False (old: stayed True against a dead pool). full
layer-1/layer-2/transaction/concurrency regression suite still green. fresh-venv install
confirms runtime purity (asyncpg only, no pixeltable-pgserver). bump v0.1.4 -> v0.1.5
Signed-off-by: disqualifier <dev@disqualifier.me>
col = $n bound to NULL never matches in sql, so get/get_one/exists/delete
silently missed every row filtered on a None value despite insert() writing
NULL fine. Kept in lockstep with the mysql lib's identical fix.
Signed-off-by: disqualifier <dev@disqualifier.me>
connect() now closes an existing pool before re-connecting (no orphan on double-connect),
and tears down the freshly-built pool if the SELECT-1 validation fails before re-raising
(no leaked pool on a failed connect). verified vs embedded postgres. bump v0.1.1 -> v0.1.2
Signed-off-by: disqualifier <dev@disqualifier.me>
_Transaction.__aenter__ acquired a connection then called tx.start(); if start() raised
(stale pooled conn after failover/idle-timeout — a fail-loud path), __aexit__ never ran so
the connection leaked, draining the pool until transaction() deadlocked on acquire(). now
release-on-failure. verified: 6 forced start-failures (2x pool) no longer exhaust the pool.
bump v0.1.0 -> v0.1.1
Signed-off-by: disqualifier <dev@disqualifier.me>