feat(scripts): reset-aware Attributes.WriteBatchAndWaitAsync overload + deploy-gate mirror (#36)
Claude-Session: https://claude.ai/code/session_01XPsuy2ZZ5Gbyfpt8PrK5BV
This commit is contained in:
@@ -332,6 +332,19 @@ public sealed class ScriptCompileSurface
|
||||
/// <param name="timeout">The maximum time to wait for the response.</param>
|
||||
/// <returns><c>true</c> if the response value was observed before the timeout elapsed; otherwise <c>false</c>.</returns>
|
||||
public Task<bool> WriteBatchAndWaitAsync(IReadOnlyDictionary<string, object?> values, string flagKey, object? flagValue, string responseKey, object? responseValue, TimeSpan timeout) => throw new NotSupportedException(CompileOnly);
|
||||
|
||||
/// <summary>Mirrors the reset-aware <c>AttributeAccessor.WriteBatchAndWaitAsync</c> overload (Gitea #36).</summary>
|
||||
/// <param name="values">The set of attribute values to write as a batch.</param>
|
||||
/// <param name="flagKey">The name of the flag attribute signaling the write.</param>
|
||||
/// <param name="flagValue">The value written to the flag attribute.</param>
|
||||
/// <param name="responseKey">The name of the attribute to observe for a response.</param>
|
||||
/// <param name="responseValue">The value to wait for on the response attribute.</param>
|
||||
/// <param name="timeout">The maximum time to wait for the response.</param>
|
||||
/// <param name="resetKey">The attribute written first and waited on before the batch.</param>
|
||||
/// <param name="resetValue">The reset value the device must echo before the batch is written.</param>
|
||||
/// <param name="resetTimeout">The maximum time to wait for the reset echo; <c>null</c> means <paramref name="timeout"/>.</param>
|
||||
/// <returns>The phase-aware handshake outcome.</returns>
|
||||
public Task<HandshakeResult> WriteBatchAndWaitAsync(IReadOnlyDictionary<string, object?> values, string flagKey, object? flagValue, string responseKey, object? responseValue, TimeSpan timeout, string resetKey, object? resetValue, TimeSpan? resetTimeout = null) => throw new NotSupportedException(CompileOnly);
|
||||
}
|
||||
|
||||
/// <summary>Compile-only mirror of <c>ChildrenAccessor</c>.</summary>
|
||||
|
||||
@@ -111,6 +111,47 @@ public class AttributeAccessor
|
||||
timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset-aware handshake (Gitea #36): writes <paramref name="resetKey"/>=<paramref name="resetValue"/>,
|
||||
/// waits (event-driven, bounded by <paramref name="resetTimeout"/>, default = <paramref name="timeout"/>)
|
||||
/// for the device to ECHO that reset, and only then performs the ordinary
|
||||
/// <see cref="WriteBatchAndWaitAsync(IReadOnlyDictionary{string, object?}, string, object?, string, object?, TimeSpan)"/>
|
||||
/// legs (batch → trigger → response wait). Returns a <see cref="HandshakeResult"/> so a
|
||||
/// script can tell a reset-echo timeout (<see cref="HandshakeResult.ResetFailed"/>; nothing
|
||||
/// else was written) from a completion timeout. Use this for every level-triggered
|
||||
/// flag handshake: without an observed reset the plain overload can be satisfied
|
||||
/// instantly by the previous run's cached response value. Throws
|
||||
/// <see cref="System.InvalidOperationException"/> if the reset write or the batch/trigger
|
||||
/// write itself fails; never throws on either timeout.
|
||||
/// </summary>
|
||||
/// <param name="values">Attribute key → value to batch-write (data-sourced, one connection).</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 after the trigger.</param>
|
||||
/// <param name="responseValue">Target value to wait for (<c>null</c> ⇒ any change).</param>
|
||||
/// <param name="timeout">How long to wait for the response before giving up.</param>
|
||||
/// <param name="resetKey">Attribute written FIRST (usually <paramref name="responseKey"/>); static or data-sourced.</param>
|
||||
/// <param name="resetValue">Value the device must echo back before the batch is written.</param>
|
||||
/// <param name="resetTimeout">How long to wait for the reset echo; <c>null</c> ⇒ <paramref name="timeout"/>.</param>
|
||||
/// <returns>The phase-aware handshake outcome.</returns>
|
||||
public Task<HandshakeResult> WriteBatchAndWaitAsync(
|
||||
IReadOnlyDictionary<string, object?> values, string flagKey, object? flagValue,
|
||||
string responseKey, object? responseValue, TimeSpan timeout,
|
||||
string resetKey, object? resetValue, TimeSpan? resetTimeout = null)
|
||||
{
|
||||
var encoded = new Dictionary<string, string?>(values.Count);
|
||||
foreach (var kv in values)
|
||||
encoded[Resolve(kv.Key)] = AttributeValueCodec.Encode(kv.Value);
|
||||
|
||||
return _ctx.WriteBatchResetAndWait(
|
||||
encoded,
|
||||
Resolve(flagKey), AttributeValueCodec.Encode(flagValue),
|
||||
Resolve(responseKey), AttributeValueCodec.Encode(responseValue),
|
||||
timeout,
|
||||
Resolve(resetKey), AttributeValueCodec.Encode(resetValue),
|
||||
resetTimeout ?? timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WaitForAttribute (spec §3-§5): waits event-driven until the attribute equals
|
||||
/// <paramref name="targetValue"/> (value-equality, codec-normalized), bounded by
|
||||
|
||||
Reference in New Issue
Block a user