feat(siteruntime): event-driven Attributes.WriteBatchAndWaitAsync (batched DCL write + trigger + existing WaitForAttribute waiter) + compile mirror

This commit is contained in:
Joseph Doherty
2026-06-17 12:13:02 -04:00
parent e8db6c71a8
commit 0e989c867d
8 changed files with 363 additions and 0 deletions
@@ -74,6 +74,40 @@ public class AttributeAccessor
public Task SetAsync(string key, object? value)
=> _ctx.SetAttribute(Resolve(key), AttributeValueCodec.Encode(value) ?? string.Empty);
/// <summary>
/// Writes a SET of data-sourced attributes to the device in ONE gateway batch
/// round-trip, then writes <paramref name="flagKey"/>=<paramref name="flagValue"/>,
/// then waits EVENT-DRIVEN (reusing the existing <c>WaitForAttribute</c> waiter — not a
/// poll) for <paramref name="responseKey"/> to reach <paramref name="responseValue"/>,
/// bounded by <paramref name="timeout"/>. Replaces N sequential per-attribute writes
/// with one batched call before the wait. All keys are scope-resolved (<see cref="Resolve"/>)
/// and all values codec-encoded just like the other accessors. Returns <c>true</c> if
/// the response was observed within the timeout, <c>false</c> on timeout (no throw on
/// timeout); throws <see cref="System.InvalidOperationException"/> if the batch/trigger
/// write itself fails.
/// </summary>
/// <param name="values">Attribute key → value to batch-write (keys scope-resolved, values codec-encoded).</param>
/// <param name="flagKey">Trigger attribute key written AFTER the batch.</param>
/// <param name="flagValue">Value to write to the trigger.</param>
/// <param name="responseKey">Attribute key to wait on.</param>
/// <param name="responseValue">Target value to wait for (<c>null</c> ⇒ any change).</param>
/// <param name="timeout">How long to wait before returning false.</param>
/// <returns><c>true</c> on response match within the timeout; <c>false</c> on timeout.</returns>
public Task<bool> WriteBatchAndWaitAsync(
IReadOnlyDictionary<string, object?> values, string flagKey, object? flagValue,
string responseKey, object? responseValue, TimeSpan timeout)
{
var encoded = new Dictionary<string, string?>(values.Count);
foreach (var kv in values)
encoded[Resolve(kv.Key)] = AttributeValueCodec.Encode(kv.Value);
return _ctx.WriteBatchAndWait(
encoded,
Resolve(flagKey), AttributeValueCodec.Encode(flagValue),
Resolve(responseKey), AttributeValueCodec.Encode(responseValue),
timeout);
}
/// <summary>
/// WaitForAttribute (spec §3-§5): waits event-driven until the attribute equals
/// <paramref name="targetValue"/> (value-equality, codec-normalized), bounded by