Skip to main content

OxiaClient

Struct OxiaClient 

Source
pub struct OxiaClient { /* private fields */ }
Expand description

The Oxia client.

Cheap to clone (all clones share one set of connections, batchers and sessions) and safe to share across tasks. Obtain one with OxiaClient::connect or OxiaClient::builder; every data operation returns a request builder that is executed by .awaiting it.

Dropping the last clone tears down all background work abruptly; call close for a graceful shutdown that flushes pending batches and closes sessions.

§Cancellation

Dropping an operation’s future stops waiting but does not recall the operation: once submitted to a batch it may still execute on the server. Use conditional operations (e.g. expected_version_id) when you need certainty about what was applied.

Implementations§

Source§

impl OxiaClient

Source

pub fn builder() -> OxiaClientBuilder

Returns a builder for configuring and creating a client.

Source

pub async fn connect( service_address: impl Into<String>, ) -> Result<OxiaClient, OxiaError>

Connects to the given service address (host:port) with default options.

Use OxiaClient::builder to customize the namespace, timeouts, or batching before connecting.

§Errors

Fails fast — within the request timeout — when the cluster is unreachable (OxiaError::Disconnected / OxiaError::Timeout), or with OxiaError::Grpc when the namespace does not exist (NotFound) or the credentials are rejected (Unauthenticated).

§Example
let client = oxia::OxiaClient::connect("localhost:6648").await?;
Source

pub fn put(&self, key: impl Into<String>, value: impl Into<Bytes>) -> PutBuilder

Stores value under key, creating or overwriting the record.

Returns a PutBuilder; chain options (ephemeral, expected_version_id, partition_key, sequence_key_deltas, secondary_index, …) and .await it. The value is Bytes-backed and is not copied on its way to the wire.

§Errors

Awaiting the builder returns:

§Example
let res = client.put("config/mode", "primary").await?;
// Compare-and-swap on the returned version id:
client
    .put("config/mode", "standby")
    .expected_version_id(res.version.version_id)
    .await?;
Source

pub fn get(&self, key: impl Into<String>) -> GetBuilder

Reads the record associated with key.

Returns a GetBuilder; chain options (comparison, partition_key, include_value, use_index, …) and .await it. With a non-Equal comparison the returned record’s key is the found key, which may differ from the requested one. Records written with a partition key must be read with the same partition key.

An exact-match get is routed to the single shard that owns the key (or the partition key, when given); an inequality comparison or a secondary-index lookup instead fans out across all shards.

§Errors

Awaiting the builder returns:

§Example
use oxia::ComparisonType;

let exact = client.get("config/mode").await?;
let floor = client
    .get("config/zz")
    .comparison(ComparisonType::Floor)
    .await?;
Source

pub fn delete(&self, key: impl Into<String>) -> DeleteBuilder

Deletes the record associated with key.

Returns a DeleteBuilder; optionally chain expected_version_id for a conditional delete or partition_key for records written with one, and .await it.

§Errors

Awaiting the builder returns:

§Example
client.delete("config/mode").await?;
Source

pub fn delete_range( &self, min_key_inclusive: impl Into<String>, max_key_exclusive: impl Into<String>, ) -> DeleteRangeBuilder

Deletes every record with min_key_inclusive <= key < max_key_exclusive (in Oxia’s slash-aware key order).

Without a partition_key the deletion is applied on every shard; it is not atomic across shards.

§Errors

Awaiting the builder returns OxiaError::Timeout, OxiaError::Closed, or transient routing/transport errors. Deleting an empty range is not an error.

§Example
// Everything under the "config/" prefix:
client.delete_range("config/", "config/~").await?;
Source

pub fn list( &self, min_key_inclusive: impl Into<String>, max_key_exclusive: impl Into<String>, ) -> ListBuilder

Lists the keys with min_key_inclusive <= key < max_key_exclusive (in Oxia’s slash-aware key order).

.await the builder for all keys at once (bounded by the request timeout), or call stream() for an incremental ListStream with no overall deadline. Both deliver keys in the server’s global key order, merged across shards.

§Errors

Awaiting the builder returns OxiaError::Timeout when collecting all keys exceeds the request timeout, OxiaError::Closed after close, or transient routing/transport errors. An empty range yields an empty Vec, not an error.

§Example
let keys = client.list("config/", "config/~").await?;
Source

pub fn range_scan( &self, min_key_inclusive: impl Into<String>, max_key_exclusive: impl Into<String>, ) -> RangeScanBuilder

Reads every record with min_key_inclusive <= key < max_key_exclusive (in Oxia’s slash-aware key order).

.await the builder for all records at once (bounded by the request timeout), or call stream() for an incremental RangeScanStream that holds at most one buffered record per shard — prefer it for large ranges. Both deliver records in the server’s global key order, merged across shards.

§Errors

Awaiting the builder returns OxiaError::Timeout when collecting all records exceeds the request timeout, OxiaError::Closed after close, or transient routing/transport errors. An empty range yields an empty Vec, not an error.

§Example
use futures::TryStreamExt;

let mut scan = client.range_scan("logs/", "logs/~").stream().await?;
while let Some(record) = scan.try_next().await? {
    println!("{} => {:?}", record.key, record.value);
}
Source

pub fn notifications(&self) -> NotificationsBuilder

Subscribes to all changes applied to the database, streamed as Notifications.

Awaiting the builder yields a Notifications handle. Per-shard subscriptions are established in the background and re-established automatically after connection loss, resuming from the last delivered offset so no notification in between is lost. Events from the same shard arrive in order; interleaving across shards is unspecified. Changes made before the subscription is fully established may not be delivered.

Dropping the handle ends the subscription. When the channel buffer (buffer_size) is full, delivery applies backpressure to the per-shard listeners.

§Errors

Awaiting the builder returns OxiaError::Closed after close.

§Example
let mut notifications = client.notifications().await?;
while let Some(event) = notifications.recv().await {
    println!("{event}");
}
Source

pub fn sequence_updates( &self, key: impl Into<String>, partition_key: impl Into<String>, ) -> SequenceUpdatesBuilder

Subscribes to updates of the sequence rooted at key, delivering the highest assigned sequence key as it advances. partition_key must be the partition key the sequential records are written with (see PutBuilder::sequence_key_deltas).

Awaiting the builder yields a SequenceUpdates handle. Consecutive advances may be coalesced: each delivery carries the highest sequence key at that moment. The subscription reconnects automatically after connection loss; dropping the handle ends it.

§Errors

Awaiting the builder returns OxiaError::Closed after close.

§Example
let mut updates = client.sequence_updates("seq/events", "pk-0").await?;
client
    .put("seq/events", "data")
    .partition_key("pk-0")
    .sequence_key_deltas([1])
    .await?;
let highest = updates.recv().await;
Source

pub async fn close(&self) -> Result<(), OxiaError>

Closes the client gracefully: pending batches are flushed, subscriptions stop, sessions are closed server-side (immediately removing this client’s ephemeral records), and connections are released.

Idempotent: subsequent calls (from any clone) return Ok(()). Operations submitted after close fail with OxiaError::Closed. Merely dropping every clone instead tears the client down abruptly: queued operations are not flushed and ephemeral records linger until their session times out.

§Errors

Returns the first error encountered while shutting down (shutdown still proceeds through every component). Only the first call can return an error.

§Example
client.close().await?;

Trait Implementations§

Source§

impl Clone for OxiaClient

Source§

fn clone(&self) -> OxiaClient

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for OxiaClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more