.NET Location Configuration And Operations Public Interface¶
.NET per-language interface table of contents · Location Runtime · Provider SPI · Host Monitoring
1. Scope¶
This document only defines the Location configuration, readiness, and operational queries the application uses. The technical primitives the Store provider implements are owned by the provider SPI.
Authority key/version, owner token, descriptor record, capacity fence, reservation, aggregate, and relocation reference are framework-internal information, so they aren't declared in this application contract.
2. Location Option¶
public sealed class ZLinkLocationOptions
{
public TimeSpan OwnerLeaseRenewInterval { get; set; }
= TimeSpan.FromSeconds(5);
public TimeSpan OwnerLeaseTtl { get; set; }
= TimeSpan.FromSeconds(15);
public TimeSpan PollingInterval { get; set; }
= TimeSpan.FromSeconds(1);
public TimeSpan StoreFailureGrace { get; set; }
= TimeSpan.FromSeconds(30);
public TimeSpan OwnerLeaseFencingMargin { get; set; }
= TimeSpan.FromSeconds(5);
public TimeSpan OwnerLeaseRenewTimeout { get; set; }
= TimeSpan.FromSeconds(3);
public TimeSpan RouteCacheMaxAge { get; set; }
= TimeSpan.FromSeconds(15);
public TimeSpan MessageFollowDuration { get; set; }
= TimeSpan.FromSeconds(30);
public TimeSpan SessionRelocationSealTimeout { get; set; }
= TimeSpan.FromSeconds(3);
public long RelocationPayloadChunkLimit { get; set; }
= 256 * 1024;
public long RelocationInFlightPayloadBudget { get; set; }
= 16 * 1024 * 1024;
public long RelocationNodeInFlightPayloadBudget { get; set; }
= 0;
public TimeSpan RelocationCutoverWaitTimeout { get; set; }
= TimeSpan.FromSeconds(1);
}
The signature of the root's AddLocationStore(...),
AddRelocationStore(...), and ConfigureLocations() is owned by
Topology Configuration.
Exactly one Store is registered per role. Registering the same role twice
fails startup with ZLinkConfigurationException before socket bind.
Lease and polling options must be greater than 0. Every Location host must satisfy the following relationship.
RouteCacheMaxAge and MessageFollowDuration are at least 0. If both
are positive, cache age must be at least 5 seconds smaller than the
Message Follow duration. 0 turns that feature off.
SessionRelocationSealTimeout is a startup-only positive duration with a three-second
default. Zero, negative, infinite, or a value not representable as finite milliseconds is
a configuration error before socket bind.
RelocationPayloadChunkLimit is the maximum size in bytes of one encoded chunk of a
relocation payload, defaulting to 256 KiB. Setting it above the frame limit the
transport negotiated is a startup configuration error before socket bind.
RelocationInFlightPayloadBudget caps the sum of relocation chunk bytes concurrently
in flight per peer connection, defaulting to 16 MiB; 0 disables the budget.
RelocationNodeInFlightPayloadBudget applies the same accounting rule to the
node-wide sum and defaults to 0, meaning not applied. RelocationCutoverWaitTimeout
is both the time the target waits for cutover and the time the source keeps its
boundary batch copy for retransmission, defaulting to one second. All four values are
startup-only, and negative values are a configuration error before socket bind.
3. Readiness And Operational Queries¶
public sealed record ZLinkLocationRuntimeStatus(
bool StoreHealthy,
bool OwnerLeaseHealthy,
DateTimeOffset? LastRefreshAt,
DateTimeOffset? OwnerLeaseRenewedAt);
public enum ZLinkLocationTopologyState
{
Discovered = 1,
Connecting = 2,
Ready = 3,
Lost = 4,
Error = 5,
Stopped = 6
}
public sealed record ZLinkLocationTopologyFilter(
string? MeshName = null,
RoutingId? NodeRid = null,
ZLinkLocationTopologyState? State = null);
public sealed record ZLinkLocationTopologyEntry(
string MeshName,
RoutingId NodeRid,
string Endpoint,
bool Draining,
ZLinkLocationTopologyState State,
DateTimeOffset UpdatedAt);
public sealed record ZLinkLocationServiceSummaryFilter(
string? MeshName = null);
public sealed record ZLinkLocationServiceSummary(
string MeshName,
uint TotalCount,
uint ReadyCount,
uint ErrorCount,
uint StoppedCount,
DateTimeOffset LastUpdatedAt);
public enum ZLinkLocationObjectKind
{
Actor = 0,
UserSpot = 1,
InstanceSpot = 2
}
public enum ZLinkLocationObjectState
{
Creating = 0,
Ready = 1,
Unavailable = 2
}
public sealed record ZLinkLocationObjectEntry(
string GlobalId,
ulong ObjectGeneration,
string MeshName,
RoutingId NodeRid,
ZLinkLocationObjectState State,
string StableType);
public sealed record ZLinkLocationObjectFilter(
ZLinkLocationObjectKind ObjectKind,
string? StableType = null,
string? MeshName = null);
public readonly record struct ZLinkPageRequest(
int PageSize = 100,
string? ContinuationToken = null);
public sealed record ZLinkLocationPage<T>(
IReadOnlyList<T> Items,
string? ContinuationToken);
public interface IZLinkLocationReadiness
{
ValueTask<bool> IsPeerReadyAsync(
string meshName,
ZLinkLocationRole role,
RoutingId? nodeRid = null,
CancellationToken cancellationToken = default);
}
public interface IZLinkLocationRuntimeQuery
{
ValueTask<ZLinkLocationRuntimeStatus> GetStatusAsync(
CancellationToken cancellationToken = default);
ValueTask<ZLinkLocationPage<ZLinkLocationTopologyEntry>> ListTopologyAsync(
ZLinkLocationTopologyFilter filter,
ZLinkPageRequest page = default,
CancellationToken cancellationToken = default);
ValueTask<ZLinkLocationPage<ZLinkLocationServiceSummary>>
ListServiceSummariesAsync(
ZLinkLocationServiceSummaryFilter filter,
ZLinkPageRequest page = default,
CancellationToken cancellationToken = default);
ValueTask<ZLinkLocationObjectEntry?> FindActorLocationAsync(
string actorId,
CancellationToken cancellationToken = default);
ValueTask<ZLinkLocationObjectEntry?> FindSpotLocationAsync(
string spotId,
CancellationToken cancellationToken = default);
ValueTask<ZLinkLocationPage<ZLinkLocationObjectEntry>>
ListObjectLocationsAsync(
ZLinkLocationObjectFilter filter,
ZLinkPageRequest page = default,
CancellationToken cancellationToken = default);
}
public enum ZLinkLocationRole : ushort
{
Invalid = 0,
Spot = 2,
Router = 3,
Dealer = 4,
Pub = 5,
Sub = 6
}
An operational query only returns human-readable health/topology/service
summary and object location. It doesn't return Store key/version, owner lease generation,
descriptor payload, or protocol envelope. NodeRid is kept as the public
RoutingId since it's the actual transport routing identity.
Page size is 1..1000, and the continuation token is an opaque value
issued by that query. The application doesn't interpret the token or use
it in a different query.
Direct lookup by Actor ID and Spot ID each queries one current object
location. Missing returns null; Creating returns a Creating entry;
Ready returns a Ready entry; and an unavailable current owner after
commit returns an Unavailable entry. Spot direct lookup treats User Spot
and Instance Spot under the same Spot-ID lookup contract. A list requires
ObjectKind, and takes StableType and MeshName as optional filters.
The encoded page is at most 4 MiB. A Store query failure is
ZLinkFrameworkErrorKind.Unavailable and does not return a partial page.
4. Host Maintenance¶
Host maintenance is owned by IZLinkFrameworkRuntime.RelocateAsync(...)
and ShutdownAsync(...). RelocateAsync(...) moves as much workload as
possible to a different owner and completes in the Relocated state.
PlannedMaintenance only moves to the same application version as
source, and doesn't take a target version. RollingUpdate requires a
target version greater than source, and only moves to a node matching
that version exactly. Both modes restrict and select candidates in the
order version, maintenance wave, capability, capacity, placement weight.
If there's no target satisfying the requested condition, it waits until
the deadline and then completes with Blocked/TargetUnavailable. The
application can shut down the host with ShutdownAsync(...) after
confirming the result. Calling ShutdownAsync(...) directly from
Serving doesn't start a new relocation, and shuts down the host after
bounded cleanup. The signature and result are owned by
Host Monitoring.