TigerBeetlex.Client (tigerbeetlex v0.16.50)
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
end
Where 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.