From 68761843874504d485425269db822e90d399304a Mon Sep 17 00:00:00 2001 From: vibesoftwarecoder Date: Fri, 11 Sep 2026 08:52:24 -0500 Subject: [PATCH] fix(seats): the teardown warning overstated the stall The warning shipped in #50 said the standalone Apollo's stream "will stall for about a second". Verified on the reference host today and that is wrong in the direction that matters -- it makes operators expect something worse than happens. Measured with a client genuinely streaming the console Apollo while a seat was provisioned and torn down: 08:49:23.503 warning fired 08:49:24.661 Apollo: Creating encoder <- 1.2s AFTER the warning 08:49:25.099 Session 8 logged off 08:49:31.996 Apollo: Creating encoder <- 7s after teardown, unexplained The rebuild took 266 ms, against the 690 ms measured on 2026-09-04, and the person streaming DID NOT NOTICE IT AT ALL. So: "hitch for a few hundred milliseconds", not "stall for about a second". CLAUDE.md carries the same correction, with both measurements and the caveat that one user's perception on one LAN does not prove it is always imperceptible. Two other things this run settled, both recorded on #23 rather than here: - Provisioning did NOT cause a rebuild. The session was created at 08:49:09.933 with no encoder activity near it, which supports the original observation in the issue rather than contradicting it. An earlier reading of mine that claimed otherwise was wrong -- corrected by correlating timestamps instead of eyeballing a log tail. - The warning fires BEFORE the stall, by 1.2s, which was the whole point of placing it ahead of the lifecycle gate. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01SQvL62WkT8xDWXqyjFCGDw --- CLAUDE.md | 12 +++++++++--- src/MultiSeat.Service/Sessions/SeatManager.cs | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index c9470dd..f799117 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -342,9 +342,15 @@ MultiSeat is self-contained and **non-destructive**: it works out of the box whe 2. **Own port range.** Default `PortBase = 48100`, above a stock Apollo's block — no runtime port conflict. 3. **Never kills a non-MultiSeat Apollo.** On startup `MultiSeatWorker.KillOrphanedApolloProcesses` reaps **only** Apollo processes MultiSeat launched, identified via WMI (`GetManagedApolloPids`) by executable path (under the ApolloVibe dir) or a MultiSeat per-seat config path on the command line. It no longer stops/disables `ApolloService`, and `install-service.ps1` leaves that service alone. (WMI failure → empty set → cleanup is skipped rather than risk killing an unrelated Apollo.) -⚠️ **"Non-destructive" has one exception, and it is not fixable here: tearing a seat down stalls a -standalone Apollo's stream for about 690 ms** while it rebuilds its encoder. Self-recovering, and -it does not compound with seat count — seat-to-seat interference was measured and does not exist. +⚠️ **"Non-destructive" has one exception, and it is not fixable here: tearing a seat down makes a +standalone Apollo rebuild its encoder.** Self-recovering, and it does not compound with seat count — +seat-to-seat interference was measured and does not exist. + +⭐ **It is smaller than it sounds.** 690 ms on 2026-09-04, **266 ms on 2026-09-11**, and on +2026-09-11 the person actually streaming **did not notice it at all**. Do not describe this as a +freeze or a second-long stall; that came from one early measurement and overstates it. ⚠️ One +user's perception on one LAN is not proof it is always imperceptible — but "a few hundred +milliseconds, usually unnoticed" is what the evidence supports. ⛔ **The cause is NOT a second Apollo starting or stopping**, which is the intuitive guess and was this issue's original premise. Decomposed step by step (#23): stopping the seat's Apollo produced diff --git a/src/MultiSeat.Service/Sessions/SeatManager.cs b/src/MultiSeat.Service/Sessions/SeatManager.cs index 2c74b13..80eb36c 100644 --- a/src/MultiSeat.Service/Sessions/SeatManager.cs +++ b/src/MultiSeat.Service/Sessions/SeatManager.cs @@ -649,8 +649,8 @@ private async Task WarnIfStandaloneApolloStreamingAsync(Guid seatId, Cancellatio _logger.LogWarning( "Seat {Id}: tearing down while the standalone Apollo (PID {Pid}, {Name}) is " + "streaming. Ending this seat's RDP session changes the desktop topology, so " + - "that stream will stall for about a second while its encoder rebuilds. It " + - "recovers on its own. See issue #23.", + "that stream will hitch for a few hundred milliseconds while its encoder " + + "rebuilds. It recovers on its own. See issue #23.", seatId, host.ProcessId, host.HostName ?? "unnamed"); } }