Add idiomatic documentation to Go, Java, Python, and Rust clients

This commit is contained in:
Joseph Doherty
2026-04-30 12:04:46 -04:00
parent eed1e88a37
commit 8d3352f2c6
44 changed files with 1631 additions and 102 deletions
+139 -1
View File
@@ -1,3 +1,13 @@
//! Typed handle around an opened gateway session.
//!
//! [`Session`] wraps an `OpenSession` reply (just the session id) plus a
//! cloned [`GatewayClient`] and offers Rust-shaped methods for the
//! command surface that the worker exposes — `Register`, `AddItem`,
//! bulk subscribe variants, `Write`/`Write2`, and the event stream.
//!
//! Bulk commands enforce a 1000-item cap before contacting the worker, in
//! line with the gateway's documented `MAX_BULK_ITEMS`.
use crate::client::{EventStream, GatewayClient};
use crate::error::{ensure_protocol_success, Error};
use crate::generated::mxaccess_gateway::v1::mx_command::Payload;
@@ -13,7 +23,13 @@ use crate::value::MxValue;
const MAX_BULK_ITEMS: usize = 1_000;
/// Session identifier returned by the gateway.
/// Handle to an opened gateway session.
///
/// `Session` carries the gateway-issued session id and a cloned
/// [`GatewayClient`]. All methods are async and stateless on the client
/// side: the gateway tracks per-session worker state. Drop the handle and
/// call [`Session::close`] to release the worker; the gateway also reaps
/// orphaned sessions on its own schedule.
#[derive(Clone)]
pub struct Session {
id: String,
@@ -28,10 +44,18 @@ impl Session {
}
}
/// Borrow the gateway-assigned session id.
pub fn id(&self) -> &str {
&self.id
}
/// Convenience constructor that issues `OpenSession` with the supplied
/// client session name and returns the resulting [`Session`].
///
/// # Errors
///
/// Propagates errors from
/// [`GatewayClient::open_session`](crate::client::GatewayClient::open_session).
pub async fn open(client: GatewayClient, client_session_name: &str) -> Result<Self, Error> {
client
.open_session(OpenSessionRequest {
@@ -41,6 +65,12 @@ impl Session {
.await
}
/// Issue `CloseSession` against this session id.
///
/// # Errors
///
/// Returns [`Error::ProtocolStatus`] if the gateway returns a non-OK
/// envelope and any transport/status errors propagated by tonic.
pub async fn close(&self) -> Result<(), Error> {
let reply = self
.client
@@ -53,6 +83,12 @@ impl Session {
Ok(())
}
/// Run MXAccess `Register` and return the assigned `ServerHandle`.
///
/// # Errors
///
/// Returns [`Error::Command`] if the worker reports a non-OK status,
/// plus transport/status errors from tonic.
pub async fn register(&self, client_name: &str) -> Result<i32, Error> {
let reply = self
.invoke(
@@ -66,6 +102,13 @@ impl Session {
Ok(register_server_handle(&reply))
}
/// Run MXAccess `AddItem` against `server_handle` and return the
/// assigned `ItemHandle`.
///
/// # Errors
///
/// Returns [`Error::Command`] when MXAccess rejects the item
/// definition, plus transport/status errors from tonic.
pub async fn add_item(&self, server_handle: i32, item_definition: &str) -> Result<i32, Error> {
let reply = self
.invoke(
@@ -80,6 +123,12 @@ impl Session {
Ok(add_item_handle(&reply))
}
/// Run MXAccess `AddItem2` (item with a caller-supplied context string)
/// and return the assigned `ItemHandle`.
///
/// # Errors
///
/// Same conditions as [`Session::add_item`].
pub async fn add_item2(
&self,
server_handle: i32,
@@ -100,6 +149,12 @@ impl Session {
Ok(add_item2_handle(&reply))
}
/// Run MXAccess `RemoveItem` for the given handle pair.
///
/// # Errors
///
/// Returns [`Error::Command`] on a non-OK worker status, plus the
/// usual transport/status errors.
pub async fn remove_item(&self, server_handle: i32, item_handle: i32) -> Result<(), Error> {
self.invoke(
MxCommandKind::RemoveItem,
@@ -112,6 +167,12 @@ impl Session {
Ok(())
}
/// Run MXAccess `Advise` to start receiving change notifications for
/// the given item.
///
/// # Errors
///
/// Returns [`Error::Command`] when the worker reports a non-OK status.
pub async fn advise(&self, server_handle: i32, item_handle: i32) -> Result<(), Error> {
self.invoke(
MxCommandKind::Advise,
@@ -124,6 +185,12 @@ impl Session {
Ok(())
}
/// Run MXAccess `UnAdvise` to stop change notifications for the given
/// item.
///
/// # Errors
///
/// Returns [`Error::Command`] when the worker reports a non-OK status.
pub async fn un_advise(&self, server_handle: i32, item_handle: i32) -> Result<(), Error> {
self.invoke(
MxCommandKind::UnAdvise,
@@ -136,6 +203,13 @@ impl Session {
Ok(())
}
/// Bulk variant of [`Session::add_item`]. Each tag address yields one
/// `SubscribeResult` in the returned vector.
///
/// # Errors
///
/// Returns [`Error::InvalidArgument`] when the input exceeds the
/// gateway's 1000-item bulk cap, plus the usual command-level errors.
pub async fn add_item_bulk(
&self,
server_handle: i32,
@@ -155,6 +229,11 @@ impl Session {
Ok(bulk_results(reply, BulkReplyKind::AddItemBulk))
}
/// Bulk variant of [`Session::advise`].
///
/// # Errors
///
/// Same conditions as [`Session::add_item_bulk`].
pub async fn advise_item_bulk(
&self,
server_handle: i32,
@@ -174,6 +253,11 @@ impl Session {
Ok(bulk_results(reply, BulkReplyKind::AdviseItemBulk))
}
/// Bulk variant of [`Session::remove_item`].
///
/// # Errors
///
/// Same conditions as [`Session::add_item_bulk`].
pub async fn remove_item_bulk(
&self,
server_handle: i32,
@@ -193,6 +277,11 @@ impl Session {
Ok(bulk_results(reply, BulkReplyKind::RemoveItemBulk))
}
/// Bulk variant of [`Session::un_advise`].
///
/// # Errors
///
/// Same conditions as [`Session::add_item_bulk`].
pub async fn un_advise_item_bulk(
&self,
server_handle: i32,
@@ -212,6 +301,11 @@ impl Session {
Ok(bulk_results(reply, BulkReplyKind::UnAdviseItemBulk))
}
/// Bulk `Subscribe` (atomic add-and-advise) for a list of tag addresses.
///
/// # Errors
///
/// Same conditions as [`Session::add_item_bulk`].
pub async fn subscribe_bulk(
&self,
server_handle: i32,
@@ -231,6 +325,12 @@ impl Session {
Ok(bulk_results(reply, BulkReplyKind::SubscribeBulk))
}
/// Bulk `Unsubscribe` (atomic un-advise-and-remove) for a list of
/// item handles.
///
/// # Errors
///
/// Same conditions as [`Session::add_item_bulk`].
pub async fn unsubscribe_bulk(
&self,
server_handle: i32,
@@ -250,6 +350,12 @@ impl Session {
Ok(bulk_results(reply, BulkReplyKind::UnsubscribeBulk))
}
/// Run MXAccess `Write` (single-value, no caller-supplied timestamp).
///
/// # Errors
///
/// Returns [`Error::Command`] for non-OK worker statuses, plus the
/// usual transport/status errors.
pub async fn write(
&self,
server_handle: i32,
@@ -270,6 +376,11 @@ impl Session {
Ok(())
}
/// Run MXAccess `Write2` (single-value with caller-supplied timestamp).
///
/// # Errors
///
/// Same conditions as [`Session::write`].
pub async fn write2(
&self,
server_handle: i32,
@@ -292,10 +403,23 @@ impl Session {
Ok(())
}
/// Open the per-session event stream from the beginning.
///
/// # Errors
///
/// Returns the `tonic::Status` mapped through [`Error::from`] when the
/// gateway rejects the subscription.
pub async fn events(&self) -> Result<EventStream, Error> {
self.events_after(0).await
}
/// Open the per-session event stream, requesting only events whose
/// `worker_sequence` is greater than `after_worker_sequence`. Pass `0`
/// to receive every buffered event.
///
/// # Errors
///
/// Same conditions as [`Session::events`].
pub async fn events_after(&self, after_worker_sequence: u64) -> Result<EventStream, Error> {
self.client
.stream_events(StreamEventsRequest {
@@ -305,6 +429,13 @@ impl Session {
.await
}
/// Issue a raw `Invoke` for an arbitrary command, without filtering on
/// the protocol status. Useful when callers need the full reply for
/// commands not yet wrapped by `Session`.
///
/// # Errors
///
/// Returns the `tonic::Status` mapped through [`Error::from`].
pub async fn invoke_raw(
&self,
kind: MxCommandKind,
@@ -315,6 +446,13 @@ impl Session {
.await
}
/// Issue an `Invoke` for an arbitrary command and surface a non-OK
/// reply as [`Error::Command`].
///
/// # Errors
///
/// Returns [`Error::Command`] for non-OK worker statuses plus any
/// errors propagated by [`invoke_raw`](Self::invoke_raw).
pub async fn invoke(
&self,
kind: MxCommandKind,