45 lines
2.2 KiB
C#
45 lines
2.2 KiB
C#
namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts;
|
|
|
|
/// <summary>
|
|
/// Flow Debugger step logs (design 2026-09-09 D6): the ambient "which step is running right now"
|
|
/// marker used to attribute runtime-sourced log lines to a step node.
|
|
///
|
|
/// <para>A <c>ScriptLog</c> row names its owning step explicitly (D2), but the runtime lines the
|
|
/// node logs on the script's behalf are produced deep inside a helper — the helper knows its
|
|
/// pre-minted step <c>EventId</c>, the logging call site does not. Rather than thread that id
|
|
/// through every internal call, the helpers open a scope around their body and
|
|
/// <see cref="ScriptLogger"/> reads <see cref="Current"/> when no explicit id is supplied.</para>
|
|
///
|
|
/// <para><see cref="AsyncLocal{T}"/> so the value flows through the helper's own awaits and
|
|
/// nowhere else: it is captured by continuations started inside the scope and is invisible to
|
|
/// concurrent runs on other threads of the script execution pool. Lines logged outside any scope
|
|
/// see <see langword="null"/> and fall back to the execution's anchor row (D2).</para>
|
|
/// </summary>
|
|
public static class TraceStepScope
|
|
{
|
|
private static readonly AsyncLocal<Guid?> _current = new();
|
|
|
|
/// <summary>The step <c>EventId</c> owning the currently executing helper body, or <see langword="null"/> outside any scope.</summary>
|
|
public static Guid? Current => _current.Value;
|
|
|
|
/// <summary>
|
|
/// Sets the current step for the scope's lifetime; restores the previous value on dispose,
|
|
/// so nested scopes (a helper calling another helper) unwind correctly.
|
|
/// </summary>
|
|
/// <param name="stepEventId">The pre-minted <c>EventId</c> of the step row this body belongs to.</param>
|
|
/// <returns>A handle that restores the previous ambient value when disposed.</returns>
|
|
public static IDisposable Enter(Guid stepEventId)
|
|
{
|
|
var prev = _current.Value;
|
|
_current.Value = stepEventId;
|
|
return new Restore(prev);
|
|
}
|
|
|
|
/// <summary>Restores the ambient step id captured at <see cref="Enter"/> time.</summary>
|
|
private sealed class Restore(Guid? prev) : IDisposable
|
|
{
|
|
/// <inheritdoc />
|
|
public void Dispose() => _current.Value = prev;
|
|
}
|
|
}
|