foundationdb

Struct Database

Source
pub struct Database { /* private fields */ }
Expand description

Represents a FoundationDB database

A mutable, lexicographically ordered mapping from binary keys to binary values.

Modifications to a database are performed via transactions.

Implementations§

Source§

impl Database

Source

pub fn new(path: Option<&str>) -> FdbResult<Database>

Create a database for the given configuration path if any, or the default one.

If the client was not initialized yet, the network is started with the default API version, like crate::boot would.

Source

pub unsafe fn new_from_pointer(ptr: NonNull<FDBDatabase>) -> Self

Create a new FDBDatabase from a raw pointer. Users are expected to use the new method.

§Safety

The caller must ensure that ptr is a valid pointer to an FDBDatabase object obtained from the FoundationDB C API, and that the pointer is not aliased or used after being passed to this function.

Source

pub fn from_path(path: &str) -> FdbResult<Database>

Create a database for the given configuration path

Source

pub fn default() -> FdbResult<Database>

Create a database for the default configuration path

Source§

impl Database

Source

pub fn get_client_status( &self, ) -> impl Future<Output = FdbResult<FdbSlice>> + Send + Sync + Unpin + use<>

Retrieve a client-side status information in a JSON format.

Source§

impl Database

Source

pub async fn new_compat(path: Option<&str>) -> FdbResult<Database>

Create a database for the given configuration path

This is a compatibility api. If you only use API version ≥ 610 you should use Database::new, Database::from_path or Database::default.

Source

pub fn set_option(&self, opt: DatabaseOption) -> FdbResult<()>

Called to set an option an on Database.

Source

pub fn create_trx(&self) -> FdbResult<Transaction>

Creates a new transaction on the given database.

Source

pub async fn transact<F>( &self, f: F, options: TransactOption, ) -> Result<F::Item, F::Error>

transact returns a future which retries on error. It tries to resolve a future created by caller-provided function f inside a retry loop, providing it with a newly created transaction. After caller-provided future resolves, the transaction will be committed automatically.

§Warning: Hanging on Network/DNS failures

By default, the FoundationDB C API will retry indefinitely if it cannot reach the cluster or if DNS resolution fails. This can cause transact to hang forever. To prevent this, you should set options::DatabaseOption::TransactionTimeout or options::DatabaseOption::TransactionRetryLimit on the Database object, or options::TransactionOption::Timeout or options::TransactionOption::RetryLimit on the transaction itself.

Note that TransactOption also provides retry_limit and time_out, but these are Rust-side budgets that are only checked between retries. If the C API hangs during a call like commit() or on_error(), these budgets will not be reached.

Once Generic Associated Types lands in stable rust, the returned future of f won’t need to be boxed anymore, also the lifetime limitations around f might be lowered.

Source

pub fn transact_boxed<'trx, F, D, T, E>( &'trx self, data: D, f: F, options: TransactOption, ) -> impl Future<Output = Result<T, E>> + Send + 'trx
where for<'a> F: FnMut(&'a Transaction, &'a mut D) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'a>> + Send + 'trx, E: TransactError + Send + 'trx, T: Send + 'trx, D: Send + 'trx,

transact_boxed is a version of Database::transact that accepts a closure returning a pinned, boxed future.

§Warning: Hanging on Network/DNS failures

By default, the FoundationDB C API will retry indefinitely if it cannot reach the cluster or if DNS resolution fails. This can cause transact_boxed to hang forever. To prevent this, you should set options::DatabaseOption::TransactionTimeout or options::DatabaseOption::TransactionRetryLimit on the Database object, or options::TransactionOption::Timeout or options::TransactionOption::RetryLimit on the transaction itself.

Note that TransactOption also provides retry_limit and time_out, but these are Rust-side budgets that are only checked between retries. If the C API hangs during a call like commit() or on_error(), these budgets will not be reached.

Source

pub fn transact_boxed_local<'trx, F, D, T, E>( &'trx self, data: D, f: F, options: TransactOption, ) -> impl Future<Output = Result<T, E>> + 'trx
where for<'a> F: FnMut(&'a Transaction, &'a mut D) -> Pin<Box<dyn Future<Output = Result<T, E>> + 'a>> + 'trx, E: TransactError + 'trx, T: 'trx, D: 'trx,

transact_boxed_local is a version of Database::transact that accepts a closure returning a pinned, boxed future that is not Send.

§Warning: Hanging on Network/DNS failures

By default, the FoundationDB C API will retry indefinitely if it cannot reach the cluster or if DNS resolution fails. This can cause transact_boxed_local to hang forever. To prevent this, you should set options::DatabaseOption::TransactionTimeout or options::DatabaseOption::TransactionRetryLimit on the Database object, or options::TransactionOption::Timeout or options::TransactionOption::RetryLimit on the transaction itself.

Note that TransactOption also provides retry_limit and time_out, but these are Rust-side budgets that are only checked between retries. If the C API hangs during a call like commit() or on_error(), these budgets will not be reached.

Source

pub async fn run<F, Fut, T, E>(&self, closure: F) -> Result<T, E>
where F: Fn(RetryableTransaction, MaybeCommitted) -> Fut, Fut: Future<Output = Result<T, E>>, E: RetryableError,

Runs a transactional function against this Database with retry logic. The associated closure will be called until a non-retryable FDBError is thrown or commit(), returns success.

Users are not expected to keep reference to the RetryableTransaction. If a weak or strong reference is kept by the user, the binding will throw an error.

