Skip to content

Rust — Server API

The server API binds a transport, accepts sessions, receives submits and control messages, and emits results, progress, flow-control feedback, object/cache events, and close acknowledgements.

Workflow

  1. Build NnrpServerOptions with one application endpoint and a provider route set.
  2. Register the transport providers compiled into this deployment.
  3. Listen with NnrpServer::listen; Auto/Prefer opens every eligible route atomically.
  4. Accept a session with NnrpServer::accept.
  5. Receive work with receive_submit or dispatch await_event.
  6. Send output through the returned NnrpServerOperation.
  7. Receive runtime-control frames with receive_runtime_control.
  8. Close the session explicitly.

NnrpServer::listen

rust
let options = NnrpServerOptions {
    endpoint: "nnrp://localhost/runtime/default".parse()?,
    provider_routes: ServerProviderRoutes::from([
        (
            TransportId::Ipc,
            ServerProviderRoute::at("unix:///run/nnrp/runtime.sock".parse()?),
        ),
    ]),
    transport_policy: TransportPolicy::PreferIpc,
    session: NnrpServerConfig::default(),
};

let server = NnrpServer::listen(
    options,
    [Arc::new(IpcProvider::default()), Arc::new(TcpProvider::default())],
).await?;

The returned NnrpServer is one logical server over an atomic listener set. Auto/Prefer opens every eligible installed route, Force opens only the named route, and any required bind failure closes every listener opened by that call. accept waits across the set and each accepted session adopts exactly one carrier connection.

NnrpServerOptions

FieldTypeRequiredDescription
endpointNnrpEndpointYesApplication-facing nnrp:// or nnrps:// endpoint.
provider_routesServerProviderRoutesNoPer-carrier bind locator and server-security configuration.
transport_policyTransportPolicyNoListener-set eligibility policy.
sessionNnrpServerConfigNoTransport-neutral accepted-session defaults.

ServerProviderRoutes is a BTreeMap<TransportId, ServerProviderRoute>. ServerProviderRoute has exactly provider_endpoint: Option<ProviderEndpoint> and security: Option<ServerTransportSecurity>. A singular provider endpoint or role-wide security object is not part of NnrpServerOptions.

ServerTransportSecurity has exactly certificate_der: Vec<u8> and private_key_pkcs8_der: Vec<u8>. Both owned byte vectors must be non-empty. Supplying it enables TCP TLS and is required for QUIC and native WSS routes.

A route for a transport whose provider is absent remains visible as local-unavailable. A missing required locator for an installed, otherwise eligible provider is a listen configuration error and triggers atomic rollback.

Low-Level NnrpServer::bind_tcp

ParameterTypeRequiredValues / RangeDescription
addrimpl tokio::net::ToSocketAddrsYesSocket addressLocal TCP bind address.
configNnrpServerConfigYesTransport-neutralServer runtime configuration.
ReturnsErrors
Result<NnrpServer, RuntimeError>Bind, listener, transport, or configuration errors.
rust
let config = NnrpServerConfig::default();
let server = NnrpServer::bind_tcp("127.0.0.1:4433", config).await?;

This method creates a one-listener logical set for provider tests, diagnostics, and controlled single-carrier deployments. Production multi-provider hosts use listen.

Provider Bind

ProviderPackageTypical methodDescription
TcpProvidernnrp-transport-tcpbind(addr, config)TCP listener.
QuicProvidernnrp-transport-quicbind(endpoint_config, config)QUIC listener with certificate and ALPN config.
IpcProvidernnrp-transport-ipcbind(endpoint, config)Unix socket or Windows named pipe listener.
WebSocketProvidernnrp-transport-websocketbind(endpoint, config)Native WebSocket listener for binary frames.

NnrpServer::from_listener

ParameterTypeRequiredValues / RangeDescription
listenerL: FramedListener + 'staticYesAny framed listenerCustom or provider-created listener.
configNnrpServerConfigYesTransport-neutralRuntime configuration.
ReturnsErrors
Result<NnrpServer, RuntimeError>Listener-kind mismatch or invalid configuration.

NnrpServer::accept

ParameterTypeRequiredValues / RangeDescription
None---Accepts one peer and opens one runtime session.
ReturnsErrors
Result<NnrpServerSession, RuntimeError>Accept, session-open rejection, or transport errors.

Every accepted session exposes active_transport_id() -> TransportId. The value identifies the listener that accepted the carrier and must match the negotiated active_transport_id; it is never inferred from listener preference order.

bound_provider_endpoints() -> &BTreeMap<TransportId, ProviderEndpoint> returns the actual endpoint of every listener in the logical set, including operating-system-assigned ports. A terminal provider-listener failure fails the logical server and closes the remaining set; peer handshake rejection does not.

