fix(siteruntime): injectable ScriptExecutionScheduler + un-leakable expression-fault test
Gitea #18: the process-wide ScriptExecutionScheduler was reached via a static singleton (Shared) directly inside ScriptActor, ScriptExecutionActor, AlarmActor, AlarmExecutionActor, and ScriptSchedulerStatsReporter, so it could not be substituted — a shared mutable global for anything running more than one logical site in a process, most visibly the test assembly. Add an optional scheduler injection seam to all five: the Host injects nothing and gets the shared pool (byte-for-byte unchanged), while a test (or a future multi-site host) hands an actor its own instance. Spawning actors thread their scheduler down to the execution children they create. Shared() now also recreates a disposed cached instance rather than returning it (new IsDisposed guard), so a disposed scheduler can never silently poison every later script/alarm execution. Gitea #16: ScriptActorTests now runs on its OWN scheduler (disposed at class teardown), so the faulted-task test can no longer strand a worker on the process-wide pool and starve unrelated test classes (one prior run failed 22 tests). EvalGate's wait is bounded to 30 s (was unbounded — the actual leak mechanism) and reset per test; the teardown releases one permit per worker instead of Release(Entries), which under-released in exactly the failure case. Full SiteRuntime suite: 6/6 runs green (524/524); was 3/6 failing on clean main. Fixes: #18 Fixes: #16
This commit was merged in pull request #21.
This commit is contained in:
+18
@@ -45,6 +45,24 @@ public class ScriptExecutionSchedulerTests
|
||||
Assert.Same(a, b);
|
||||
}
|
||||
|
||||
// Gitea #18: IsDisposed backs the Shared() recreate guard so a disposed scheduler
|
||||
// can never be handed back and silently poison every later execution. Verified on a
|
||||
// local instance — deliberately NOT by disposing the process-wide singleton, which
|
||||
// would strand any script another test class queued on it (the very static hazard
|
||||
// #18 is about).
|
||||
[Fact]
|
||||
public void IsDisposed_FlipsOnDispose()
|
||||
{
|
||||
var scheduler = new ScriptExecutionScheduler(1);
|
||||
Assert.False(scheduler.IsDisposed);
|
||||
|
||||
scheduler.Dispose();
|
||||
Assert.True(scheduler.IsDisposed);
|
||||
|
||||
scheduler.Dispose(); // idempotent — stays disposed, does not throw
|
||||
Assert.True(scheduler.IsDisposed);
|
||||
}
|
||||
|
||||
// SiteRuntime-S2/UA5: the scheduler exposes observability gauges so a stuck /
|
||||
// saturated script-execution pool is visible to operators via site health.
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user