mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-26 05:29:43 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b1e7077d0a |
@@ -258,6 +258,18 @@ namespace AutopilotMonitor.Agent.V2.Core.Transport.Telemetry
|
||||
_pendingBytes -= _pending.First.Value.ByteLength;
|
||||
_pending.RemoveFirst();
|
||||
}
|
||||
|
||||
// _pendingBytes drives the spool-pressure trigger: negative drift would
|
||||
// silently disarm it, a stale positive on an empty list would pin it on.
|
||||
// The list is authoritative — on drift, recompute from it and log loudly.
|
||||
if (_pendingBytes < 0 || (_pending.Count == 0 && _pendingBytes != 0))
|
||||
{
|
||||
long recomputed = 0;
|
||||
foreach (var entry in _pending) recomputed += entry.ByteLength;
|
||||
_logger?.Warning(
|
||||
$"TelemetrySpool: pending-bytes accounting drifted to {_pendingBytes} with {_pending.Count} pending items after MarkUploaded({upToItemIdInclusive}) — recomputed to {recomputed}.");
|
||||
_pendingBytes = recomputed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -192,6 +192,33 @@ namespace AutopilotMonitor.DecisionCore.Tests
|
||||
Assert.Equal(SessionStage.Completed, completed.NewState.Stage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BackstopFired_WithoutDesktop_ParksInAwaitingDesktopUntilDesktopCompletes()
|
||||
{
|
||||
// The arming site (HandleDesktopArrivedV1) guarantees desktop-first, so this
|
||||
// fires only on a stale/replayed timer — Dispatch routes DeadlineFired purely on
|
||||
// the payload name, no armed-state check. The fallback must keep the handler
|
||||
// total: synthetic Hello timeout recorded, session parks in AwaitingDesktop, and
|
||||
// a later real desktop arrival still completes it.
|
||||
var engine = new DecisionEngine();
|
||||
var state = SeedWdpSession(engine);
|
||||
|
||||
var fired = engine.Reduce(state, DeadlineFired(20, T0.AddMinutes(39), DeadlineNames.DevicePrepCompletion));
|
||||
|
||||
Assert.Equal(SessionStage.AwaitingDesktop, fired.NewState.Stage);
|
||||
Assert.NotNull(fired.NewState.HelloResolvedUtc);
|
||||
Assert.Equal("Timeout", fired.NewState.HelloOutcome!.Value);
|
||||
Assert.DoesNotContain(fired.NewState.Deadlines, d => d.Name == DeadlineNames.DevicePrepCompletion);
|
||||
|
||||
// Hello is satisfied (synthetically) — only the desktop is still missing.
|
||||
var waiting = Assert.Single(CompletionWaitingEffects(fired));
|
||||
Assert.Equal("desktop_arrival", waiting.Parameters!["missingPrerequisites"]);
|
||||
|
||||
var completed = engine.Reduce(fired.NewState,
|
||||
MakeSignal(21, DecisionSignalKind.DesktopArrived, T0.AddMinutes(45)));
|
||||
Assert.Equal(SessionStage.Finalizing, completed.NewState.Stage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HelloResolved_BeforeBackstopFires_CompletesNormally()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user