Repository navigation
Conversation
update_applied_lsn now wakes the worker, which sends the new position once status_interval has passed since its last status update, also on an idle stream. Before, an idle stream reported it only at the next idle wakeup, server message or keepalive reply request.
The fast-path load of the signalled flag in update_applied_lsn was Relaxed, so it could still see a flag the worker had already cleared after reading the LSN before the raise: the raise then skipped the wake and the worker kept waiting until its idle wakeup. Make it SeqCst, move the lock-free core into ProgressCell, and add a loom model (run in CI) proving a raise concurrent with send or clear is sent, pending or wakes the worker.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
update_applied_lsn()only stored the position in an atomic, so on an idle stream the new position reached the server only at the nextidle_wakeup_intervalwakeup, server message or keepalive reply request. A consumer that acknowledges after traffic stops (for example after a downstream commit) held WAL for up to that long. Loweringidle_wakeup_intervalhides this but wakes every idle connection on a fixed cadence even when nothing changed.Change
status_intervalhas passed since its last status update; updates in between coalesce into one status carrying the newest position.signalledflag before reading the position, so a raise after that point always wakes it. Every access to the flag and the position on both sides is SeqCst; the lock-free core isProgressCell.update_applied_lsnstays as cheap as before.Tests
Protocol tests against a scripted server (paused clock):
New live test
postgres_idle_feedback_is_change_driven: on an idle stream,confirmed_flush_lsnreaches an acknowledged commit within 2 s. It took 2.8 ms, and fails onmain.Mutants caught:
Loom model (
src/client/progress.rs, run in CI with--cfg pgwire_loom): two raises concurrent with two worker cycles of mark, clear, read and send. In every interleaving, the newest raise is sent, pending, or has a wake waiting.update_applied_lsnis still 8.8 ns per call.Measurements
Real clients over TCP against a scripted idle server; status interval 1 s; 60 s windows.
update_applied_lsncost, 10M increasing calls on a live client:Load by number of sources. "main 10 s" is the current client with its 10 s idle wakeup; "main 1 s" lowers that wakeup to 1 s.
With
mainat a 10 s wakeup, acknowledgements were still unsent when the window ended: 1 of 13 at 1 source, rising to 169 of 3,601 at 300.