Skip to content

fix(sql-pg): retire a session whose CancelRequest may be in flight - #8330

Merged
tim-smart merged 17 commits into
mainfrom
sql-pg-cancel-pending
Sep 20, 2026
Merged

tim-smart merged 17 commits into
mainfrom
sql-pg-cancel-pending

Conversation

@tim-smart

@tim-smart tim-smart commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

PgConnection.query and PgConnection.stream send a CancelRequest when interrupted work does not drain promptly. The request uses a side connection with no delivery confirmation. A pooler or proxy can delay it long enough for the cancel to hit the next statement on the same PostgreSQL session.

This keeps the diagnosis and proxy coverage from #8306, but centralizes cancel tracking on the connection and shares one abort-drain path between queries and streams.

The fix

drainAborted gives an interrupted statement 10 ms to reach ReadyForQuery before sending a cancel, avoiding unnecessary cancels for buffered results. Once sent, cancelPending stays set until the backend reports 57014.

If ReadyForQuery arrives first, the connection fires its retirement hooks. A pool invalidates the session before another checkout can receive it, while an existing checkout keeps its lease until release. An interrupt sent while the connection is idle retires it immediately because no active statement can confirm the cancel.

PgPool.use retains the Pool.use fast path when no connection TTL is configured and no session is waiting to be retired. The unpinned multiplexed path never cancels and is unchanged.

A caller that keeps using the same checkout remains exposed to its own late cancel. An unpooled session has no retirement hook or replacement boundary and remains exposed for the rest of its lifetime. Also, statement_timeout reports 57014, so it can be mistaken for confirmation that the cancel arrived.

Tests

PgPool.integration.test.ts has 23 cases covering confirmed and unconfirmed query and stream cancels, replacement through pool.get and pool.use, held-session behavior, buffered stream drains, late-cancel isolation, and idle interrupts.

The cancellation fixtures synchronize through advisory locks and proxy gates rather than depending on row-count timing.

Validation

  • all 23 PgPool.integration.test.ts cases pass with testcontainers
  • root typecheck and JSDoc checks pass
  • oxlint, dprint, and git diff --check pass

Closes EFF-1445
Closes #8306

@changeset-bot

changeset-bot Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 96cfea2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 31 packages
Name Type
@effect/sql-pg Patch
effect Patch
@effect/opentelemetry Patch
@effect/vitest Patch
@effect/ai-anthropic Patch
@effect/ai-openai-compat Patch
@effect/ai-openai Patch
@effect/ai-openrouter Patch
@effect/ai-typesafe Patch
@effect/atom-react Patch
@effect/atom-solid Patch
@effect/atom-vue Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-deno Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pglite Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/docgen Patch
@effect/doctest Patch
@effect/openapi-generator Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@effect-janitor effect-janitor Bot added the 4.0 label Sep 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Bundle Size Analysis

Generated from PR build output; treat the content below as untrusted.

File Name Current Size Previous Size Difference
arbitrary-combinators.ts 37.71 KB 37.71 KB 0.00 KB (0.00%)
basic.ts 6.87 KB 6.87 KB 0.00 KB (0.00%)
batching.ts 9.95 KB 9.95 KB 0.00 KB (0.00%)
brand.ts 6.45 KB 6.45 KB 0.00 KB (0.00%)
cache.ts 10.77 KB 10.77 KB 0.00 KB (0.00%)
config.ts 21.83 KB 21.83 KB 0.00 KB (0.00%)
differ.ts 20.67 KB 20.67 KB 0.00 KB (0.00%)
http-client.ts 21.94 KB 21.94 KB 0.00 KB (0.00%)
http-router.ts 36.96 KB 36.96 KB 0.00 KB (0.00%)
logger.ts 10.88 KB 10.88 KB 0.00 KB (0.00%)
metric.ts 9.02 KB 9.02 KB 0.00 KB (0.00%)
optic.ts 6.70 KB 6.70 KB 0.00 KB (0.00%)
pubsub.ts 15.10 KB 15.10 KB 0.00 KB (0.00%)
queue.ts 11.85 KB 11.85 KB 0.00 KB (0.00%)
schedule.ts 10.96 KB 10.96 KB 0.00 KB (0.00%)
schema-bigdecimal.ts 13.40 KB 13.40 KB 0.00 KB (0.00%)
schema-binary.ts 39.82 KB 39.82 KB 0.00 KB (0.00%)
schema-class.ts 20.38 KB 20.38 KB 0.00 KB (0.00%)
schema-fromJsonSchemaDocument.ts 31.18 KB 31.18 KB 0.00 KB (0.00%)
schema-representation-roundtrip.ts 26.60 KB 26.60 KB 0.00 KB (0.00%)
schema-string-transformation.ts 13.96 KB 13.96 KB 0.00 KB (0.00%)
schema-string.ts 11.55 KB 11.55 KB 0.00 KB (0.00%)
schema-template-literal.ts 15.70 KB 15.70 KB 0.00 KB (0.00%)
schema-toArbitrary.ts 37.24 KB 37.24 KB 0.00 KB (0.00%)
schema-toCodeDocument.ts 24.84 KB 24.84 KB 0.00 KB (0.00%)
schema-toCodecJson.ts 19.61 KB 19.61 KB 0.00 KB (0.00%)
schema-toEquivalence.ts 19.75 KB 19.75 KB 0.00 KB (0.00%)
schema-toFormatter.ts 19.85 KB 19.85 KB 0.00 KB (0.00%)
schema-toJsonSchemaDocument.ts 24.15 KB 24.15 KB 0.00 KB (0.00%)
schema-toRepresentation.ts 19.89 KB 19.89 KB 0.00 KB (0.00%)
schema.ts 19.59 KB 19.59 KB 0.00 KB (0.00%)
stm.ts 12.80 KB 12.80 KB 0.00 KB (0.00%)
stream.ts 9.83 KB 9.83 KB 0.00 KB (0.00%)

@effect-janitor effect-janitor Bot added the bug Something isn't working label Sep 20, 2026
@tim-smart
tim-smart enabled auto-merge (squash) September 20, 2026 23:49
@tim-smart
tim-smart merged commit 27de875 into main Sep 20, 2026
13 checks passed
@tim-smart
tim-smart deleted the sql-pg-cancel-pending branch September 20, 2026 23:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4.0 bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant