Add idiomatic documentation to Go, Java, Python, and Rust clients
This commit is contained in:
+139
-1
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user