Table of Contents

Client

This page documents Orleans.Lattice.Api.State 9.9.0, in the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at client.md, and llms.txt lists every page.

LatticeStateApiGrpcClient is the public, strongly-typed client for the state-API gRPC surface. It is the consumer half of the gRPC contract: one method per RPC, over Orleans-serialized C# request/response records that either reuse facade DTOs directly or wrap facade arguments and results for transport.

Building a client

Create takes a gRPC CallInvoker and a service provider that has Orleans serialization registered. The service provider supplies the per-message serializers, so its registration must match the server's (AddSerializer()).

using Grpc.Net.Client;
using Microsoft.Extensions.DependencyInjection;
using Orleans.Serialization;

var serializerProvider = new ServiceCollection().AddSerializer().BuildServiceProvider();

using var channel = GrpcChannel.ForAddress("https://cluster.example:5001");
var stateClient = LatticeStateApiGrpcClient.Create(channel.CreateCallInvoker(), serializerProvider);

The client adds only the per-RPC marshalling. Address, TLS, retries, deadlines, and call credentials all live on the GrpcChannel / CallInvoker you pass in, so apply your transport and auth policy there:

using Grpc.Net.Client;
using Grpc.Core;

var credentials = CallCredentials.FromInterceptor((_, metadata) =>
{
    metadata.Add("authorization", "Bearer <token>");
    return Task.CompletedTask;
});

using var channel = GrpcChannel.ForAddress("https://cluster.example:5001", new GrpcChannelOptions
{
    Credentials = ChannelCredentials.Create(ChannelCredentials.SecureSsl, credentials),
});

Calling the surface

The unary RPCs return a Task<TResponse>; the streaming RPCs return an IAsyncEnumerable<TResponse> consumed with await foreach. The full set, with the request and response each carries, is in Surfaces:

  • ListTreesAsync / ListViewsAsync / ListTagIndexesAsync / ListTagValuesAsync - paged discovery catalog.
  • ListCoveredTreesAsync / ListIndexTagsAsync / ScanTagMembersAsync - index-wide tag-index browsing (covered trees, distinct tags, and live tag members across every covered tree).
  • GetTreeStructureAsync - shard-root node graph.
  • ScanEntriesAsync / GetEntryAsync - key-ordered entry scan (snapshot-isolated by default; EntryScanMode.Live / LivePointInTime open a cheaper baseline-free cursor) and single-key fetch.
  • GetEntryHistoryAsync - per-key change-history timeline.
  • CancelScanAsync - release a server-side scan cursor early.
  • GetDeadLetterCountAsync(DeadLetterCountRequest request, CancellationToken cancellationToken = default) - count strict-mode dead-letter entries for one tree.
  • ListDeadLettersAsync(DeadLetterQueueRequest request, CancellationToken cancellationToken = default) - page a tree's strict-mode dead-letter queue.
  • GetMetricsSnapshotAsync - one-shot metrics.
  • GetClusterInfoAsync - connected-cluster identity (cluster id, service id).
  • GetAuthSchemeAsync - the endpoint's advertised auth schemes (unauthenticated; callable before a credential is acquired).
  • ObserveChangesAsync - server-streamed live mutations.
  • ObserveMetricsAsync - server-streamed live metric deltas.

Cancel a streaming call through its CancellationToken to unsubscribe; the server tears the subscription down when the stream ends.

In-process reuse

The facade is transport-agnostic, so a consumer co-located in the silo - for example an in-process introspection host - does not need a network hop. The facade interfaces are public in Orleans.Lattice.Api.Abstractions, so the simplest path resolves ILatticeStateQuery and its observer siblings straight from DI, as the co-hosted Orleans.Lattice.Api.Mcp server does. Alternatively, co-host the gRPC service in the silo process (AddLatticeStateApiGrpc + MapLatticeStateApiGrpc) and dial it over an in-process / loopback channel with the same LatticeStateApiGrpcClient: the client code is identical to the remote case; only the channel address changes. The binding's MCP-reuse parity test pins the transport neutrality both paths rely on: a thin adapter over the facade, with no gRPC in between, returns the same records as the gRPC path for the same requests.

The StateExplorer sample demonstrates the full journey - silo plus gRPC host in one process, a client dialing it over a loopback channel, and a walk through discovery, structure, scan, and a live change tail.

Next

  • Surfaces - each request and response in detail.
  • Security - the channel-side credentials the authorizer validates.