feat(inbound): routed Route.To().WaitForAttribute — contract + central path (spec §6)
This commit is contained in:
@@ -35,4 +35,9 @@ public sealed class CommunicationServiceInstanceRouter : IInstanceRouter
|
||||
public Task<RouteToSetAttributesResponse> RouteToSetAttributesAsync(
|
||||
string siteId, RouteToSetAttributesRequest request, CancellationToken cancellationToken) =>
|
||||
_communicationService.RouteToSetAttributesAsync(siteId, request, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<RouteToWaitForAttributeResponse> RouteToWaitForAttributeAsync(
|
||||
string siteId, RouteToWaitForAttributeRequest request, CancellationToken cancellationToken) =>
|
||||
_communicationService.RouteToWaitForAttributeAsync(siteId, request, cancellationToken);
|
||||
}
|
||||
|
||||
@@ -34,4 +34,12 @@ public interface IInstanceRouter
|
||||
/// <returns>A task that resolves to the set-attributes response from the target site.</returns>
|
||||
Task<RouteToSetAttributesResponse> RouteToSetAttributesAsync(
|
||||
string siteId, RouteToSetAttributesRequest request, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Routes a wait-for-attribute request to the specified site (spec §6).</summary>
|
||||
/// <param name="siteId">Target site identifier.</param>
|
||||
/// <param name="request">The wait-for-attribute request to route (value-equality only).</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the routed call.</param>
|
||||
/// <returns>A task that resolves to the wait-for-attribute response from the target site.</returns>
|
||||
Task<RouteToWaitForAttributeResponse> RouteToWaitForAttributeAsync(
|
||||
string siteId, RouteToWaitForAttributeRequest request, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -205,6 +205,47 @@ public class RouteTarget
|
||||
return response.Values;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Blocks until a remote instance attribute reaches <paramref name="targetValue"/>
|
||||
/// or <paramref name="timeout"/> elapses (spec §6). Value-equality ONLY across the
|
||||
/// wire: the target is canonically encoded via <see cref="AttributeValueCodec"/> and
|
||||
/// the site evaluates equality — there is no predicate and no quality flag in the
|
||||
/// comparison.
|
||||
/// </summary>
|
||||
/// <param name="attributeName">Name of the attribute to wait on.</param>
|
||||
/// <param name="targetValue">Target value the attribute must equal for the wait to match.</param>
|
||||
/// <param name="timeout">Maximum time to wait for the attribute to reach the target value.</param>
|
||||
/// <param name="cancellationToken">Optional cancellation token; defaults to the method deadline.</param>
|
||||
/// <returns>A task that resolves to <c>true</c> if the attribute reached the target value, <c>false</c> if the wait timed out.</returns>
|
||||
public async Task<bool> WaitForAttribute(
|
||||
string attributeName,
|
||||
object? targetValue,
|
||||
TimeSpan timeout,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var token = Effective(cancellationToken);
|
||||
var siteId = await ResolveSiteAsync(token);
|
||||
|
||||
// Audit Log #23 (ParentExecutionId): mirrors the Call path — stamp the
|
||||
// spawning inbound request's ExecutionId so future site-side audit
|
||||
// emission for routed waits can record this wait's parent. CorrelationId
|
||||
// is the per-operation lifecycle id, freshly minted per routed wait.
|
||||
var request = new RouteToWaitForAttributeRequest(
|
||||
Guid.NewGuid().ToString(), _instanceCode, attributeName,
|
||||
AttributeValueCodec.Encode(targetValue), timeout, DateTimeOffset.UtcNow,
|
||||
_parentExecutionId);
|
||||
|
||||
var response = await _instanceRouter.RouteToWaitForAttributeAsync(siteId, request, token);
|
||||
|
||||
if (!response.Success)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
response.ErrorMessage ?? "Remote attribute wait failed");
|
||||
}
|
||||
|
||||
return response.Matched;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a single attribute value on the remote instance.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user