Fix pub/sub message delivery to idle subscribers (v0.11.9) - #41
Merged
Conversation
A subscriber did not receive published messages until it happened to send another byte to the server. The connection loop latches `in_pubsub` at the top of each iteration; when a SUBSCRIBE was processed inside the normal-mode branch, control fell through to a blocking socket read instead of the select! that also polls pubsub_rx, so a delivered message sat unread in the channel until the next loop iteration (triggered only by more client input). Re-enter the loop after processing commands if the connection has entered pub/sub mode, so the next iteration waits on the pub/sub channel. Also commit the integration test suite (previously untracked); the two pubsub tests failed against this bug and now pass.
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.
Bug
A subscriber never received a published message until it happened to send another byte to the server. Any client that subscribes and then waits passively (the normal pub/sub pattern) missed messages.
Root cause
In
src/server/connection.rs, thehandle()loop latchesin_pubsubonce at the top of each iteration:When a fresh subscriber's
SUBSCRIBEis processed, it happens inside theelsebranch (becausein_pubsubwasfalsewhen the iteration began). Control then falls through to the blockingread_buf— not theselect!— sopubsub_rxis never polled. The published message is delivered into the channel (that's whyPUBLISHcorrectly returns:1) but nothing drains it until the next loop iteration, which only happens when the client sends more data.Reproduced with a raw RESP client: the
messageframe arrived only after poking the subscriber socket with an unrelatedPING.(The earlier idle-read timeout reduced the symptom from "hangs forever" to "delivered after 30s", still well past the tests' 5s wait.)
Fix
After the normal-mode command loop, re-enter the loop if the connection has just entered pub/sub mode, so the next iteration waits on the
select!that watchespubsub_rx:Verification
cargo testfull suite green (87 unit + all integration), including the two pubsub tests that previously failed.Also commits the integration test suite (
tests/), previously untracked — the two pubsub tests exercised exactly this bug and now pass, so they're worth keeping as regression coverage.