feat(siteruntime): event-driven Attributes.WriteBatchAndWaitAsync (batched DCL write + trigger + existing WaitForAttribute waiter) + compile mirror
This commit is contained in:
@@ -525,6 +525,44 @@ public class ScriptRuntimeContext
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a SET of data-sourced attributes to the device in ONE DCL batch round-trip,
|
||||
/// then writes a trigger flag, then waits EVENT-DRIVEN (reusing the existing
|
||||
/// <see cref="WaitAttribute"/> waiter — not a poll) for <paramref name="responseAttr"/>
|
||||
/// to reach <paramref name="responseEncoded"/>, bounded by <paramref name="timeout"/>.
|
||||
/// Replaces N sequential per-attribute writes with a single gateway call before the
|
||||
/// wait. Throws <see cref="InvalidOperationException"/> if the write/trigger leg fails
|
||||
/// (resolution error, multi-connection batch, device error); returns the wait result
|
||||
/// otherwise (true = matched, false = timeout, never throws on timeout).
|
||||
/// </summary>
|
||||
/// <param name="encodedValues">Scope-resolved attribute name → codec-encoded value to batch-write.</param>
|
||||
/// <param name="triggerAttr">Scope-resolved trigger attribute name written AFTER the batch.</param>
|
||||
/// <param name="triggerEncoded">Codec-encoded value for the trigger.</param>
|
||||
/// <param name="responseAttr">Scope-resolved attribute to wait on.</param>
|
||||
/// <param name="responseEncoded">Codec-encoded target value (null ⇒ any change).</param>
|
||||
/// <param name="timeout">How long to wait for the response before returning false.</param>
|
||||
/// <returns><c>true</c> on response match within the timeout; <c>false</c> on timeout.</returns>
|
||||
public async Task<bool> WriteBatchAndWait(
|
||||
IReadOnlyDictionary<string, string?> encodedValues, string triggerAttr, string? triggerEncoded,
|
||||
string responseAttr, string? responseEncoded, TimeSpan timeout)
|
||||
{
|
||||
var cid = Guid.NewGuid().ToString();
|
||||
var batchReq = new WriteAttributeBatchRequest(
|
||||
cid, _instanceName, encodedValues, triggerAttr, triggerEncoded, DateTimeOffset.UtcNow);
|
||||
|
||||
// 35s: the InstanceActor's DCL Ask is internally bounded at 30s, so allow a small
|
||||
// margin so the DCL's own typed failure/timeout reply is the one we observe rather
|
||||
// than an AskTimeoutException here. Honors the script execution-timeout token.
|
||||
var batchResp = await _instanceActor.Ask<WriteAttributeBatchResponse>(
|
||||
batchReq, TimeSpan.FromSeconds(35), _scriptTimeoutToken);
|
||||
|
||||
if (!batchResp.Success)
|
||||
throw new InvalidOperationException(
|
||||
$"WriteBatchAndWait write failed: {batchResp.ErrorMessage}");
|
||||
|
||||
return await WaitAttribute(responseAttr, responseEncoded, null, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls a sibling script on the same instance by name (Ask pattern).
|
||||
/// WP-20: Enforces recursion limit.
|
||||
|
||||
Reference in New Issue
Block a user