Sessions that never call StreamEvents hold a worker for the full lease (1800 s); no lease renewal #167

Closed
opened 2026-10-22 06:05:32 -04:00 by dohertj2 · 1 comment
Owner

Found by a cross-repo review (OtOpcUa lmxopcua#735, GalaxyDriver respawn leak). Detach-grace only starts after a subscriber has attached at least once, so a session that never calls StreamEvents lives for the full DefaultLeaseSeconds (1800 s). GatewaySession.ExtendLease has no callers and there is no renew RPC. A client that leaks sessions (each pinning an x86 worker) exhausts MaxSessions after ~64 leaks inside the window.

Ask: start the idle/detach grace at session open (or on last RPC activity), and/or add a lease-renew RPC that clients call on keep-alive.

Found by a cross-repo review (OtOpcUa lmxopcua#735, GalaxyDriver respawn leak). Detach-grace only starts after a subscriber has attached at least once, so a session that never calls `StreamEvents` lives for the full `DefaultLeaseSeconds` (1800 s). `GatewaySession.ExtendLease` has no callers and there is no renew RPC. A client that leaks sessions (each pinning an x86 worker) exhausts `MaxSessions` after ~64 leaks inside the window. Ask: start the idle/detach grace at session open (or on last RPC activity), and/or add a lease-renew RPC that clients call on keep-alive.
Author
Owner

Fixed on origin/main and verified (closing as part of #169).

  • 285ef64 adds MxGateway:Sessions:UnattachedSessionGraceSeconds. When it's set, the lease sweep reaps a Ready session that has never had a subscriber (external or internal) once it has been idle for the window. The window runs from the later of Ready and the last unary command. ec9f264 is a follow-up that exempts internal subscribers and handles close races. Both are in merge 7f0720f.
  • Tests in SessionManagerTests: CloseExpiredLeasesAsync_ReapsNeverSubscribedSessionAfterUnattachedGrace, _UnattachedGrace_IsRestartedByUnaryActivity, _DoesNotReapSessionThatSubscribed, _DoesNotReapSessionWithInternalSubscriber, _IdleClockStartsAtReady, _IsDisabledByDefault. --filter CloseExpiredLeasesAsync gives 19/19 on macOS; the full gateway suite is 1349/1349 on windev at 777fef9.

Operational note: the setting defaults to 0, which is off. A deployment only gets the protection against leaked sessions if it sets UnattachedSessionGraceSeconds above its clients' OpenSession→StreamEvents time (see docs/GatewayConfiguration.md). There is still no lease-renew RPC; this fix implements the "idle grace from last RPC activity" option the issue asked for.

Fixed on origin/main and verified (closing as part of #169). - 285ef64 adds `MxGateway:Sessions:UnattachedSessionGraceSeconds`. When it's set, the lease sweep reaps a Ready session that has never had a subscriber (external or internal) once it has been idle for the window. The window runs from the later of Ready and the last unary command. ec9f264 is a follow-up that exempts internal subscribers and handles close races. Both are in merge 7f0720f. - Tests in `SessionManagerTests`: `CloseExpiredLeasesAsync_ReapsNeverSubscribedSessionAfterUnattachedGrace`, `_UnattachedGrace_IsRestartedByUnaryActivity`, `_DoesNotReapSessionThatSubscribed`, `_DoesNotReapSessionWithInternalSubscriber`, `_IdleClockStartsAtReady`, `_IsDisabledByDefault`. `--filter CloseExpiredLeasesAsync` gives 19/19 on macOS; the full gateway suite is 1349/1349 on windev at 777fef9. **Operational note:** the setting defaults to `0`, which is off. A deployment only gets the protection against leaked sessions if it sets `UnattachedSessionGraceSeconds` above its clients' OpenSession→StreamEvents time (see `docs/GatewayConfiguration.md`). There is still no lease-renew RPC; this fix implements the "idle grace from last RPC activity" option the issue asked for.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/mxaccessgw#167