Client

Struct Client 

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

The TigerBeetle client.

Implementations§

Source§

impl Client

Source

pub fn new(cluster_id: u128, addresses: &str) -> Result<Client, InitStatus>

Create a new TigerBeetle client.

§Addresses

The addresses argument is a comma-separated string of addresses, where each may be either an IP4 address, a port number, or the pair of IP4 address and port number separated by a colon. Examples include 127.0.0.1, 3001, 127.0.0.1:3001 and 127.0.0.1,3002,127.0.0.1:3003. The default IP address is 127.0.0.1 and default port is 3001.

This is the same address format supported by the TigerBeetle CLI.

§References

Client Sessions.

Source

pub fn create_accounts( &self, events: &[Account], ) -> impl Future<Output = Result<Vec<CreateAccountsResult>, PacketStatus>>

Create one or more accounts.

Accounts to create are provided as a slice of input Account events. Their fields must be initialized as described in the corresponding protocol reference.

The request is queued for submission prior to return of this function; dropping the returned Future will not cancel the request.

§Interpreting the return value

This function has two levels of errors: if the entire request fails then the future returns Err of PacketStatus and the caller should assume that none of the submitted events were processed.

The results of events are represented individually. There are two related event result types: CreateAccountResult is the enum of possible outcomes, while CreateAccountsResult includes the index to map back to input events.

This function does not return a result for all input events. Instead it only returns results that would not be CreateAccountResult::Ok. In other words, this function does not return results for successful events, only unsuccessful events (though note the case of CreateAccountResult::Exists, described below). This behavior reflects optimizations in the underlying protocol. This client will never return a CreateAccountResult::Ok; that variant is defined in case it is useful for clients to materialize omitted request results. To relate a CreateAccountsResult to its input event, the CreateAccountsResult::index field is an index into the input event slice. An example of efficiently materializing all results is included below.

Note that a result of CreateAccountResult::Exists should often be treated the same as CreateAccountResult::Ok. This result can happen in cases of application crashes or other scenarios where requests have been replayed.

§Example
use tigerbeetle as tb;

async fn make_create_accounts_request(
    client: &tb::Client,
    accounts: &[tb::Account],
) -> Result<(), Box<dyn std::error::Error>> {
    let create_accounts_results = client.create_accounts(accounts).await?;
    let create_accounts_results_merged = merge_create_accounts_results(accounts, create_accounts_results);
    for (account, create_account_result) in create_accounts_results_merged {
        match create_account_result {
            tb::CreateAccountResult::Ok | tb::CreateAccountResult::Exists => {
                handle_create_account_success(account, create_account_result).await?;
            }
            _ => {
                handle_create_account_failure(account, create_account_result).await?;
            }
        }
    }
    Ok(())
}

fn merge_create_accounts_results(
    accounts: &[tb::Account],
    results: Vec<tb::CreateAccountsResult>,
) -> impl Iterator<Item = (&tb::Account, tb::CreateAccountResult)> + '_ {
    let mut results = results.into_iter().peekable();
    accounts.iter().enumerate().map(move |(i, account)| {
        match results.peek().copied() {
            Some(result) if result.index == i => {
                let _ = results.next();
                (account, result.result)
            }
            _ => (account, tb::CreateAccountResult::Ok),
        }
    })
}
§Maximum batch size

If the length of the events argument exceeds the maximum batch size the future will return Err of PacketStatus::TooMuchData. In TigerBeetle’s standard build-time configuration the maximum batch size is 8189.

§Protocol reference

create_accounts.

Source

pub fn create_transfers( &self, events: &[Transfer], ) -> impl Future<Output = Result<Vec<CreateTransfersResult>, PacketStatus>>

Create one or more transfers.

Transfers to create are provided as a slice of input Transfer events. Their fields must be initialized as described in the corresponding protocol reference.

The request is queued for submission prior to return of this function; dropping the returned Future will not cancel the request.

§Interpreting the return value

This function has two levels of errors: if the entire request fails then the future returns Err of PacketStatus and the caller should assume that none of the submitted events were processed.

The results of events are represented individually. There are two related event result types: CreateTransferResult is the enum of possible outcomes, while CreateTransfersResult includes the index to map back to input events.

