fix(siteruntime): injectable ScriptExecutionScheduler + un-leakable expression-fault test (#16, #18) #21

Merged
dohertj2 merged 1 commits from fix/script-scheduler-seam-16-18 into main 2026-07-17 16:07:39 -04:00
Owner

Fixes #16 and #18.

#18 — injection seam. ScriptExecutionScheduler was reached via its static Shared() singleton directly inside all five consumers (ScriptActor, ScriptExecutionActor, AlarmActor, AlarmExecutionActor, ScriptSchedulerStatsReporter), so it was un-substitutable. Each now takes an optional scheduler param: the Host injects nothing and gets the shared pool (byte-for-byte unchanged); a test (or future multi-site host) can hand an actor its own instance. Spawning actors thread it down to their execution children. Shared() also recreates a disposed cached instance rather than returning it (new IsDisposed guard), closing #18's latent disposed-singleton poisoning.

#16 — flake. 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 other test classes. EvalGate's wait is bounded to 30s (was unbounded — the leak), reset per test, and teardown releases one permit per worker instead of Release(Entries) (which under-released in exactly the failure case).

Verification: full solution build 0/0; SiteRuntime suite 6/6 runs green (524/524 each) — was 3/6 failing on clean main. Component-SiteRuntime.md updated.

Fixes #16 and #18. **#18 — injection seam.** `ScriptExecutionScheduler` was reached via its static `Shared()` singleton directly inside all five consumers (ScriptActor, ScriptExecutionActor, AlarmActor, AlarmExecutionActor, ScriptSchedulerStatsReporter), so it was un-substitutable. Each now takes an optional scheduler param: the Host injects nothing and gets the shared pool (byte-for-byte unchanged); a test (or future multi-site host) can hand an actor its own instance. Spawning actors thread it down to their execution children. `Shared()` also recreates a disposed cached instance rather than returning it (new `IsDisposed` guard), closing #18's latent disposed-singleton poisoning. **#16 — flake.** 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 other test classes. EvalGate's wait is bounded to 30s (was unbounded — the leak), reset per test, and teardown releases one permit per worker instead of Release(Entries) (which under-released in exactly the failure case). **Verification:** full solution build 0/0; SiteRuntime suite 6/6 runs green (524/524 each) — was 3/6 failing on clean main. Component-SiteRuntime.md updated.
dohertj2 added 1 commit 2026-07-17 16:07:27 -04:00
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
dohertj2 merged commit b1b4874090 into main 2026-07-17 16:07:39 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/ScadaBridge#21