Skip to content

Rust — Client API

The client API starts a transport, opens one runtime session, submits work, receives events, and sends control-plane updates. Core metadata types are documented in Core Types.

Dependencies

toml
[dependencies]
nnrp-core = "1.0.0-preview.4.17"
nnrp-runtime = "1.0.0-preview.4.17"
nnrp-transport-tcp = "1.0.0-preview.4.17"
nnrp-transport-quic = "1.0.0-preview.4.17"
nnrp-transport-ipc = "1.0.0-preview.4.17"
nnrp-transport-websocket = "1.0.0-preview.4.17"
tokio = { version = "1", features = ["macros", "rt-multi-thread", "net", "io-util"] }

Workflow

  1. Build NnrpClientOptions with one application endpoint and a provider route set.
  2. Register the transport providers compiled into this deployment.
  3. Connect with NnrpClient::connect; Auto/Prefer evaluates every eligible provider route.
  4. Open a session with NnrpClient::open_session.
  5. Submit work with NnrpClientSession::submit.
  6. Receive output and control events with await_event.
  7. Close the session with close.

NnrpClient::connect

rust
let options = NnrpClientOptions {
    endpoint: "nnrps://runtime.example/session/default".parse()?,
    provider_routes: ClientProviderRoutes::from([
        (TransportId::Quic, ClientProviderRoute::native_tls("runtime.example", trusted_certificate_der.clone())),
        (TransportId::Tcp, ClientProviderRoute::native_tls("runtime.example", trusted_certificate_der)),
    ]),
    transport_policy: TransportPolicy::Auto,
    session: NnrpClientConfig::default(),
};

let client = NnrpClient::connect(
    options,
    [Arc::new(QuicProvider::default()), Arc::new(TcpProvider::default())],
).await?;

NnrpClient::connect resolves and validates every installed route, probes every eligible Auto/Prefer candidate, and adopts exactly one selected carrier into the returned runtime client. Force policies never fall back. Candidate diagnostics remain available from client.transport_selection().

The provider collection is explicit in Rust because Cargo dependencies cannot register themselves at runtime. Every official provider implements the shared client-provider trait; route keys and provider transport IDs must match.

NnrpClientOptions

FieldTypeRequiredDescription
endpointNnrpEndpointYesApplication-facing nnrp:// or nnrps:// endpoint.
provider_routesClientProviderRoutesNoPer-carrier locator and peer-security configuration.
transport_policyTransportPolicyNoAuto, preference, or force policy.
sessionNnrpClientConfigNoTransport-neutral session defaults.

ClientProviderRoutes is a BTreeMap<TransportId, ClientProviderRoute>. ClientProviderRoute has exactly provider_endpoint: Option<ProviderEndpoint> and security: Option<ClientTransportSecurity>. It is not valid to put one provider endpoint or one security object on NnrpClientOptions itself.

ClientTransportSecurity has exactly server_name: String and trusted_certificate_der: Vec<u8>. Both values must be non-empty and the certificate bytes are owned by the security value. Supplying it enables TCP TLS and is required for QUIC and native WSS routes.

A route for a transport whose provider is not present remains a local-unavailable candidate. When several checks fail, the protocol rejection registry order applies, so route-unresolved precedes security-unsatisfied.

Low-Level NnrpClient::connect_tcp

ParameterTypeRequiredValues / RangeDescription
addrimpl tokio::net::ToSocketAddrsYesSocket addressTarget TCP endpoint.
configNnrpClientConfigYesTransport-neutralClient runtime configuration.
ReturnsErrors
Result<NnrpClient, RuntimeError>DNS, connect, transport, or configuration errors.
rust
let config = NnrpClientConfig::default();
let client = NnrpClient::connect_tcp("127.0.0.1:4433", config).await?;

This method is the singular TCP provider surface. It does not implement route selection and is intended for provider tests, diagnostics, and controlled single-carrier deployments.

Provider Connect

Use these singular provider calls for provider tests, diagnostics, or controlled single-carrier deployments. Production provider selection starts from NnrpClient::connect.

