fix: memoize in-flight acquire so concurrent acquire() is re-entrant-safe (E00-S03-T04)
CI / Frozen lockfile install (pull_request) Successful in 49s
CI / Secrets not embedded (E00-S02-T08) (pull_request) Successful in 26s
CI / Database-postgres import isolation (E00-S03-T02) (pull_request) Successful in 26s
CI / Migration ledger (E00-S03-T03) (pull_request) Successful in 45s
CI / Migration advisory lock (E00-S03-T04) (pull_request) Successful in 50s
CI / Compose config (E00-S03-T01) (pull_request) Successful in 25s

Security-review finding F2: two concurrent acquire() calls on the same
MigrationLock instance could each check out a connection; the second
pg_advisory_lock would overwrite this.client, leaking the first locked
connection until session end.

acquire() now memoizes the in-flight acquire in acquireInFlight and
returns it on re-entry, so exactly one connection is checked out and no
locked connection leaks. The memo is cleared once the acquire settles.
tryAcquire()/release() paths unchanged.

Locked in by:
- static criterion test: acquireInFlight field, re-entry guard returns
  the in-flight acquire, memo cleared on settle
- mutation probe: removing the re-entry guard fails the criterion
- real-stack probe: two concurrent acquire() calls on one instance leave
  pool.totalCount at 1 (exactly one connection), the lock granted once,
  nothing left after release; probe fails (hangs) on the pre-fix code
- CI job comment updated to reflect the re-entrancy criterion
This commit is contained in:
implementer
2026-08-30 00:29:20 +00:00
parent a2b98439e9
commit dac3679e33
3 changed files with 150 additions and 20 deletions
+9 -7
View File
@@ -80,13 +80,15 @@ jobs:
# E00-S03-T04: the static assertions of tests/database-postgres-lock.test.mjs
# gate every PR — the suite locks in the migration advisory lock (session-
# scoped pg_advisory_lock/pg_try_advisory_lock over a stable keyed hash on a
# dedicated connection, driver-boundary re-export) with mutation probes, and
# the docker-gated real-stack concurrent probe (a second runner waits or
# fails while the first holds the lock; the lock releases when the holding
# session ends) runs where a Docker daemon is available and skips cleanly
# otherwise. The job installs the frozen workspace because the real-stack
# probe executes the committed lock module from the host (it imports `pg`
# through the package's own links).
# dedicated connection, re-entrant-safe in-flight acquire so concurrent
# acquire() calls share one connection, driver-boundary re-export) with
# mutation probes, and the docker-gated real-stack concurrent probe (a
# second runner waits or fails while the first holds the lock; concurrent
# acquire() checks out exactly one connection; the lock releases when the
# holding session ends) runs where a Docker daemon is available and skips
# cleanly otherwise. The job installs the frozen workspace because the
# real-stack probe executes the committed lock module from the host (it
# imports `pg` through the package's own links).
database-postgres-lock:
name: Migration advisory lock (E00-S03-T04)
runs-on: ubuntu-latest