test(websocket): add sequence-oracle regression guard for backpressure inbound stream (#484) - #490
Open
FumingPower3925 wants to merge 4 commits into
Open
test(websocket): add sequence-oracle regression guard for backpressure inbound stream (#484)#490FumingPower3925 wants to merge 4 commits into
FumingPower3925 wants to merge 4 commits into
Conversation
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.
Refs #484
1. Reproduction & Investigation
msa2-client, kernel7.0.0-30-generic), base commitf4749e9.TestBackpressureInboundSequenceIntegrityinmiddleware/websocket/inbound_sequence_linux_test.gowith:parseErr == 0(wire frame corruption: invalid UTF-8, bad headers, unexpected EOF).ErrReadLimit) isolated intooverflowErrand assertedoverflowErr == 0at default buffer capacity.'x').multishot_recvsub-run logs detected tier and provided-buffer support, skipping cleanly if unsupported.WS484_BP=256restored (matching original reproduction fixture); verified at both 256 and 512 with identical zero-gap and zero-parse-error results.Oracle Results at Default Buffer Capacity (
WS484_BP=256)epoll:conns=96 framesSent=6037267 framesIn=6038190 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=7 closedOK=95 closeTimeout=0 dialFail=0 hsFail=0io_uring(defaults):conns=96 framesSent=6080000 framesIn=6091616 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=4 closedOK=95 closeTimeout=0 dialFail=0 hsFail=0io_uring/multishot_recv:multishot_recv sub-run: kernel=7.0.0-30-generic tier=optional providedBuffers=true multishotRecv=true,conns=96 framesSent=6144000 framesIn=6144000 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=0 closedOK=96 closeTimeout=0 dialFail=0 hsFail=0Oracle Results at Buffer Capacity (
WS484_BP=512)epoll:conns=96 framesSent=6144000 framesIn=6144000 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=0 closedOK=96 closeTimeout=0io_uring(defaults):conns=96 framesSent=5760000 framesIn=5895798 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=12 closedOK=90 closeTimeout=0io_uring/multishot_recv:conns=96 framesSent=6080000 framesIn=6087657 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=4 closedOK=95 closeTimeout=0epoll:conns=96 framesSent=6144000 framesIn=6144000 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=0 closedOK=96 closeTimeout=0io_uring(defaults):conns=96 framesSent=6080000 framesIn=6100843 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=2 closedOK=95 closeTimeout=0io_uring/multishot_recv:conns=96 framesSent=6080000 framesIn=6085268 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=4 closedOK=95 closeTimeout=0epoll:conns=96 framesSent=6080000 framesIn=6086140 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=4 closedOK=95 closeTimeout=0io_uring(defaults):conns=96 framesSent=6144000 framesIn=6144000 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=0 closedOK=96 closeTimeout=0io_uring/multishot_recv:conns=96 framesSent=6144000 framesIn=6144000 seqGaps=0 parseErr=0 overflowErr=0 protocolErrors=0 clientCloseFail=0 closedOK=96 closeTimeout=0Original Flood Test Comparison (
TestBackpressurePauseDoesNotCancelInflightSend)Instrumented to count protocol errors in the read handler against
clientCloseFail:io_uring: conns=96 protoErr=12 clientCloseFail=12 ecanceled=0 otherWriteErr=0 closedOK=84 closeTimeout=0(protoErr == clientCloseFail == 12)io_uring: conns=96 protoErr=19 clientCloseFail=19 ecanceled=0 otherWriteErr=0 closedOK=77 closeTimeout=0(protoErr == clientCloseFail == 19)epoll: conns=96 protoErr=0 clientCloseFail=0 ecanceled=0 otherWriteErr=0 closedOK=96 closeTimeout=02. Findings & Mechanism
seqGaps = 0) and zero frame parse errors (parseErr = 0) occurred across >50 million frames on both engines under sustained backpressure.protoErr == clientCloseFail). A client dying mid-frame sends incomplete bytes that the server legitimately rejects; this was the artifact reported in io_uring WS: backpressure pause/resume drops buffered inbound bytes, truncating frames #484 rather than an engine byte drop.ErrReadLimit) atchanReader.Appendis a bounded-buffer capacity artifact when pause-apply latency outpaces headroom, isolated from wire frame corruption and verified at 0 across runs.CELERIS_IOURING_MULTISHOT_RECV=1(engine/iouring/worker.go:459), so provided-buffer recycling hazards cannot occur on the default engine path.3. Fix & Hardening
middleware/websocket/inbound_sequence_linux_test.go(TestBackpressureInboundSequenceIntegrity) as a permanent regression guard with:parseErr == 0andseqGaps == 0.overflowErrand assertedoverflowErr == 0at default buffer capacity.seq == last+1starting fromlast = -1).'x').CELERIS_IOURING_MULTISHOT_RECV=1provided-buffer ring paths, with probe capability logging.testing.Short()gate scaling parameters down for fast execution.errors.Is(err, io.EOF) || errors.Is(err, syscall.ECONNRESET)and assertion ofcloseTimeout == 0.middleware/websocket/pause_cancel_linux_test.go:50-54..github/workflows/ci.ymlrunninggo test -race -count=1 -timeout=120s -run '^TestBackpressure' ./middleware/websocket/...with fast parameters (WS484_CONNS=16 WS484_BURSTS=2 WS484_BURST_FRAMES=1000).4. Proof
msa2-client(Linux 7.0.0-30-generic):middleware/websockettest suite passed under-race.5. Performance
6. Not verified
msr1(host occupied running the v1.5.9 Weekend Soak run33859172975until ~2026-09-05 10:30 UTC). PR test(websocket): add sequence-oracle regression guard for backpressure inbound stream (#484) #490 remainsRefs #484until confirmed onmsr1.Draft Closing Comment for #484 (to be posted once msr1 arm64 run confirms 0 gaps)