fix(site-runtime): shed or rate-limited traced runs emit a Failed ScriptRun row (arch-review F7)
A traced run refused before launch — by the per-script in-flight cap
(MaxConcurrentRunsPerScript) or by MinTimeBetweenRuns — emitted no ScriptTrace row at
all, so the Flow Debugger reported NO_TRIGGER_WITHIN_WINDOW ("no value-change trigger on
this attribute, or no device echo"), which is wrong in both cases and sends the operator
to check the wrong things.
Both guards now leave a Failed ScriptTrace/ScriptRun row naming the guard that refused
the run, parented to the writing execution and carrying the trigger detail. The new
ScriptRunLauncher.EmitSuppressedRun reuses EmitScriptRun with elapsedMs 0 and no
collector (a shed run has no reply to ride on — the row reaches the debugger via
PullTraceEvents / Replay), resolving the writer and identity providers from a fresh
scope because it runs on the actor thread. Best-effort, never throws, no-op untraced.
Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
@@ -532,6 +532,17 @@ public class ScriptActor : ReceiveActor, IWithTimers
|
||||
_logger.LogDebug(
|
||||
"Script {Script} on {Instance}: skipping execution, min time between runs not elapsed ({Elapsed} < {Min})",
|
||||
_scriptName, _instanceName, elapsed, _minTimeBetweenRuns.Value);
|
||||
// Arch-review F7: a TRACED run refused here is otherwise invisible to the Flow
|
||||
// Debugger, which then blames a missing trigger. Leave a Failed ScriptRun row
|
||||
// naming the guard instead.
|
||||
if (trace)
|
||||
{
|
||||
ScriptRunLauncher.EmitSuppressedRun(
|
||||
_serviceProvider, _logger, _scriptName, _instanceName, parentExecutionId,
|
||||
$"suppressed: MinTimeBetweenRuns ({_minTimeBetweenRuns.Value}) not elapsed " +
|
||||
$"since the previous run ({elapsed} ago).",
|
||||
triggerExtra);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -574,7 +585,7 @@ public class ScriptActor : ReceiveActor, IWithTimers
|
||||
{
|
||||
if (callDepth == 0 && _runsInFlight >= _options.MaxConcurrentRunsPerScript)
|
||||
{
|
||||
ShedRun(replyTo, correlationId);
|
||||
ShedRun(replyTo, correlationId, parentExecutionId, trace, triggerExtra);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -649,8 +660,18 @@ public class ScriptActor : ReceiveActor, IWithTimers
|
||||
/// an unrelated script's run) gets an explicit error so the caller fails fast rather than
|
||||
/// hanging to its Ask timeout. Nested (<c>callDepth > 0</c>) launches never reach here —
|
||||
/// see <see cref="SpawnExecution"/>.
|
||||
///
|
||||
/// <para>Arch-review F7: a traced run shed here also leaves a Failed <c>ScriptRun</c> audit
|
||||
/// row, so the Flow Debugger names the cap rather than reporting a missing trigger. The
|
||||
/// trigger detail (<paramref name="triggerExtra"/>) rides along so the row still says which
|
||||
/// attribute change would have fired the run.</para>
|
||||
/// </summary>
|
||||
private void ShedRun(IActorRef replyTo, string correlationId)
|
||||
private void ShedRun(
|
||||
IActorRef replyTo,
|
||||
string correlationId,
|
||||
Guid? parentExecutionId = null,
|
||||
bool trace = false,
|
||||
ScriptTraceExtra? triggerExtra = null)
|
||||
{
|
||||
_healthCollector?.IncrementScriptRunShed();
|
||||
|
||||
@@ -675,6 +696,15 @@ public class ScriptActor : ReceiveActor, IWithTimers
|
||||
correlationId, false, null,
|
||||
$"shed: {_runsInFlight} runs already in flight"));
|
||||
}
|
||||
|
||||
if (trace)
|
||||
{
|
||||
ScriptRunLauncher.EmitSuppressedRun(
|
||||
_serviceProvider, _logger, _scriptName, _instanceName, parentExecutionId,
|
||||
$"shed: MaxConcurrentRunsPerScript reached — {_runsInFlight} runs already in " +
|
||||
$"flight (cap {_options.MaxConcurrentRunsPerScript}).",
|
||||
triggerExtra);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleExecutionCompleted(ScriptExecutionCompleted msg)
|
||||
|
||||
Reference in New Issue
Block a user