-
Notifications
You must be signed in to change notification settings - Fork 2.5k
fix stream unable to disconnect when it is full #4831
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Solution: defer HWM check to the second frame in stream_t::xsend
I hereby agree to license my contributions to libzmq under the terms of the MPLv2.
In ZMQ_STREAM, sending the routing ID frame followed by an empty payload signals a disconnect. If the SNDHWM is reached, the routing ID frame is blocked by check_write(), returning EAGAIN and preventing the disconnect signal from being processed. Solution: defer HWM check to the payload frame in stream_t::xsend. Also added a regression test in tests/test_stream_hwm_disconnect.cpp. Fixes zeromq#4828
b508a91 to
16c7c2a
Compare
I hereby agree to license my contributions to libzmq under the terms of the MPLv2.
16c7c2a to
13e5c52
Compare
|
In the test, after the sndhwm is reached, you have a comment that at that point, it is unknown whether the socket is in the "more" state. The subsequent code then deals with both cases. It seems to me that there is a race? Let's assume that the socket is in the "more" state. Before you send the routing_id frame, is it possible for the sndhwm to transition to no longer full? If yes, then that would result in the routing id frame being sent as a payload to the client. Perhaps the "more" state should be reset if the sndhwm is reached? I see that #4829 added an API |
5ebe188 to
d05be44
Compare
…wm is at limit Solution: Implement zmq_disconnect_peer support for ZMQ_STREAM
d05be44 to
c5f0e8c
Compare
When a ZMQ_STREAM socket reaches its SNDHWM, it becomes impossible to disconnect a peer. Disconnecting requires sending the routing ID followed by a 0-byte frame. Currently, xsend returns EAGAIN on the first frame (the ID) if the pipe is full, preventing the second disconnect frame from ever being processed. Solution: Modified xsend in stream.cpp to allow the routing ID frame to pass even when the pipe is full. If the subsequent payload frame is 0-bytes, the connection is terminated immediately via terminate(). To prevent state-machine desync, _more_out is reset to false if a data-bearing payload frame is sent on a full pipe, forcing an EAGAIN and requiring a clean retry from the user.
705f411 to
8600568
Compare
|
Thanks for the feedback, I looked into the API Incompatibility: Current Progress: |
Fixes #4828
Problem
ZMQ_STREAMserver cannot disconnect a client if theSNDHWMhas been reached. This happens because thestream_t::xsendlogic returnsEAGAINon the first frame (the Routing ID) whencheck_write()fails, preventing the socket from ever receiving the second frame (the 0-byte disconnect signal).Solution
defer the check_write() call from the Routing ID frame to the actual payload frame. This allows the socket to identify the peer and process a termination signal even under HWM pressure. Actual data payloads still correctly trigger EAGAIN if the pipe is full, preserving existing backpressure behavior.
terminate(), bypassing the HWM.Verification
tests/test_stream_hwm_disconnect.cpp.EAGAIN.