Expand description
§FoundationDB Rust Client API
This is a wrapper library around the FoundationDB (Fdb) C API. It implements futures based interfaces over the Fdb future C implementations.
§Prerequisites
- Rust 1.85.1 or more,
- FoundationDB’s client installed.
§Platform Support
Support for different platforms (“targets”) are organized into three tiers, each with a different set of guarantees. For more information on the policies for targets at each tier, see the Target Tier Policy.
| Platform | Tier | Notes |
|---|---|---|
| linux x86_64 | 1 | |
| osx x86_64 | 2 | |
| osx Silicon | 2 | |
| Windows x86_64 | 3 | Windows build has been officially discontinue, now maintained by the community |
For more information on the policies for targets at each tier, see the
§Target Tier Policy
§Tier 1
Tier 1 targets can be thought of as “guaranteed to work”. This means that:
- we are actively checking correctness with the BindingTester,
- we are running classic Rust tests on each pull requests,
- you can use the crate on the platform.
§Tier 2
Tier 2 targets can be thought of as “guaranteed to build”. This means that:
- we are running classic Rust tests on each pull requests,
- you can use the crate on the platform.
But we are not checking correctness.
§Tier 3
Tier 3 targets are platforms we would like to have as Tier 2. You might be able to compile, but no CI has been set up.
§Getting Started
§Install FoundationDB
You first need to install FoundationDB. You can follow the official documentation:
§Add dependencies on foundationdb-rs
cargo add foundationdb -F embedded-fdb-include
cargo add futuresThis Rust crate is not tied to any Async Runtime.
§Exposed features
| Features | Notes |
|---|---|
fdb-5_1 | Support for FoundationDB 5.1.X |
fdb-5_2 | Support for FoundationDB 5.2.X |
fdb-6_0 | Support for FoundationDB 6.0.X |
fdb-6_1 | Support for FoundationDB 6.1.X |
fdb-6_2 | Support for FoundationDB 6.2.X |
fdb-6_3 | Support for FoundationDB 6.3.X |
fdb-7_0 | Support for FoundationDB 7.0.X |
fdb-7_1 | Support for FoundationDB 7.1.X |
fdb-7_3 | Support for FoundationDB 7.3.X |
fdb-7_4 | Support for FoundationDB 7.4.X |
embedded-fdb-include | Use the locally embedded FoundationDB fdb_c.h and fdb.options files to compile |
uuid | Support for the uuid crate for Tuples |
num-bigint | Support for the bigint crate for Tuples |
trace | Enable tracing on transaction related operations |
§Hello, World using the crate
We are going to use the Tokio runtime for this example:
use futures::prelude::*;
#[tokio::main]
async fn main() {
// Optional: creating a Database initializes the client automatically.
foundationdb::boot().expect("failed to initialize FoundationDB");
// Have fun with the FDB API
hello_world().await.expect("could not run the hello world");
// The network is stopped automatically at process exit.
}
async fn hello_world() -> foundationdb::FdbResult<()> {
let db = foundationdb::Database::default()?;
// write a value in a retryable closure
match db
.run(|trx, _maybe_committed| async move {
trx.set(b"hello", b"world");
Ok::<_, foundationdb::FdbBindingError>(())
})
.await
{
Ok(_) => println!("transaction committed"),
Err(_) => eprintln!("cannot commit transaction"),
};
// read a value
match db
.run(|trx, _maybe_committed| async move { Ok::<_, foundationdb::FdbBindingError>(trx.get(b"hello", false).await.unwrap()) })
.await
{
Ok(slice) => assert_eq!(b"world", slice.unwrap().as_ref()),
Err(_) => eprintln!("cannot commit transaction"),
}
Ok(())
}§Additional notes
§The class-scheduling tutorial
The official FoundationDB’s tutorial is called the Class Scheduling. You can find the Rust version in the examples.
§The blob tutorial
The official FoundationDB documentation provides also another topic which is further discussed inside a design recipe. A Rust implementation can be found here.
Another example, explores how to use subspaces to attach metadata to our blob.
§Must-read documentations
§Initialization
The Client is initialized on first use: creating a Database starts the network automatically, like fdb.open() does in the official bindings. You can also initialize it explicitly with the safe and idempotent foundationdb::boot function. The network then runs until process exit, where it is stopped and joined automatically. See foundationdb::api for more configuration options of the Fdb Client.
Warning: the automatic stop at process exit is meant for tests and short-lived tools. In a production application, prefer handling the network stop yourself: the network thread is the event loop driving every transaction, you may still have on-going operations at exit time, and you usually want a clean teardown. Finish or cancel your work, drop the Database handles, then call foundationdb::api::stop_network() (foundationdb::api::disable_stop_on_exit() additionally turns the exit hook into a no-op).
§Migration from 0.11 to 0.12
The initialization of the foundationdb API is now safe and idempotent, and the network can no longer be stopped by dropping the boot guard (issues #132, #195). Previously you had to write:
// old, up to 0.11
let network = unsafe { foundationdb::boot() };
// do stuff
drop(network);Now this can be converted to:
foundationdb::boot().expect("failed to initialize FoundationDB");
// do stuff; the network is stopped automatically at process exitCalling boot is even optional if you create a Database. Tests no longer need to be serialized with --test-threads=1: every test can boot in any order, in parallel.
§API stability
WARNING Until the 1.0 release of this library, the API may be in constant flux.
Re-exports§
pub use crate::metrics::AttemptMetrics;pub use crate::metrics::AttemptOutcome;pub use crate::metrics::ConflictKeys;pub use crate::metrics::MetricsReport;pub use crate::metrics::TransactionMetrics;pub use crate::budget::AttemptUsage;pub use crate::budget::BudgetExceeded;pub use crate::budget::BudgetKind;pub use crate::budget::ClientBudget;pub use crate::budget::UsageSnapshot;pub use crate::env::Clock;pub use crate::env::Environment;pub use crate::env::Rng;pub use crate::env::SeededRng;pub use crate::env::WallClock;pub use crate::runner::AttemptFailure;pub use crate::runner::MetricsHooks;pub use crate::runner::NativeRetryPolicy;pub use crate::runner::RetryPolicy;pub use crate::runner::RunnerHooks;pub use crate::runner::TransactionRunner;
Modules§
- Configuration of foundationDB API and Network
- Per-attempt usage accounting and the client-side budget.
- Directory provides a tool for managing related subspaces.
- Pluggable sources for the effects that must stay deterministic under FoundationDB simulation: time and randomness.
- Definitions of FDBKeys, used in api version 700 and more.
- Most functions in the FoundationDB API are asynchronous, meaning that they may return to the caller before actually delivering their Fdbresult.
- Definitions of MappedKeyValues, used in api version 710 and more.
- Per-attempt metrics collected by
Database::instrumented_run. - Generated configuration types for use with the various
set_optionfunctions - FoundationDB Recipes
- The retry runner behind
Database::run. - There is a key range called TimeKeeper in the system key space which stores a rolling history window of time to version mappings, with one data point every 10 seconds. It is not exposed via any user-facing API, though of course the data can be read by a user. It is not an official database feature and should not be relied on for anything where accuracy is critical as nothing prevents or detects system clock skew on the FDB process logging these data points.
Structs§
- A key range reported by one of the conflict-range special keyspaces.
- Represents a FoundationDB database
- The Standard Error type of FoundationDB
- A
KeySelectoridentifies a particular key in the database. - Wrapper around the boolean representing whether the previous transaction is still on fly This wrapper prevents the boolean to be copy and force it to be moved instead. This pretty handy when you don’t want to see the
Database::runclosure capturing the environment. RangeOptionrepresents a query parameters for range scan query.- A retryable transaction, generated by Database.run
- A set of options that controls the behavior of
Database::transact. - In FoundationDB, a transaction is a mutable snapshot of a database.
- A cancelled transaction
- A failed to commit transaction.
- A committed transaction.
Enums§
- This error represent all errors that can be throwed by
db.run. Layer developers may use theCustomError. - What the retry loop of
crate::Database::rundoes with a closure error.
Traits§
- What the retry loop of
crate::Database::runasks of a closure error. - A trait that must be implemented to use
Database::transactthis application error types.
Functions§
- Initialize the FoundationDB Client API and start the network thread.
- Returns the default Fdb cluster configuration file path
Type Aliases§
- The range type returned by
Transaction::conflicting_keys, an alias ofConflictRangewhich all three conflict-range readers share. - Alias for
Result<..., FdbError>