Files
PaperClipAI/packages/db
DottaandPaperclip 4336b9ee02 fix(db): reserve transactions before checking pipeline capacity (#17831)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Interactive requests share a PostgreSQL connection pool with
background work.
> - Prepared queries can queue behind a slow query on a busy connection.
> - Disabling pipelining lets queued work use the next free connection.
> - The driver skips its transaction reservation callback when the
pipeline limit is zero.
> - This pull request runs that callback before the capacity check.
> - Operators can test a pool without pipelining while transactions
retain their connection ownership.

## Linked Issues or Issue Description

**What happened?**

With `PGMAX_PIPELINE=0`, postgres.js 3.4.9 skips `onexecute` in its
short-circuit capacity check. A transaction then lacks its reserved
connection. Real PostgreSQL reproduces `UNSAFE_TRANSACTION` through the
app client and an undefined connection error through the raw driver.
This prevents safe use of the existing setting to reduce query queue
delays.

**Expected behavior**

A transaction must reserve its connection regardless of pipeline
capacity. Commit, rollback, savepoints, and disconnect recovery must
preserve their existing contracts.

**Steps to reproduce**

1. Use the pre-change driver patch from
`e61ee4b005f8e13f64af15f69cb62305dd869f82`.
2. Start disposable PostgreSQL and run the `no-pipeline` scenario in
`packages/db/src/__fixtures__/postgres-connection-recovery.mjs` with
`TEST_DATABASE_URL`, `DRIVER_FORMAT=esm`, and
`RECOVERY_CASE=no-pipeline`.
3. Observe the transaction failure. Apply this patch and repeat with
both `esm` and `cjs`.

Refs #13643, which introduced the existing connection recovery patch.
Searched related open and closed driver PRs. This change extends that
patch and preserves its disconnect safeguards.

## What Changed

- Move the transaction reservation callback before the pipeline capacity
check in both driver distributions.
- Add real PostgreSQL regressions for commits, concurrent transaction
reads, isolation, rollback, savepoints, reserved connections, and
progress on a freed pool connection.
- Document the existing `PGMAX_PIPELINE=0` setting and its driver
prerequisite. Keep the default pipeline limit unchanged.

## Verification

- `pnpm -r typecheck`: passed.
- `pnpm build`: passed.
- Real PostgreSQL 18.6 in an owned, disposable Docker container: the old
patch fails the new transaction scenario in both ESM and CommonJS. The
corrected patch passes all 18 scenarios, including all 12 existing
disconnect recovery cases. The container was removed afterward.
- Local service benchmark: actual `createDb` with prepared statements,
two warmed connections, two controlled advisory lock waits, and the
complete three-query `getDefaultCompanyGoal` path. Two warmups and five
alternating measured samples per setting. Pipeline 100: median 413.44
ms, range 413.33–416.10 ms. Pipeline 0 with the patch: median 12.22 ms,
range 11.86–12.57 ms. Complete SQL, bindings, and results match. Five of
five reads finish while the unrelated slow query remains blocked. These
are synthetic local queue measurements, not hosted latency claims.
- App client compatibility on real PostgreSQL: commit, concurrent
transaction reads, rollback, nested savepoint rollback, dedicated
connections, and liveness connections passed.
- `pnpm test:run`: attempted, then stopped after repeated local embedded
PostgreSQL startup failures caused by the host semaphore limit. This is
an incomplete local full-suite run, not a pass. The focused driver
checks above used disposable Docker PostgreSQL instead. The initial
sandbox attempt also stopped before test execution because tsx could not
bind its IPC socket. Final CI results will be recorded here.
- Current head `72039f71f63530300bf241475d42e857297dfb90`: Greptile and
Paperclip review are both 5/5. All three earlier findings are resolved.
[CI run
40431567516](https://github.com/paperclipai/paperclip/actions/runs/40431567516)
ran the complete validation matrix. The database lane passed all 265
tests, including all 18 real PostgreSQL driver regressions. One cleanup
timer case timed out in server shard 6/12; its isolated real-PostgreSQL
reproduction passed once and failed once, while five runs with the
pre-change driver passed. That evidence is retained and does not
establish the timer failure's cause. A single CI retry of the failed
shard passed. The final aggregate `ci / verify` gate is waiting for a
runner. Its first queued request did not start for more than 14 minutes.
A guarded queue reset confirmed that it was the only unfinished job and
that every test job had passed; attempt 3 restarts only that gate. No
test result was replaced or bypassed. The required gate must pass before
merge.

## Risks

- This changes a shared driver callback order. Both module formats and
existing disconnect recovery are covered by real database tests.
- This PR does not change pool size, enable the setting by default,
retry SQL, or change schemas. Disabling pipelining may reduce batch
throughput. Operators must compare the workload before retaining that
setting.
- The local queue benchmark proves the mechanism. Hosted request
improvement still needs acceptance after the patched image is deployed.

## Model Used

OpenAI GPT-6 in Codex, with code execution and browser developer tools.
The exact serving model identifier and context window are not exposed in
this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-27 03:00:01 +00:00
..
2026-03-12 13:09:22 -05:00