ProviderPackageTypical methodDescription
TcpProvidernnrp-transport-tcpconnect(addr, config)TCP framed transport.
QuicProvidernnrp-transport-quicconnect(endpoint, endpoint_config, config)QUIC framed transport.
IpcProvidernnrp-transport-ipcconnect(endpoint, config)Unix socket or Windows named pipe.
WebSocketProvidernnrp-transport-websocketconnect(endpoint, config)Native WebSocket binary transport.
rust
let config = NnrpClientConfig::default();
let client = IpcProvider::connect("unix:///tmp/nnrp.sock".parse()?, config).await?;

NnrpClient::from_transport

ParameterTypeRequiredValues / RangeDescription
transportT: FramedTransport + 'staticYesAny framed transportCustom or provider-created transport.
configNnrpClientConfigYesTransport-neutralRuntime configuration.
ReturnsErrors
Result<NnrpClient, RuntimeError>Transport-kind mismatch or invalid configuration.

NnrpClient::open_session

ParameterTypeRequiredValues / RangeDescription
None---Uses the connected client configuration.
ReturnsErrors
Result<NnrpClientSession, RuntimeError>Session-open rejection or transport errors.
rust
let mut session = client.open_session().await?;

NnrpClientSession::submit

ParameterTypeRequiredValues / RangeDescription
requestNnrpSubmitRequestYesValid typed submit requestIdentity, header context, encoded metadata, and owned body.
ReturnsErrors
Result<u32, RuntimeError>Serialization, flow-control, lifecycle, or transport errors.
rust
let frame_id = session
    .submit(request)
    .await?;

NnrpClientSession::submit_nowait

ParameterTypeRequiredValues / RangeDescription
requestNnrpSubmitRequestYesValid typed submit requestIdentity, header context, encoded metadata, and owned body.
ReturnsErrors
Result<u32, RuntimeError>Returns after the frame is written; result is received later through events.

NnrpClientSession::submit_encoded

This advanced method accepts already encoded submit metadata and allocates the next frame id. Normal applications should prefer submit with a profile-built NnrpSubmitRequest.

ParameterTypeRequiredValues / RangeDescription
metadataFrameSubmitMetadataYesValid submit metadataOperation metadata.
bodyVec<u8>YesMay be emptySerialized request body.
ReturnsErrors
Result<u32, RuntimeError>Returns the allocated frame id after the frame is written.

submit_encoded_nowait is the same encoded boundary with explicit fire-and-poll naming.

NnrpClientSession::submit_encoded_with_frame_id

Use this method when an embedding or coarse FFI boundary already owns the frame identifier. It performs the same validation and carrier write as submit_nowait; it does not bypass the session runtime.

ParameterTypeRequiredValues / RangeDescription
frame_idu32YesNon-zero and not below the next allocatable idFrame identifier written into the NNRP common header. The first explicit id may skip ahead.
metadataFrameSubmitMetadataYesValid submit metadataOperation metadata.
bodyVec<u8>YesMay be emptySerialized request body.
ReturnsErrors
Result<u32, RuntimeError>Returns the supplied id after the frame is written. Rejects zero, reuse, or backward movement and preserves the current allocator on failure.

A successful explicit submission advances the session allocator to frame_id + 1, so later submit calls cannot reuse the explicit id. This is the canonical path used by the coarse native FFI submit call; bindings must not construct or write the packet themselves.

NnrpClientSession::await_event

Use this method for Preview4 sessions. It returns the closed client role-event union, preserving normal wire events and headerless local operation lifecycle notifications as separate variants.

ParameterTypeRequiredValues / RangeDescription
None---Reads the next client role event.
ReturnsErrors
Result<NnrpClientRoleEvent, RuntimeError>Transport, parse, lifecycle, or unexpected-message errors.
rust
match session.await_event().await? {
    NnrpClientRoleEvent::Runtime(NnrpRuntimeEvent {
        metadata: NnrpRuntimeEventMetadata::PartialResult(metadata),
        tail: NnrpRuntimeEventTail::Body(body),
        ..
    }) => handle_partial(metadata, body),
    NnrpClientRoleEvent::Runtime(NnrpRuntimeEvent {
        metadata: NnrpRuntimeEventMetadata::Progress(metadata),
        tail: NnrpRuntimeEventTail::Body(body),
        ..
    }) => update_progress(metadata, body),
    NnrpClientRoleEvent::Runtime(NnrpRuntimeEvent {
        metadata: NnrpRuntimeEventMetadata::ResultDropReason(metadata),
        tail: NnrpRuntimeEventTail::Diagnostic(body),
        ..
    }) => record_drop(metadata, body),
    NnrpClientRoleEvent::Lifecycle(event) => record_lifecycle(event),
    _ => {}
}

