TigerBeetlex.Client (tigerbeetlex v0.16.66)
View SourceMessage based API.
This module exposes a message based API to the TigerBeetle NIF client. The responses from the NIF arrive in the form of messages. This allows to integrate the client in an existing process architecture without spawning any other processes.
Response decoding
When submitting a request through a function in this module, the response is received via message.
All the functions performing a TigerBeetle request return a ref which can be used to match the received response message.
The response message can be received with this receive pattern:
{:ok, request_ref} = Client.create_accounts(client, accounts)
{:ok, results} =
receive do
{:tigerbeetlex_response, ^request_ref, response} ->
TigerBeetlex.Response.decode(response)
end
endWhere request_ref is the ref returned when the request was submitted. response can then be
decoded using TigerBeetlex.Response.decode/1.
The value returned from TigerBeetlex.Response.decode(response) will either be {:error, reason}
or {:ok, results}.
The type of results will depend on the operation that was submitted.
If the caller is a GenServer or similar process, it should pattern match for the response tuple
in its handle_info callback.
receive_and_decode/1
If the response is the only message you need to receive, you can call Client.receive_and_decode/1
as a shorthand for the receive block above.
{:ok, request_ref} = Client.create_accounts(client, accounts)
{:ok, results} = Client.receive_and_decode(request_ref)
Summary
Functions
Creates a batch of accounts.
Creates a batch of transfers.
Fetch a list of historical TigerBeetlex.AccountBalance for a given TigerBeetlex.Account.
Fetch a list of %TigerBeetlex.Transfer{} involving a %TigerBeetlex.Account{}.
Lookup a batch of accounts.
Lookup a batch of transfers.
Creates a message based TigerBeetlex client.
Query accounts by the intersection of some fields and by timestamp range.
Query transfers by the intersection of some fields and by timestamp range.
Utility function to receive a message response and decode it.
Types
@type t() :: %TigerBeetlex.Client{ref: reference()}
Functions
@spec create_accounts(client :: t(), accounts :: [TigerBeetlex.Account.t()]) :: {:ok, reference()} | {:error, TigerBeetlex.Types.request_error()}
Creates a batch of accounts.
client is a TigerBeetlex.Client struct.
accounts is a list of TigerBeetlex.Account structs.
The decoded results are a list of TigerBeetlex.CreateAccountsResult structs
which contain the index of the account list and the reason of the failure. An account has a
corresponding TigerBeetlex.CreateAccountsResult only if it fails to be created, otherwise
the account has been created succesfully (so a successful request returns an empty list).
See create_accounts.
Examples
alias TigerBeetlex.Account
alias TigerBeetlex.ID
# Successful request
accounts = [%Account{id: ID.generate(), ledger: 3, code: 4}]
{:ok, ref} = Client.create_accounts(client, accounts)
Client.receive_and_decode(ref)
#=> {:ok, []}
# Creation error
accounts = [%Account{id: ID.from_int(0), ledger: 3, code: 4}]
{:ok, ref} = Client.create_accounts(client, accounts)
Client.receive_and_decode(ref)
#=> {:ok, [%TigerBeetlex.CreateAccountsResult{index: 0, result: :id_must_not_be_zero}]}
@spec create_transfers(client :: t(), transfers :: [TigerBeetlex.Transfer.t()]) :: {:ok, reference()} | {:error, TigerBeetlex.Types.request_error()}
Creates a batch of transfers.
client is a TigerBeetlex.Client struct.
transfers is a list of TigerBeetlex.Transfer structs.
The decoded results are a list of TigerBeetlex.CreateTransfersResult structs
which contain the index of the transfer list and the reason of the failure. A transfer has a
corresponding TigerBeetlex.CreateTransfersResult only if it fails to be created, otherwise
the transfer has been created succesfully (so a successful request returns an empty list).
See create_transfers.
Examples
alias TigerBeetlex.ID
alias TigerBeetlex.Transfer
# Successful request
transfers = [
%Transfer{
id: ID.generate(),
debit_account_id: ID.from_int(42),
credit_account_id: ID.from_int(43),
ledger: 3,
code: 4
amount: 100
}
]
{:ok, ref} = Client.create_transfers(client, transfers)
Client.receive_and_decode(ref)
#=> {:ok, []}
# Creation error
transfers = [
%Transfer{
id: ID.from_int(0),
debit_account_id: ID.from_int(42),
credit_account_id: ID.from_int(43),
ledger: 3,
code: 4
amount: 100
}
]
{:ok, ref} = Client.create_transfers(client, transfers)
Client.receive_and_decode(ref)
#=> {:ok, [%TigerBeetlex.CreateTransfersResult{index: 0, result: :id_must_not_be_zero}]}
@spec get_account_balances( client :: t(), account_filter :: TigerBeetlex.AccountFilter.t() ) :: {:ok, reference()} | {:error, TigerBeetlex.Types.request_error()}
Fetch a list of historical TigerBeetlex.AccountBalance for a given TigerBeetlex.Account.
Only accounts created with the history flag set retain historical balances. This is off by default.
client is a TigerBeetlex.Client struct.
account_filter is a TigerBeetlex.AccountFilter struct. The limit field must be set.
The decoded results are a list of TigerBeetlex.AccountBalance structs that match account_filter.
See get_account_balances.
Examples
alias TigerBeetlex.AccountFilter
alias TigerBeetlex.ID
account_filter = %AccountFilter{id: ID.from_int(42), limit: 10}
{:ok, ref} = Client.get_account_balances(client, account_filter)
Client.receive_and_decode(ref)
#=> {:ok, [%TigerBeetlex.AccountBalance{}]}
@spec get_account_transfers( client :: t(), account_filter :: TigerBeetlex.AccountFilter.t() ) :: {:ok, reference()} | {:error, TigerBeetlex.Types.request_error()}
Fetch a list of %TigerBeetlex.Transfer{} involving a %TigerBeetlex.Account{}.
client is a TigerBeetlex.Client struct.
account_filter is a TigerBeetlex.AccountFilter struct. The limit field must be set.
The decoded results are a list of TigerBeetlex.Transfer structs that match account_filter.
Examples
alias TigerBeetlex.AccountFilter
alias TigerBeetlex.ID
account_filter = %AccountFilter{id: ID.from_int(42), limit: 10}
{:ok, ref} = Client.get_account_balances(client, account_filter)
Client.receive_and_decode(ref)
#=> {:ok, [%TigerBeetlex.Transfer{}]}
@spec lookup_accounts(client :: t(), ids :: [TigerBeetlex.Types.id_128()]) :: {:ok, reference()} | {:error, TigerBeetlex.Types.request_error()}
Lookup a batch of accounts.
client is a TigerBeetlex.Client struct.
ids is a list of 128-bit binaries.
The decoded results are a list of TigerBeetlex.Account structs.
See lookup_accounts.
Examples
alias TigerBeetlex.ID
ids = [ID.from_int(42)]
{:ok, ref} = Client.lookup_accounts(client, ids)
Client.receive_and_decode(ref)
#=> {:ok, [%TigerBeetlex.Account{}]}
@spec lookup_transfers(client :: t(), ids :: [TigerBeetlex.Types.id_128()]) :: {:ok, reference()} | {:error, TigerBeetlex.Types.request_error()}
Lookup a batch of transfers.
client is a TigerBeetlex.Client struct.
ids is a list of 128-bit binaries.
The decoded results are a list of TigerBeetlex.Transfer structs.
See lookup_transfers.
Examples
alias TigerBeetlex.ID
ids = [ID.from_int(42)]
{:ok, ref} = Client.lookup_transfers(client, ids)
Client.receive_and_decode(ref)
#=> {:ok, [%TigerBeetlex.Transfer{}]}
@spec new( cluster_id :: TigerBeetlex.Types.id_128(), addresses :: [binary()] ) :: {:ok, t()} | {:error, TigerBeetlex.Types.init_client_error()}
Creates a message based TigerBeetlex client.
The returned client can be safely shared between multiple processes. Each process will receive the responses to the requests it submits.
Arguments
cluster_id(128-bit binary ID): - The TigerBeetle cluster id.addresses(list ofString.t()) - The list of node addresses. These can either be a single digit (e.g."3000"), which is interpreted as a port on127.0.0.1, an IP address + port (e.g."127.0.0.1:3000"), or just an IP address (e.g."127.0.0.1"), which defaults to port3001.
Examples
alias TigerBeetlex.ID
{:ok, client} = Client.new(ID.from_int(0), ["3000"])
@spec query_accounts(client :: t(), query_filter :: TigerBeetlex.QueryFilter.t()) :: {:ok, reference()} | {:error, TigerBeetlex.Types.request_error()}
Query accounts by the intersection of some fields and by timestamp range.
client is a TigerBeetlex.Client struct.
query_filter is a TigerBeetlex.QueryFilter struct. The limit field must be set.
The decoded results are a list of TigerBeetlex.Account structs that match query_filter.
See query_accounts.
Examples
alias TigerBeetlex.QueryFilter
query_filter = %QueryFilter{ledger: 42, limit: 10}
{:ok, ref} = Client.query_accounts(client, query_filter)
Client.receive_and_decode(ref)
#=> {:ok, [%TigerBeetlex.Account{}]}
@spec query_transfers(client :: t(), query_filter :: TigerBeetlex.QueryFilter.t()) :: {:ok, reference()} | {:error, TigerBeetlex.Types.request_error()}
Query transfers by the intersection of some fields and by timestamp range.
client is a TigerBeetlex.Client struct.
query_filter is a TigerBeetlex.QueryFilter struct. The limit field must be set.
The decoded results are a list of TigerBeetlex.Transfer structs that match query_filter.
See query_transfers.
Examples
alias TigerBeetlex.QueryFilter
query_filter = %QueryFilter{ledger: 42, limit: 10}
{:ok, ref} = Client.query_transfers(client, ids)
Client.receive_and_decode(ref)
#=> {:ok, [%TigerBeetlex.Transfer{}]}
Utility function to receive a message response and decode it.
This is useful to emulate blocking behavior if TigerBeetlex is the only process that can send messages to your process.
Note that the function doesn't have a timeout and could block forever. This is expected since the TigerBeetle client never times out.
See all the other functions in this module for example usage.