perf(runtime): split trigger evals from the blocking pool; bounded, deadline-aware execution

This commit is contained in:
Joseph Doherty
2026-08-14 22:36:15 -04:00
parent 312216ff2b
commit c4fc1f8ecd
42 changed files with 3673 additions and 1251 deletions
@@ -39,6 +39,12 @@ public class SiteHealthCollector : ISiteHealthCollector
private int _scriptQueueDepth;
private int _scriptBusyThreads;
private long _scriptOldestBusyAgeBits = BitConverter.DoubleToInt64Bits(double.NaN);
// WP3.1: workers detached and replaced by the stuck-script watchdog and not yet exited
// (point-in-time, from the same reporter tick as the gauges above), and the per-interval
// count of runs shed by the per-script in-flight cap (reset on collect like the error
// counters, and restored by AddIntervalCounters when a report fails to send).
private int _scriptDetachedThreads;
private int _scriptRunShedCount;
// WP2.6d: cumulative alarm-publish-queue drop count, refreshed by
// SiteStreamAlarmDropReporter. Point-in-time (not reset on collect), like the
// scheduler gauges above.
@@ -162,12 +168,20 @@ public class SiteHealthCollector : ISiteHealthCollector
}
/// <inheritdoc />
public void SetScriptSchedulerStats(int queueDepth, int busyThreads, double? oldestBusyAgeSeconds)
public void SetScriptSchedulerStats(
int queueDepth, int busyThreads, double? oldestBusyAgeSeconds, int detachedThreads = 0)
{
Interlocked.Exchange(ref _scriptQueueDepth, queueDepth);
Interlocked.Exchange(ref _scriptBusyThreads, busyThreads);
Interlocked.Exchange(ref _scriptOldestBusyAgeBits,
BitConverter.DoubleToInt64Bits(oldestBusyAgeSeconds ?? double.NaN));
Interlocked.Exchange(ref _scriptDetachedThreads, detachedThreads);
}
/// <inheritdoc />
public void IncrementScriptRunShed()
{
Interlocked.Increment(ref _scriptRunShedCount);
}
/// <summary>Reads the atomically-stored oldest-busy script age, mapping the NaN sentinel back to null.</summary>
@@ -283,6 +297,11 @@ public class SiteHealthCollector : ISiteHealthCollector
ScriptQueueDepth = Interlocked.CompareExchange(ref _scriptQueueDepth, 0, 0),
ScriptBusyThreads = Interlocked.CompareExchange(ref _scriptBusyThreads, 0, 0),
ScriptOldestBusyAgeSeconds = ReadScriptOldestBusyAgeSeconds(),
// WP3.1: point-in-time (like the three gauges above), so a CompareExchange read
// rather than an Exchange reset.
DetachedScriptThreads = Interlocked.CompareExchange(ref _scriptDetachedThreads, 0, 0),
// WP3.1: per-interval, so drained on collect like the error counters.
ScriptRunShedCount = Interlocked.Exchange(ref _scriptRunShedCount, 0),
// Both fields come from the ONE snapshot read above. Null (the reporter has
// not run) leaves both report fields null — "no data", not "disconnected
// with an empty backlog".