§Warning: retry

It might retry indefinitely if the transaction is highly contentious. It is recommended to set options::TransactionOption::RetryLimit or options::TransactionOption::Timeout on the transaction if the task needs to be guaranteed to finish. These options can be safely set on every iteration of the closure.

§Warning: Hanging on Network/DNS failures

By default, the FoundationDB C API will retry indefinitely if it cannot reach the cluster or if DNS resolution fails. This can cause run to hang forever. To prevent this, you should set options::DatabaseOption::TransactionTimeout or options::DatabaseOption::TransactionRetryLimit on the Database object, or options::TransactionOption::Timeout or options::TransactionOption::RetryLimit on the transaction itself.

§Warning: Maybe committed transactions

As with other client/server databases, in some failure scenarios a client may be unable to determine whether a transaction succeeded. You should make sure your closure is idempotent.

The closure will notify the user in case of a maybe_committed transaction in a previous run with the MaybeCommitted provided in the closure.

This one can be used as boolean with

db.run(|trx, maybe_committed| async {
    if maybe_committed.into() {
        // Handle the problem if needed
    }
    Ok::<_, FdbBindingError>(())
}).await;
§Typed closure errors

The closure error type E is generic: any type implementing RetryableError works, and the caller gets it back typed. Errors are classified through RetryableError::retry_decision: by default any error that is, or wraps (through source()), an FdbError is handed to on_error, which judges retryability and applies backoff; RetryDecision::Retry is routed through on_error with code 1020 (not_committed), so backoff and options::TransactionOption::RetryLimit apply uniformly and MaybeCommitted is left untouched. When retries are exhausted or the error is not retryable, the original closure error is returned as-is.

A closure that never names an error type is ambiguous; pin it on the tail expression, for example Ok::<_, FdbBindingError>(value).

§Hooks and retry policy

This is runner() with its defaults: no hooks and the native retry policy. Use the builder to observe the run with RunnerHooks or to decide the retries with a RetryPolicy.

Source

pub fn runner(&self) -> TransactionRunner<'_>

A builder for a transactional run, to plug RunnerHooks and a RetryPolicy into it.

let metrics = TransactionMetrics::new();
db.runner()
    .hooks(&MetricsHooks::new(&metrics))
    .run(|trx, _| async move {
        trx.set(b"key", b"value");
        Ok::<_, FdbBindingError>(())
    })
    .await
Source

pub async fn run_with_hooks<'a, F, Fut, T, E, H: RunnerHooks>( &'a self, hooks: &'a H, closure: F, ) -> Result<T, E>
where F: Fn(RetryableTransaction, MaybeCommitted) -> Fut, Fut: Future<Output = Result<T, E>>, E: RetryableError,

Runs a transactional function against this Database with retry logic and custom hooks.

Sugar for db.runner().hooks(hooks).run(closure). Stack several hooks with a tuple: db.run_with_hooks(&(first, second), closure).

See RunnerHooks for what each hook observes and in which order.

Source

pub async fn instrumented_run<F, Fut, T, E>( &self, closure: F, ) -> Result<(T, MetricsReport), (E, MetricsReport)>
where F: Fn(RetryableTransaction, MaybeCommitted) -> Fut, Fut: Future<Output = Result<T, E>>, E: RetryableError,

Runs a transactional function against this Database with retry logic and metrics collection. The associated closure will be called until a non-retryable FDBError is thrown or commit() returns success.

This method is similar to run() but additionally collects and returns metrics about the transaction execution, including operation counts, bytes read/written, and retry counts. It is MetricsHooks plugged into runner(): stack them on your own hooks with db.run_with_hooks(&(MetricsHooks::new(&metrics), my_hooks), closure) to get the same report out of a run you observe yourself.

§Arguments
  • closure - A function that takes a RetryableTransaction and MaybeCommitted flag and returns a Future
§Returns
  • Result<(T, Metrics), (FdbBindingError, Metrics)> - On success, returns the result of the transaction and collected metrics. On failure, returns the error and the metrics collected up to the point of failure.
§Warning: retry

It might retry indefinitely if the transaction is highly contentious. It is recommended to set options::TransactionOption::RetryLimit or options::TransactionOption::Timeout on the transaction if the task needs to be guaranteed to finish.

§Warning: Maybe committed transactions

As with other client/server databases, in some failure scenarios a client may be unable to determine whether a transaction succeeded. The closure will be notified of a maybe_committed transaction in a previous run with the MaybeCommitted provided in the closure.

Source

pub async fn perform_no_op(&self) -> FdbResult<()>

Perform a no-op against FDB to check network thread liveness. This operation will not change the underlying data in any way, nor will it perform any I/O against the FDB cluster. However, it will schedule some amount of work onto the FDB client and wait for it to complete. The FoundationDB client operates by scheduling onto an event queue that is then processed by a single thread (the “network thread”). This method can be used to determine if the network thread has entered a state where it is no longer processing requests or if its time to process requests has increased. If the network thread is busy, this operation may take some amount of time to complete, which is why this operation returns a future.

Source

pub async fn get_main_thread_busyness(&self) -> FdbResult<f64>

Returns a value where 0 indicates that the client is idle and 1 (or larger) indicates that the client is saturated. By default, this value is updated every second.

Trait Implementations§

Source§

impl Drop for Database

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Send for Database

Source§

impl Sync for Database

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.