This function does not return a result for all input events. Instead it only returns results that would not be CreateTransferResult::Ok. In other words, this function does not return results for successful events, only unsuccessful events (though note the case of CreateTransferResult::Exists, described below). This behavior reflects optimizations in the underlying protocol. This client will never return a CreateTransferResult::Ok; that variant is defined in case it is useful for clients to materialize omitted request results. To relate a CreateTransfersResult to its input event, the CreateTransfersResult::index field is an index into the input event slice. An example of efficiently materializing all results is included below.

To relate a CreateTransfersResult to its input event, the CreateTransfersResult::index field is an index into the input event slice.

Note that a result of CreateTransferResult::Exists should often be treated the same as CreateTransferResult::Ok. This result can happen in cases of application crashes or other scenarios where requests have been replayed.

§Example
use tigerbeetle as tb;

async fn make_create_transfers_request(
    client: &tb::Client,
    transfers: &[tb::Transfer],
) -> Result<(), Box<dyn std::error::Error>> {
    let create_transfers_results = client.create_transfers(transfers).await?;
    let create_transfers_results_merged = merge_create_transfers_results(transfers, create_transfers_results);
    for (transfer, create_transfer_result) in create_transfers_results_merged {
        match create_transfer_result {
            tb::CreateTransferResult::Ok | tb::CreateTransferResult::Exists => {
                handle_create_transfer_success(transfer, create_transfer_result).await?;
            }
            _ => {
                handle_create_transfer_failure(transfer, create_transfer_result).await?;
            }
        }
    }
    Ok(())
}

fn merge_create_transfers_results(
    transfers: &[tb::Transfer],
    results: Vec<tb::CreateTransfersResult>,
) -> impl Iterator<Item = (&tb::Transfer, tb::CreateTransferResult)> + '_ {
    let mut results = results.into_iter().peekable();
    transfers.iter().enumerate().map(move |(i, transfer)| {
        match results.peek().copied() {
            Some(result) if result.index == i => {
                let _ = results.next();
                (transfer, result.result)
            }
            _ => (transfer, tb::CreateTransferResult::Ok),
        }
    })
}
§Maximum batch size

If the length of the events argument exceeds the maximum batch size the future will return Err of PacketStatus::TooMuchData. In TigerBeetle’s standard build-time configuration the maximum batch size is 8189.

§Protocol reference

create_transfers.

Source

pub fn lookup_accounts( &self, events: &[u128], ) -> impl Future<Output = Result<Vec<Account>, PacketStatus>>

Query individual accounts.

The request is queued for submission prior to return of this function; dropping the returned future will not cancel the request.

§Interpreting the return value

This function has two levels of errors: if the entire request fails then the future returns Err of PacketStatus and the caller should assume that none of the submitted events were processed.

This request returns the found accounts, in the order requested. The return value does not indicate which accounts were not found. Those can be determined by comparing the output results to the input events, example provided below.

§Example
use tigerbeetle as tb;

async fn make_lookup_accounts_request(
    client: &tb::Client,
    accounts: &[u128],
) -> Result<(), Box<dyn std::error::Error>> {
    let lookup_accounts_results = client.lookup_accounts(accounts).await?;
    let lookup_accounts_results_merged = merge_lookup_accounts_results(accounts, lookup_accounts_results);
    for (account_id, maybe_account) in lookup_accounts_results_merged {
        match maybe_account {
            Some(account) => {
                handle_lookup_accounts_success(account).await?;
            }
            None => {
                handle_lookup_accounts_failure(account_id).await?;
            }
        }
    }
    Ok(())
}

fn merge_lookup_accounts_results(
    accounts: &[u128],
    results: Vec<tb::Account>,
) -> impl Iterator<Item = (u128, Option<tb::Account>)> + '_ {
    let mut results = results.into_iter().peekable();
    accounts.iter().map(move |&id| match results.peek() {
        Some(acc) if acc.id == id => (id, results.next()),
        _ => (id, None),
    })
}
§Maximum batch size

