Skip to content

Add pg_notify support to reduce polling latency#121

Draft
stephenbinns wants to merge 1 commit into
masterfrom
add-pg-notify-support
Draft

Add pg_notify support to reduce polling latency#121
stephenbinns wants to merge 1 commit into
masterfrom
add-pg-notify-support

Conversation

@stephenbinns

Copy link
Copy Markdown
Contributor

Idle workers currently only notice new jobs on their next poll (wake_interval, 5s by default). Add a migration (schema v7) that triggers pg_notify() on insert, and a Listener class that lets WorkerGroup wake idle workers immediately on notification instead of waiting out the full interval. This is a supplement to polling, not a replacement - workers keep polling exactly as before, so a missed notification just costs the next poll's worth of latency rather than losing the job.

Opt-in via listen: true (WorkerGroup) / --listen (bin/que), since it requires running the new migration and reserving one extra long-held connection per worker group for the LISTEN, for pooled adapters.

Also fixes WorkerGroup#stop to broadcast the wakeup condvar so a large wake_interval doesn't force a hard Thread#raise kill on graceful shutdown when listen mode is enabled.

Idle workers currently only notice new jobs on their next poll
(wake_interval, 5s by default). Add a migration (schema v7) that triggers
pg_notify() on insert, and a Listener class that lets WorkerGroup wake idle
workers immediately on notification instead of waiting out the full
interval. This is a supplement to polling, not a replacement - workers keep
polling exactly as before, so a missed notification just costs the next
poll's worth of latency rather than losing the job.

Opt-in via `listen: true` (WorkerGroup) / `--listen` (bin/que), since it
requires running the new migration and reserving one extra long-held
connection per worker group for the LISTEN, for pooled adapters.

Also fixes WorkerGroup#stop to broadcast the wakeup condvar so a large
wake_interval doesn't force a hard Thread#raise kill on graceful shutdown
when listen mode is enabled.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Comment thread README.md

### Reducing polling latency with pg_notify

By default, idle workers only notice new jobs on their next poll (`--wake-interval`/`wake_interval`, 5 seconds by default). Running `Que.migrate!` up to the latest schema version adds a trigger that calls `pg_notify` whenever a job becomes available, and passing `--listen` to `bin/que` (or `listen: true` to `Que::WorkerGroup.start`) makes idle workers wake up on that notification instead of waiting out the full interval. Polling itself is unaffected and still runs as normal - notifications are purely a way to shorten the wait, so a missed one just means the job is picked up on the next poll as before.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so a missed one just means the job is picked up on the next poll as before.

What are the instances that miss might happen (and how) ?

Comment thread README.md

By default, idle workers only notice new jobs on their next poll (`--wake-interval`/`wake_interval`, 5 seconds by default). Running `Que.migrate!` up to the latest schema version adds a trigger that calls `pg_notify` whenever a job becomes available, and passing `--listen` to `bin/que` (or `listen: true` to `Que::WorkerGroup.start`) makes idle workers wake up on that notification instead of waiting out the full interval. Polling itself is unaffected and still runs as normal - notifications are purely a way to shorten the wait, so a missed one just means the job is picked up on the next poll as before.

This holds one dedicated connection open for the lifetime of each worker group to listen on, in addition to the connections workers use to run queries. If you're using a pooled adapter (ActiveRecord, Sequel, Pond), make sure your pool has capacity for one extra connection per worker group when enabling `--listen`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An extra connection per worker group could be costly (in some instances - large number of groups and limited connections) - Wondering if it'd help having some guidance on which queues this is useful for vs which not?

For eg: if the queue is not heavily busy - then this might be more useful and if the queue is high frequency (busy) - then probably not worth it?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • need a dedicated, long-lived session connection in both Postgres & YB, combined with connection manager in YB means we hold that connection (it will need to be a sticky connection on the node)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah its not ideal is it, I do wonder if it needs to be session or transaction based. My gut feeling is that because its a long running connection it might not even matter. I wonder if we have any findings from the use of goodjob elsewhere

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants