namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts; /// /// 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. /// /// A ScriptLog 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 EventId, the logging call site does not. Rather than thread that id /// through every internal call, the helpers open a scope around their body and /// reads when no explicit id is supplied. /// /// 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 and fall back to the execution's anchor row (D2). /// public static class TraceStepScope { private static readonly AsyncLocal _current = new(); /// The step EventId owning the currently executing helper body, or outside any scope. public static Guid? Current => _current.Value; /// /// 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. /// /// The pre-minted EventId of the step row this body belongs to. /// A handle that restores the previous ambient value when disposed. public static IDisposable Enter(Guid stepEventId) { var prev = _current.Value; _current.Value = stepEventId; return new Restore(prev); } /// Restores the ambient step id captured at time. private sealed class Restore(Guid? prev) : IDisposable { /// public void Dispose() => _current.Value = prev; } }