Skip to content

PostgresMessageQueue.listen() can return before UNLISTEN completes #1081

Description

@dahlia

Problem

The abort handler in packages/postgres/src/mq.ts calls listen.unlisten() without awaiting or handling its Promise. The listening Promise can resolve while UNLISTEN is still pending. Closing the SQL client afterward can reject that request without a rejection handler.

This appears to explain a test-node failure on PR #1079 in PostgresMessageQueue continues processing when handler hangs (no ordering key):

failureType: 'unhandledRejection'
error: 'write CONNECTION_DESTROYED localhost:5432'
…
Object.unlisten (.../postgres/src/index.js:193:17)

The test aborts the listener, awaits it, then drops the queue table and calls sql.end(). The PostgreSQL queue code was not changed by that PR.

Verification

On Node.js 22.23.1 with PostgreSQL 17.11, the test that failed in CI passed in 20 local runs. A separate probe wrapping the SQL client's listener handle confirmed that unlisten() was still pending after the queue's listening Promise resolved following an abort. The CI exception was not reproduced locally.

Expected behavior

Awaiting the listening Promise after abort should wait for UNLISTEN to finish and handle cleanup errors, so callers can safely close the SQL client.

A deterministic regression test should hold unlisten() pending and verify that the listening Promise waits for it, including the rejection path.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Fields

Priority

None yet

Effort

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions