pub struct Client { /* private fields */ }Expand description
The TigerBeetle client.
Implementations§
Source§impl Client
impl Client
Sourcepub fn new(cluster_id: u128, addresses: &str) -> Result<Client, InitStatus>
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
Sourcepub fn create_accounts(
&self,
events: &[Account],
) -> impl Future<Output = Result<Vec<CreateAccountsResult>, PacketStatus>>
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
Sourcepub fn create_transfers(
&self,
events: &[Transfer],
) -> impl Future<Output = Result<Vec<CreateTransfersResult>, PacketStatus>>
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
Sourcepub fn lookup_accounts(
&self,
events: &[u128],
) -> impl Future<Output = Result<Vec<Account>, PacketStatus>>
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
Sourcepub fn lookup_transfers(
&self,
events: &[u128],
) -> impl Future<Output = Result<Vec<Transfer>, PacketStatus>>
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
Sourcepub fn get_account_transfers(
&self,
event: AccountFilter,
) -> impl Future<Output = Result<Vec<Transfer>, PacketStatus>>
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
Sourcepub fn get_account_balances(
&self,
event: AccountFilter,
) -> impl Future<Output = Result<Vec<AccountBalance>, PacketStatus>>
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
Sourcepub fn query_accounts(
&self,
event: QueryFilter,
) -> impl Future<Output = Result<Vec<Account>, PacketStatus>>
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
Sourcepub fn query_transfers(
&self,
event: QueryFilter,
) -> impl Future<Output = Result<Vec<Transfer>, PacketStatus>>
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
Sourcepub fn close(self) -> impl Future<Output = ()>
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.