Skip to content

Listener: defer Open frame until peer protocol header is received - #651

Open
alt-Rational wants to merge 1 commit into
Azure:masterfrom
alt-Rational:fix/defer-listener-open-frame
Open

Listener: defer Open frame until peer protocol header is received#651
alt-Rational wants to merge 1 commit into
Azure:masterfrom
alt-Rational:fix/defer-listener-open-frame

Conversation

@alt-Rational

Copy link
Copy Markdown

Problem

ListenerConnection pipelines its AMQP protocol header and Open frame
immediately after SASL (OpenPipe state). When both are flushed into a single
TCP segment, some clients fail to parse the coalesced bytes and hang until their
connection-open timeout.

It's intermittent and timing-dependent (depends on wire chunking), and is
reproducible with the Node @azure/service-bus / rhea client opening several
connections concurrently against a ConnectionListener: the client receives the
server's header+open (peek_size undefined, N) but never advances, then times
out after ~60s.

Fix

Defer the listener's Open until the peer's protocol header arrives, so the
header and Open are sent as separate writes. This matches the more
conservative handshake used by brokers such as Azure Service Bus and is
transparent to clients that already handle the pipelined case.

A new internal virtual Connection.PipelineOpen (default true) controls the
behaviour; ListenerConnection overrides it to false. Client connections are
unchanged.

Verification

Built a broker on ConnectionListener and ran the Node SDK opening 2 clients ×
(2 senders + 2 receivers), 20 msgs each, repeatedly. Before: runs after the
first reliably hang with operation timeout / negotiateCbs. After: every run
succeeds.

The listener connection pipelines its AMQP protocol header and Open frame
immediately after SASL (OpenPipe state). When both are flushed into a single
TCP segment, some clients fail to parse the coalesced bytes and hang until
their connection open timeout. This is intermittent and timing dependent
(it depends on how the bytes are chunked on the wire), and is reproducible
with the Node @azure/service-bus / rhea client opening several connections
concurrently against a ConnectionListener.

Defer the listener's Open until the peer's protocol header arrives, so the
header and Open are sent as separate writes. This matches the more
conservative handshake used by brokers such as Azure Service Bus and is
transparent to clients that already handle the pipelined case.

A new internal virtual Connection.PipelineOpen (default true) controls the
behaviour; ListenerConnection overrides it to false. Client connections are
unchanged.
@alt-Rational

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

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.

1 participant