Skip to content

Revert WebSocket Close issue#5940

Open
afifi-ins wants to merge 3 commits into
dotnet:mainfrom
afifi-ins:revert-websocket-issue-5818
Open

Revert WebSocket Close issue#5940
afifi-ins wants to merge 3 commits into
dotnet:mainfrom
afifi-ins:revert-websocket-issue-5818

Conversation

@afifi-ins
Copy link
Copy Markdown
Contributor

Issue: #5818

afifi-ins added a commit to afifi-ins/wcf that referenced this pull request May 20, 2026
The integration test suite calls Close() unconditionally after PR dotnet#5940
(revert of WebSocket close workaround). On resource-constrained Helix
Linux Open queues (2-4 vCPU), running tests at default parallelism can
starve the SelfHosted(Core)WCF service and cause WebSocket close
handshakes to time out, matching the failure pattern in issue dotnet#5819.

Add a global default to Directory.Build.props that caps -maxthreads at
min(ProcessorCount, 4) for any project with IsTestProject=true. This:
  - Resolves to '-maxthreads 2' on 2-vCPU Helix VMs (Linux Open queues)
  - Resolves to '-maxthreads 4' on 16-core dev boxes (preserves throughput)
  - Is consumed by the Helix xunit.console runner via _XunitOptions
  - Composes cleanly with existing per-project overrides:
      * Client.ChannelLayer: '-maxthreads 4 -maxthreads 16' (project wins, last value)
      * Client.ClientBase / Security.TransportSecurity: '-maxthreads 4 -parallel none'
        (parallel none disables threading regardless of maxthreads)
  - Can be overridden per-project by setting WcfHelixMaxThreads before
    the global default applies.

Verified on WSL Ubuntu-24.04 with the SelfHostedCoreWCFService running
and dotnet test pinned to 2 CPUs via 'taskset -c 0,1'. All 63 PR-affected
WebSocket test cases (WebSocket_Http_Duplex_Buffered, WebSocket_Http/Https_
RequestReply_*) pass in 23 s with the cap applied. The pre-existing
WebSocket_Http_Duplex_Streamed failures reproduce identically on main
(both with and without the cap), confirming they are unrelated to PR dotnet#5940.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
afifi-ins added a commit to afifi-ins/wcf that referenced this pull request May 20, 2026
The integration test suite calls Close() unconditionally after PR dotnet#5940
(revert of WebSocket close workaround). On resource-constrained Helix
Linux Open queues (2-4 vCPU), running tests at default parallelism can
starve the SelfHosted(Core)WCF service and cause WebSocket close
handshakes to time out, matching the failure pattern in issue dotnet#5819.

Add a global default to Directory.Build.props that caps -maxthreads at
min(ProcessorCount, 4) for any project with IsTestProject=true. This:
  - Resolves to '-maxthreads 2' on 2-vCPU Helix VMs (Linux Open queues)
  - Resolves to '-maxthreads 4' on 16-core dev boxes (preserves throughput)
  - Is consumed by the Helix xunit.console runner via _XunitOptions
  - Composes cleanly with existing per-project overrides:
      * Client.ChannelLayer: '-maxthreads 4 -maxthreads 16' (project wins, last value)
      * Client.ClientBase / Security.TransportSecurity: '-maxthreads 4 -parallel none'
        (parallel none disables threading regardless of maxthreads)
  - Can be overridden per-project by setting WcfHelixMaxThreads before
    the global default applies.

Verified on WSL Ubuntu-24.04 with the SelfHostedCoreWCFService running
and dotnet test pinned to 2 CPUs via 'taskset -c 0,1'. All 63 PR-affected
WebSocket test cases (WebSocket_Http_Duplex_Buffered, WebSocket_Http/Https_
RequestReply_*) pass in 23 s with the cap applied. The pre-existing
WebSocket_Http_Duplex_Streamed failures reproduce identically on main
(both with and without the cap), confirming they are unrelated to PR dotnet#5940.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@afifi-ins afifi-ins force-pushed the revert-websocket-issue-5818 branch 2 times, most recently from d29320c to 3984b56 Compare May 22, 2026 05:40
afifi-ins and others added 3 commits May 22, 2026 10:45
Issue dotnet#5818: WebSocket_Http_RequestReply_* intermittently fails on Helix

Linux Open queues with 'remote party closed the WebSocket connection

without completing the close handshake'. Cannot reproduce on WSL

Ubuntu 24.04 (180+ runs across Debug/Release, 1-64 parallelism).

Adds an IConnectionMiddleware on the SelfHostedCoreWcfService WebSocket

Kestrel listeners (ports 8083/8084) plus Trace-level filters for Kestrel

and AspNetCore.WebSockets so the next Helix run captures:

  * connection lifecycle (open/close/exception) tagged [WSDIAG]

  * raw TCP byte counts + FIN/RST events from Kestrel.Transport.Sockets

  * WebSocket close-frame send/receive from AspNetCore.WebSockets

  * CoreWCF channel-shutdown trace

Output is to stdout (inherited by the bootstrapped child process) so it

lands in the Helix console.log next to the test failure for correlation

with the client-side stack trace.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wraps the Kestrel IDuplexPipe.Output on the WebSocket listeners with a

PipeWriter that observes (without modifying) every byte written by the

ASP.NET Core WebSockets middleware / CoreWCF WebSocket transport channel.

Logs to [WSDIAG] the first time a close-frame opcode byte (0x88 = FIN+

Close, unmasked server-to-client) is written for a connection, plus a

per-connection summary (total bytes, write count, closeFrameSent flag)

on output-complete and on connection close.

Goal: prove whether the 'remote party closed without completing the

close handshake' race on Helix (dotnet#5818) is caused by (a) the server

never writing a Close frame at all, or (b) writing it too late to reach

the wire before Kestrel's transport send loop sends TCP FIN.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@afifi-ins afifi-ins force-pushed the revert-websocket-issue-5818 branch from 147dd3f to 9e1d1ec Compare May 22, 2026 07:45
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