Skip to content

antstorm/tigerbeetle-ruby

Repository files navigation

Ruby Client for TigerBeetle

Gem CI License

Are you looking to integrate Tigebeetle into your Ruby (or Rails) stack? You've come to the right place!

TigerBeetle is a high performance financial transaction database (i.e. Ledger) designed to power the next 30 years of Online Transaction Processing. And this is a feature complete Ruby client for it that leverages the native Zig client.

Usage

Start by adding the TigerBeetle gem to your Gemfile:

gem 'tigerbeeetle'

Ensure TigerBeetle is running (more on this):

$ curl -Lo tigerbeetle.zip https://linux.tigerbeetle.com && unzip tigerbeetle.zip && ./tigerbeetle version
$ ./tigerbeetle format --cluster=0 --replica=0 --replica-count=1 --development 0_0.tigerbeetle
$ ./tigerbeetle start --addresses=3000 --development 0_0.tigerbeetle

Connect your Ruby client and start using it:

client = TigerBeetle.connect # using default cluster_id (0) and address (127.0.0.1:3000)

# create accounts
client.create_accounts(
  TigerBeetle::Account.new(id: 100, ledger: 1, code: 1),
  TigerBeetle::Account.new(id: 101, ledger: 1, code: 1)
)

# move funds between accounts
client.create_transfers(
  TigerBeetle::Transfer.new(
    id: 100,
    debit_account_id: 100,
    credit_account_id: 101,
    amount: 999,
    ledger: 1,
    code: 10
  )
)

# check balances
account_1, account_2 = client.lookup_accounts(100, 101)
account_1.debits_posted # 999
account_2.credits_posted # 999

More information on the ledger and code attributes can be found here.

IDs

You can choose whatever IDs you want when creating accounts and transfers (as long as they are unique per cluster). However to leverage the maximum performance TigerBeetle recommends using strictly increasing decentralized 128-bit IDs. To generate such an ID you can use the provided TigerBeetle.id method.

client.create_accounts(
  TigerBeetle::Account.new(id: TigerBeetle.id, ledger: 1, code: 1)
)

More on how to approach this — https://docs.tigerbeetle.com/coding/data-modeling/#id.

Async

All the lower level calls executed by the client are non-blocking. However, since async calls are much less common in Ruby, these are made blocking by default. In order to use the client asynchronously all you need to do is provide your own callback to any method on the client:

# default blocking call
result = client.lookup_accounts(100)
result # [#<struct TigerBeetle::Account id=100, ... >]

# async non-blocking call
client.lookup_accounts(100) do |result|
  result # [#<struct TigerBeetle::Account id=100, ... >]
end

In the example above the first call will block until TigerBeetle responds and the return value of the call will contain the result. The second call however will return nil straight away (and keep executing your code) while calling the provided block only once TigerBeetle has responded, passing in the result as an argument to the block.

Contributing

We'd love your help building the TigerBeetle Ruby gem.

  • Join the official Slack for general questions on TigerBeetle
  • For any discovered problems or questions about the Ruby client — open a new issue
  • For codebase improvements:
    • Fork this repo
    • Implement your changes
    • Ensure the tests pass by running bundle exec rspec
    • Open a new pull request

License

This project is licensed under Apache 2.0 license.

About

A Ruby client for TigerBeetle

Resources

License

Stars

Watchers

Forks

Packages

No packages published