fix(sessions): account SessionClosed for sweep-driven closes
TryBeginCloseIfExpired set _closeStarted when it reserved a session, so the sweep's own CloseAsync reported AlreadyClosed: true and CloseSessionCoreAsync skipped SessionClosed: lease-expired, faulted-reaped and detach-grace-expired closes never left the sessions.open gauge and under-counted sessions.closed. The reservation now writes Closing only; the first CloseAsync to take the close lock does the accounting exactly once.
This commit is contained in:
@@ -1822,6 +1822,15 @@ public sealed class GatewaySession
|
||||
/// committing to <c>Closing</c>, so a reattach that wins the race leaves the session
|
||||
/// in <c>Ready</c> and usable.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This is a <em>reservation</em>, not the close itself: it flips the state so no
|
||||
/// reattach can revive the session and no other sweep pass re-selects it, but it
|
||||
/// deliberately leaves <c>_closeStarted</c> untouched. The sweep's own
|
||||
/// <see cref="CloseAsync"/> that follows is the first close to run, and must report
|
||||
/// <c>AlreadyClosed: false</c> so the manager accounts <c>SessionClosed</c> for it;
|
||||
/// setting <c>_closeStarted</c> here made that close look like a second, concurrent one
|
||||
/// and every sweep-driven close went unaccounted.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
internal bool TryBeginCloseIfExpired(DateTimeOffset now, out bool alreadyClosing)
|
||||
{
|
||||
@@ -1843,7 +1852,6 @@ public sealed class GatewaySession
|
||||
}
|
||||
|
||||
alreadyClosing = _closeStarted;
|
||||
_closeStarted = true;
|
||||
_state = SessionState.Closing;
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user