Bind WS handlers via local closure instead of ivars - #9
Merged
Merged
Conversation
websocket-client-simple invokes on() blocks with instance_exec, so when the handlers reference @Mutex / @message_queue / @connected those resolve to ivars on the underlying Client (which are nil) instead of the wrapper. Result: every incoming frame is silently dropped and #call hangs forever on queue.pop with no error. Capture self as a local 'owner' and route close/message through small private helpers so the handler bodies don't depend on what self is. The mock client in the spec was calling handlers with plain block.call, which hid the issue. Changed it to instance_exec to match the real lib.
Owner
|
Thank you @lucas-domeij for the careful diagnosis and the spec update that pins the contract. Merged in 64fc6ea. |
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.
The
on(:message),on(:close), andon(:error)blocks reference@mutex,@message_queue, and@connected. websocket-client-simple invokes these blocks withinstance_exec, so those ivars resolve to fields on the underlying Client (all nil), not the gem's wrapper.Effect: every incoming frame is silently dropped.
#callhangs forever onqueue.popwith no error, no log line, nothing.Fix: capture
selfas a localownerso the handlers can call back into the wrapper, and move the close/message logic into small private helpers.The mock
MockWSClientin the spec was calling handlers with plainblock.call, which is why the existing tests passed. Updated it to useinstance_execto match the real lib's behavior — that makes future regressions of this kind fail loudly.Verified end-to-end against the live endpoint: streaming works,
gpt-4.1-minianswers in about 1.2s,gpt-5in about 4.4s.