NnrpClientSession::await_result

ParameterTypeRequiredValues / RangeDescription
None---Reads the next event and requires it to be a terminal result.
ReturnsErrors
Result<NnrpResult, RuntimeError>Returns Success, Cancelled, Dropped, or Error without flattening the terminal event. Use await_event when non-terminal events are valid.

Runtime Control Methods

MethodParametersReturnsDescription
cancel_operationoperation_id, reason_codeResult<(), RuntimeError>Requests operation cancellation.
abort_operationoperation_id, reason_codeResult<(), RuntimeError>Requests operation abort with stronger semantics.
update_prioritypriority metadataResult<(), RuntimeError>Updates runtime scheduling priority.
update_deadlinedeadline metadataResult<(), RuntimeError>Updates task deadline.
expire_atexpiration metadataResult<(), RuntimeError>Marks work as invalid after a timestamp.
send_flow_updateflow metadataResult<(), RuntimeError>Sends flow/backpressure state.
send_credit_updatecredit metadataResult<(), RuntimeError>Sends available credit.
send_control_requestmessage type, metadataResult<(), RuntimeError>Generic compact control frame.
send_control_request_with_diagnosticsmessage type, metadata, diagnosticsResult<(), RuntimeError>Generic control frame with trace/diagnostic body.

The wire definitions for these frames live in Runtime Control Profiles.

Session Lifecycle Methods

MethodParametersReturnsDescription
patch_sessionsession patch metadataResult<SessionPatchAckMetadata, RuntimeError>Applies session parameter updates.
migrate_transportmigration metadataResult<SessionMigrateAckMetadata, RuntimeError>Requests transport migration.
closenoneResult<(), RuntimeError>Graceful session close.
close_transportnoneResult<(), RuntimeError>Exceptional transport close.

NnrpClientConfig

FieldTypeDefaultDescription
requested_session_idu320Requested session id.
profile_idu16Standard token profileRequested profile.
schema_id / schema_versionu32Standard registry valuesSchema identity.
priority_classSessionPriorityClassBalancedScheduling priority.
default_deadline_msu32500Default operation deadline.
max_in_flight_operationsu164Local in-flight limit.
lease_ttl_hint_msu3230000Lease TTL hint.
allow_resumeboolfalseEnables recovery semantics.
cache_hintsVec<CacheObjectKind>EmptyCache object kinds expected by this client.

CachePolicyOptions

CachePolicyOptions is a local opt-in value and never performs an implicit lookup or emits a frame.

Rust fieldTypeDefault
enabledboolfalse
reuse_scopeOption<CacheReuseScope>None
expiration_hint_msu640
invalidation_reasonCachePolicyInvalidationReasonExplicit

CachePolicyInvalidationReason has Explicit, DependencyInvalidated, LeaseExpired, VersionMismatch, and SchemaMismatch. CachePolicyOptions::validate enforces the shared contract.

NnrpResult

FieldTypeDescription
operation_idu64Non-zero submitted operation identity.
terminal_stateResultTerminalStateSuccess, Cancelled, Dropped, or Error.
eventNnrpTerminalEventClosed Runtime(NnrpRuntimeEvent) | Lifecycle(OperationLifecycleEvent) terminal evidence.

Successful results preserve RESULT_PUSH in the Runtime variant. Non-success results preserve the wire event or exact local lifecycle event that established the state. The SDK never fabricates a wire header or successful result metadata.

OperationLifecycleEvent

FieldTypeDescription
operation_idu64Non-zero operation identity.
stateOperationStateExact local lifecycle state.

This is a local role notification, not a wire event. It never carries or fabricates a RuntimeFrameHeader. Terminal mapping is Completed -> Success, Cancelled -> Cancelled, Superseded -> Dropped, and Failed -> Error.

NNRP Documentation