feat(sitecall-audit): carry + persist SourceNode end-to-end via cached telemetry
Site: site emitters of SiteCallOperational (ExternalSystemClient, the script-API cached call path in ScriptRuntimeContext, CachedCallLifecycleBridge) inject INodeIdentityProvider and stamp SourceNode = NodeName at construction. OperationTrackingStore call site in CachedCallTelemetryForwarder now stamps SourceNode too. Central: SiteCallAuditRepository.UpsertAsync INSERT includes SourceNode in the column list; conditional monotonic UPDATE uses COALESCE(@SourceNode, SourceNode) so later packets cannot blank a previously- stamped value. After this commit every SiteCalls row carries node-a/node-b in SourceNode (subject to monotonic preservation).
This commit is contained in:
@@ -310,7 +310,11 @@ public class ScriptRuntimeContext
|
||||
_cachedForwarder,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning execution's id,
|
||||
// threaded alongside _executionId. Null for non-routed runs.
|
||||
_parentExecutionId);
|
||||
_parentExecutionId,
|
||||
// SourceNode-stamping (Task 14): the local node name (node-a/node-b),
|
||||
// threaded so the cached-call telemetry construction sites can stamp
|
||||
// it onto SiteCallOperational.SourceNode.
|
||||
_sourceNode);
|
||||
|
||||
/// <summary>
|
||||
/// WP-13: Provides access to database operations.
|
||||
@@ -334,7 +338,11 @@ public class ScriptRuntimeContext
|
||||
_cachedForwarder,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning execution's id,
|
||||
// threaded alongside _executionId. Null for non-routed runs.
|
||||
_parentExecutionId);
|
||||
_parentExecutionId,
|
||||
// SourceNode-stamping (Task 14): the local node name (node-a/node-b),
|
||||
// threaded so Database.CachedWrite's CachedSubmit telemetry can
|
||||
// stamp it onto SiteCallOperational.SourceNode.
|
||||
_sourceNode);
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to the Notification Outbox API.
|
||||
@@ -453,6 +461,16 @@ public class ScriptRuntimeContext
|
||||
private readonly string? _sourceScript;
|
||||
private readonly ICachedCallTelemetryForwarder? _cachedForwarder;
|
||||
|
||||
/// <summary>
|
||||
/// SourceNode-stamping (Task 14): the local cluster node name on
|
||||
/// which this script is executing (<c>node-a</c>/<c>node-b</c>).
|
||||
/// Stamped onto <c>SiteCallOperational.SourceNode</c> on the three
|
||||
/// cached-call telemetry construction sites (CachedSubmit + the two
|
||||
/// immediate-completion rows) so central can persist it on the
|
||||
/// <c>SiteCalls</c> row.
|
||||
/// </summary>
|
||||
private readonly string? _sourceNode;
|
||||
|
||||
// Internal constructor for tests living in ScadaLink.SiteRuntime.Tests
|
||||
// (via InternalsVisibleTo). Production sites resolve the helper through
|
||||
// ScriptRuntimeContext.ExternalSystem.
|
||||
@@ -474,7 +492,8 @@ public class ScriptRuntimeContext
|
||||
string siteId = "",
|
||||
string? sourceScript = null,
|
||||
ICachedCallTelemetryForwarder? cachedForwarder = null,
|
||||
Guid? parentExecutionId = null)
|
||||
Guid? parentExecutionId = null,
|
||||
string? sourceNode = null)
|
||||
{
|
||||
_client = client;
|
||||
_instanceName = instanceName;
|
||||
@@ -485,6 +504,7 @@ public class ScriptRuntimeContext
|
||||
_sourceScript = sourceScript;
|
||||
_cachedForwarder = cachedForwarder;
|
||||
_parentExecutionId = parentExecutionId;
|
||||
_sourceNode = sourceNode;
|
||||
}
|
||||
|
||||
public async Task<ExternalCallResult> Call(
|
||||
@@ -670,9 +690,11 @@ public class ScriptRuntimeContext
|
||||
Channel: "ApiOutbound",
|
||||
Target: target,
|
||||
SourceSite: _siteId,
|
||||
// SourceNode: stamped by Task 14 once the script context
|
||||
// gets an INodeIdentityProvider; null until then.
|
||||
SourceNode: null,
|
||||
// SourceNode-stamping (Task 14): the local node name
|
||||
// (node-a/node-b) — threaded through INodeIdentityProvider
|
||||
// at the ScriptExecutionActor; null when no provider was
|
||||
// wired so central persists SiteCalls.SourceNode as NULL.
|
||||
SourceNode: _sourceNode,
|
||||
Status: "Submitted",
|
||||
RetryCount: 0,
|
||||
LastError: null,
|
||||
@@ -791,9 +813,11 @@ public class ScriptRuntimeContext
|
||||
Channel: "ApiOutbound",
|
||||
Target: target,
|
||||
SourceSite: _siteId,
|
||||
// SourceNode: stamped by Task 14 once the script context
|
||||
// gets an INodeIdentityProvider; null until then.
|
||||
SourceNode: null,
|
||||
// SourceNode-stamping (Task 14): the local node name
|
||||
// (node-a/node-b) — threaded through INodeIdentityProvider
|
||||
// at the ScriptExecutionActor; null when no provider was
|
||||
// wired so central persists SiteCalls.SourceNode as NULL.
|
||||
SourceNode: _sourceNode,
|
||||
Status: "Attempted",
|
||||
// RetryCount stays 0 — the operation never reached the
|
||||
// S&F retry sweep, so no retries were performed.
|
||||
@@ -861,9 +885,11 @@ public class ScriptRuntimeContext
|
||||
Channel: "ApiOutbound",
|
||||
Target: target,
|
||||
SourceSite: _siteId,
|
||||
// SourceNode: stamped by Task 14 once the script context
|
||||
// gets an INodeIdentityProvider; null until then.
|
||||
SourceNode: null,
|
||||
// SourceNode-stamping (Task 14): the local node name
|
||||
// (node-a/node-b) — threaded through INodeIdentityProvider
|
||||
// at the ScriptExecutionActor; null when no provider was
|
||||
// wired so central persists SiteCalls.SourceNode as NULL.
|
||||
SourceNode: _sourceNode,
|
||||
Status: operationalTerminalStatus,
|
||||
RetryCount: 0,
|
||||
LastError: result.Success ? null : result.ErrorMessage,
|
||||
@@ -1120,6 +1146,15 @@ public class ScriptRuntimeContext
|
||||
/// </summary>
|
||||
private readonly IAuditWriter? _auditWriter;
|
||||
|
||||
/// <summary>
|
||||
/// SourceNode-stamping (Task 14): the local cluster node name on
|
||||
/// which this script is executing (<c>node-a</c>/<c>node-b</c>).
|
||||
/// Stamped onto <c>SiteCallOperational.SourceNode</c> at the
|
||||
/// <c>Database.CachedWrite</c> CachedSubmit telemetry construction
|
||||
/// site so central can persist it on the <c>SiteCalls</c> row.
|
||||
/// </summary>
|
||||
private readonly string? _sourceNode;
|
||||
|
||||
// Parameter ordering: executionId sits immediately after the
|
||||
// ILogger — see the note on ExternalSystemHelper's ctor for why the
|
||||
// post-logger slot is the one consistent position across all four
|
||||
@@ -1133,7 +1168,8 @@ public class ScriptRuntimeContext
|
||||
string siteId = "",
|
||||
string? sourceScript = null,
|
||||
ICachedCallTelemetryForwarder? cachedForwarder = null,
|
||||
Guid? parentExecutionId = null)
|
||||
Guid? parentExecutionId = null,
|
||||
string? sourceNode = null)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_instanceName = instanceName;
|
||||
@@ -1144,6 +1180,7 @@ public class ScriptRuntimeContext
|
||||
_sourceScript = sourceScript;
|
||||
_cachedForwarder = cachedForwarder;
|
||||
_parentExecutionId = parentExecutionId;
|
||||
_sourceNode = sourceNode;
|
||||
}
|
||||
|
||||
public async Task<System.Data.Common.DbConnection> Connection(
|
||||
@@ -1274,9 +1311,11 @@ public class ScriptRuntimeContext
|
||||
Channel: "DbOutbound",
|
||||
Target: target,
|
||||
SourceSite: _siteId,
|
||||
// SourceNode: stamped by Task 14 once the script context
|
||||
// gets an INodeIdentityProvider; null until then.
|
||||
SourceNode: null,
|
||||
// SourceNode-stamping (Task 14): the local node name
|
||||
// (node-a/node-b) — threaded through INodeIdentityProvider
|
||||
// at the ScriptExecutionActor; null when no provider was
|
||||
// wired so central persists SiteCalls.SourceNode as NULL.
|
||||
SourceNode: _sourceNode,
|
||||
Status: "Submitted",
|
||||
RetryCount: 0,
|
||||
LastError: null,
|
||||
|
||||
Reference in New Issue
Block a user