Skip to content

v11.3.2

Choose a tag to compare

@github-actions github-actions released this 06 Sep 23:42
00f533c
  • A request issued while the client is switching servers no longer hangs until RequestTimeout (#177). Every path that retires a connection - ChangeServer, the ping-triggered fast reconnect, Disconnect, DisconnectAndWaitAsync, and the path taken when an OnConnected handler fails - rejected the pending requests first and cleared the socket reference afterwards. The rejection resumes the consumer, and a consumer that issues its next request from there - the second value of a page load, read from the response handler of the first - found the retired socket still installed, passed the connectivity check on it, and was written into it after the sweep that would have rejected it. Nothing completed it: the sweep had run, and a failed send is report-only. Forty seconds later it timed out, with the connection healthy for thirty-nine of them.

    • the fix clears the socket reference before the sweep. Moving it ahead of the first await, as the issue proposed, is not enough: RequestManager builds its completion sources without RunContinuationsAsynchronously, so on a thread pool the consumer's continuation runs inline, inside the sweep itself, before any await. A fifth retirement path the issue did not list is covered too
    • ImmediateFail now refuses such a request at once with NotConnectedException; WaitForConnection carries it over to the new connection. A request whose send fails because the connection went away between the check and the send is rejected rather than left pending for RequestTimeout
    • for consumers: retry logic that recognised this failure by the TimeoutException it used to produce now sees NotConnectedException (or OperationCanceledException, for a request that was in flight when the switch began) immediately. Classify by type rather than by message
    • the regression test hands the sweep a continuation that runs synchronously and asserts which socket the follow-up saw
  • ChangeServer, the fast reconnect and Disconnect no longer stall a single-threaded host for two seconds. Stopping the stream-message processor blocked the calling thread on its reader task, with a two-second cap. On Blazor WebAssembly the reader's continuation needs the very thread that was blocked, so the cap was always reached: every server switch froze the UI for two seconds, and a wake-from-background reconnect is such a switch. The stop is awaited now, after the request sweep, and the reader is gone in milliseconds. Measured on the WebAssembly test client: 2000 ms to 5-390 ms per switch.

  • A ping-triggered reconnect no longer waits three seconds for itself. RetireCurrentSessionAndReconnectAsync runs inside the ping check that calls it, and waited for the ping to finish before retiring the session - its own, whose flag could not clear until it returned. Every reconnect the health check started paid the full WaitForPingToFinishAsync timeout before announcing that the session had ended. The wait now recognises the ping it runs in. RestoringConnection to OnSessionEnded on the stand: 6 s to 20 ms.

  • A reconnect the loop finished is not reconnected a second time. When the fast reconnect's own attempt failed at the socket, the failure callback started the reconnect loop on the same cancellation source; the loop connected first, OnceOpen retired the source, and the fast reconnect's wait came back cancelled. Its catch read that as a failure: it reported RestoringConnection on a client that was connected and started a second loop, whose first attempt retired the live socket and opened another. Consumers saw two OnConnected per recovery, with a spurious RestoringConnection between them, and restored their subscriptions twice. A connected client is now recognised as settled, and the loop no longer retires a socket that is open when its turn comes.

    • pinned by a test that takes the server down at RestoringConnection, so the sequence falls to the loop, brings a replacement up on the same port and requires exactly one connection afterwards