NnrpServerSession::await_event

rust
pub async fn await_event(&mut self) -> Result<NnrpServerEvent, RuntimeError>

Returns the next submit, control, runtime-object, cache, recovery, or close event in wire order. This is the application-facing server receive API. Native FFI bindings may poll bounded event batches internally, but they must project those batches back into this ordered single-event contract.

NnrpServerSession::receive_submit

ParameterTypeRequiredValues / RangeDescription
None---Reads the next submit frame.
ReturnsErrors
Result<NnrpServerOperation, RuntimeError>Transport, parse, lifecycle, or unexpected-message errors.
rust
let operation = session.receive_submit().await?;

receive_submit is a narrow convenience for hosts that only admit submit traffic at that point in their state machine. Hosts that permit interleaved control, object, cache, and close frames use await_event and dispatch the returned NnrpServerEvent.

NnrpServerOperation Replies

ParameterTypeRequiredValues / RangeDescription
metadataResultPushMetadataYesValid result metadataResult status and timing metadata.
bodyVec<u8>YesMay be emptySerialized result body.
ReturnsErrors
Result<(), RuntimeError>Lifecycle, serialization, or transport errors.
rust
operation
    .send_result(&mut session, ResultPushMetadata::default(), output)
    .await?;
MethodParametersReturnsDescription
send_resultsession, metadata, bodyResult<(), RuntimeError>Sends the operation's sole terminal result.
send_result_dropsession, metadata, diagnosticResult<(), RuntimeError>Sends the operation's terminal drop reason.
send_progresssession, metadata, bodyResult<(), RuntimeError>Sends non-terminal progress for this operation.
send_partial_resultsession, metadata, bodyResult<(), RuntimeError>Sends incremental result bytes for this operation.

The operation validates session ownership and operation_id before writing. It cannot be cloned, and exactly one terminal method may succeed. Operation-scoped reply methods are not exposed on NnrpServerSession.

Receiving a terminal lifecycle event does not invalidate the owned operation before its terminal reply succeeds. The operation remains reply-capable until that reply or session shutdown; polling another event cannot change this lifetime.

Runtime Control Methods

MethodParametersReturnsDescription
receive_cancelnoneResult<CancelMetadata, RuntimeError>Receives cancellation.
receive_runtime_controlnoneResult<NnrpRuntimeControl, RuntimeError>Receives generic Preview4 control frames with metadata and body.
send_backpressuremetadataResult<(), RuntimeError>Tells the client to slow down.
receive_pressure_updatenoneResult<PressureUpdateMetadata, RuntimeError>Receives client-side pressure state.
send_capabilitymetadataResult<(), RuntimeError>Sends supported cost/preference/limit information.
send_route_hintmetadataResult<(), RuntimeError>Sends execution or routing hints.

Object And Cache Methods

MethodParametersReturnsDescription
send_object_declaremetadata, bodyResult<(), RuntimeError>Declares a runtime object.
send_object_refmetadata, bodyResult<(), RuntimeError>References an existing object.
send_object_releasemetadata, bodyResult<(), RuntimeError>Releases an object reference.
send_object_deltametadata, bodyResult<(), RuntimeError>Sends object delta bytes.
send_cache_referencemetadata, bodyResult<(), RuntimeError>Sends a cache hit/reference.
send_cache_missmetadata, bodyResult<(), RuntimeError>Reports a miss.
send_cache_invalidatemetadata, bodyResult<(), RuntimeError>Invalidates a cache entry.

Lifecycle Methods

MethodParametersReturnsDescription
receive_closenoneResult<SessionCloseMetadata, RuntimeError>Waits for client close.
ack_closeclose metadataResult<(), RuntimeError>Acknowledges close.
closenoneResult<(), RuntimeError>Closes the server session.

NnrpServerConfig

FieldTypeDefaultDescription
supported_profilesVec<u16>Standard token profileAccepted profiles.
supported_cache_objectsVec<CacheObjectKind>EmptyAccepted cache object kinds.
schema_registrySchemaRegistryStandard registryAccepted schemas.
max_in_flight_operationsu164In-flight operation limit.
granted_operation_creditu162Initial operation credit.
lease_ttl_msu3230000Lease TTL.
resume_window_msu32120000Resume window.
application_policyArc<dyn NnrpServerPolicy>Allow-allApplication validation policy.

NnrpServerOperation

FieldTypeDescription
frame_idu32Submitted frame id.
operation_idu64Non-zero operation identity from submit metadata.
submitNnrpRuntimeEventComplete owned FRAME_SUBMIT event, including metadata and body.

WARNING

receive_submit is intentionally selective. If submit, control, object, cache, lifecycle, and close events can interleave, use await_event; receive_submit retains skipped events in the same session queue and never discards them.

NNRP Documentation