fix(site-runtime): artifact-apply watchdog + queued-apply failure on stop, boot-skip site event, enable revert, batch Ask slack (review 2026-10-21 lane A L1-L4)

L1: an artifact apply holding the slot past 10 min (ctor-overridable) logs an
Error site event naming it without releasing the slot; PostStop answers
queued applies Failed. L2: a boot-batch instance whose actor cannot be created
emits an Error site event and leaves the deployed set. L3: a failed enable
reverts the committed is_enabled (generation-bumped both ends). L4: the routed
SetAttributes batch Ask is the 30 s per-write bound plus 10 s mailbox slack.
This commit is contained in:
Joseph Doherty
2026-10-22 09:06:28 -04:00
parent 099b2221d6
commit 6f6534ac7e
4 changed files with 158 additions and 12 deletions
@@ -98,4 +98,34 @@ public class DeploymentManagerArtifactSerializationTests : TestKit, IDisposable
Assert.True(_sharedScriptLibrary.Contains("Z"));
Assert.DoesNotContain(_sharedScriptLibrary.GetRegisteredScriptNames(), n => n.StartsWith("Slow"));
}
/// <summary>
/// Lane A L1: an apply that holds the slot past the watchdog is named in an Error site event,
/// and queued deploys are answered Failed when the manager stops.
/// </summary>
[Fact]
public void StuckApply_IsReported_AndQueuedAppliesAreFailedOnStop()
{
var siteLog = new FakeSiteEventLogger();
var dm = ActorOf(Props.Create(() => new DeploymentManagerActor(
_storage, _compilationService, _sharedScriptLibrary, null,
new SiteRuntimeOptions { InstanceSweepIntervalSeconds = 0 },
NullLogger<DeploymentManagerActor>.Instance,
null, null, new SingleServiceProvider(siteLog), null, null, null, null, null, null, null, null,
null, null, TimeSpan.FromMilliseconds(200))));
var slowSet = Enumerable.Range(0, 60).Select(i => $"Stuck{i}").ToList();
var queuedSender = CreateTestProbe();
dm.Tell(SharedScripts("dep-slow", slowSet));
dm.Tell(SharedScripts("dep-queued", ["Q"]), queuedSender.Ref);
AwaitAssert(() => Assert.Contains(siteLog.OfType("deployment"), r =>
r.Severity == "Error" && r.Message.Contains("dep-slow", StringComparison.Ordinal)),
TimeSpan.FromSeconds(10), TimeSpan.FromMilliseconds(50));
Sys.Stop(dm);
var failed = queuedSender.ExpectMsg<ArtifactDeploymentResponse>(TimeSpan.FromSeconds(10));
Assert.Equal("dep-queued", failed.DeploymentId);
Assert.False(failed.Success);
}
}