If the length of the events argument exceeds the maximum batch size the future will return Err of PacketStatus::TooMuchData. In TigerBeetle’s standard build-time configuration the maximum batch size is 8189.

§Errors

This request has two levels of errors: if the entire request fails then the future returns Err of PacketStatus and the caller can assume that none of the submitted events were processed; if the request was processed, then each event may possibly be NotFound.

§Protocol reference

lookup_accounts.

Source

pub fn lookup_transfers( &self, events: &[u128], ) -> impl Future<Output = Result<Vec<Transfer>, PacketStatus>>

Query individual transfers.

The request is queued for submission prior to return of this function; dropping the returned future will not cancel the request.

§Maximum batch size

If the length of the events argument exceeds the maximum batch size the future will return Err of PacketStatus::TooMuchData. In TigerBeetle’s standard build-time configuration the maximum batch size is 8189.

§Errors

This request has two levels of errors: if the entire request fails then the future returns Err of PacketStatus and the caller can assume that none of the submitted events were processed; if the request was processed, then each event may possibly be NotFound.

§Example
use tigerbeetle as tb;

async fn make_lookup_transfers_request(
    client: &tb::Client,
    transfers: &[u128],
) -> Result<(), Box<dyn std::error::Error>> {
    let lookup_transfers_results = client.lookup_transfers(transfers).await?;
    let lookup_transfers_results_merged = merge_lookup_transfers_results(transfers, lookup_transfers_results);
    for (transfer_id, maybe_transfer) in lookup_transfers_results_merged {
        match maybe_transfer {
            Some(transfer) => {
                handle_lookup_transfers_success(transfer).await?;
            }
            None => {
                handle_lookup_transfers_failure(transfer_id).await?;
            }
        }
    }
    Ok(())
}

fn merge_lookup_transfers_results(
    transfers: &[u128],
    results: Vec<tb::Transfer>,
) -> impl Iterator<Item = (u128, Option<tb::Transfer>)> + '_ {
    let mut results = results.into_iter().peekable();
    transfers.iter().map(move |&id| match results.peek() {
        Some(transfer) if transfer.id == id => (id, results.next()),
        _ => (id, None),
    })
}
§Protocol reference

lookup_transfers.

Source

pub fn get_account_transfers( &self, event: AccountFilter, ) -> impl Future<Output = Result<Vec<Transfer>, PacketStatus>>

Query multiple transfers for a single account.

The request is queued for submission prior to return of this function; dropping the returned future will not cancel the request.

§Errors

If the entire request fails then the future returns Err of PacketStatus.

§Protocol reference

get_account_transfers.

Source

pub fn get_account_balances( &self, event: AccountFilter, ) -> impl Future<Output = Result<Vec<AccountBalance>, PacketStatus>>

Query historical account balances for a single account.

The request is queued for submission prior to return of this function; dropping the returned future will not cancel the request.

§Errors

If the entire request fails then the future returns Err of PacketStatus.

§Protocol reference

get_account_balances.

Source

pub fn query_accounts( &self, event: QueryFilter, ) -> impl Future<Output = Result<Vec<Account>, PacketStatus>>

Query multiple accounts related by fields and timestamps.

The request is queued for submission prior to return of this function; dropping the returned future will not cancel the request.

§Errors

If the entire request fails then the future returns Err of PacketStatus.

§Protocol reference

query_accounts.

Source

pub fn query_transfers( &self, event: QueryFilter, ) -> impl Future<Output = Result<Vec<Transfer>, PacketStatus>>

Query multiple transfers related by fields and timestamps.

The request is queued for submission prior to return of this function; dropping the returned future will not cancel the request.

§Errors

If the entire request fails then the future returns Err of PacketStatus.

§Protocol reference

query_transfers.

Source

pub fn close(self) -> impl Future<Output = ()>

Close the client and asynchronously wait for completion.

Note that it is not required for correctness to call this method — Client’s destructor will correctly shut down the client, though without providing the ability to wait for shutdown.

Calling close will cancel any pending requests. This is only possible if the futures for those requests were dropped without awaiting them.

Trait Implementations§

Source§

impl Debug for Client

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Drop for Client

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Send for Client

Source§

impl Sync for Client

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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, 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.