Client Network Thread

Full working code for concepts described in this section is here.

FoundationDB clients are required to start a network thread before they can communicate with the cluster.

Each language binding provides its own mechanism for starting client network thread. An important consideration is that while the client network thread can be started and stopped, once it has been stopped, it cannot be started again.

For our Tokio binding, we recommend that you start the client network thread and open the database in the main thread before starting the Tokio runtime. Once the Tokio runtime completes, you can safely close the database and stop the network thread.

In the next sections we describe how this can be accomplished in more detail.

Identifying the cluster file

Begin by identifying the location of the FoundationDB cluster file. It is common practice to specify this file using the environment variable FDB_CLUSTER_FILE.

let fdb_cluster_file = env::var("FDB_CLUSTER_FILE")
    .expect("FDB_CLUSTER_FILE not defined!");

Select API version

Before starting the client network you need to specify API version to use. This can be done as follows.

unsafe {
    fdb::select_api_version(710);
    // ...
}

Here we are selecting API version 710. In Rust unsafe keyword is used to indicate to the user of API that there invariants that cannot be checked by the compiler.

For our bindings, we have marked initialization APIs as unsafe primarily to help you understand the interaction that between Tokio runtime and FoundationDB client network thread.

Start Client Network Thread

Once the API version is selected you can start the client network thread as follows.

unsafe {
    fdb::select_api_version(710);
    fdb::start_network();
}

Open Database

After the client network thread as started, you can open the FoundationDB database specified by the cluster file.

let fdb_database = fdb::open_database(fdb_cluster_file)?;

open_database function returns a value of FdbResult type.

FdbResult type provides a common error handling abstraction for all APIs in the crate. In addition it also signals errors that might have occurred in the C API.

In the above code fdb_database is a value of FdbDatabase type and points to the FoundationDB database specified by the cluster file.

Start Tokio Runtime

After you have obtained a value of FdbDatabase type, you can start the Tokio Runtime, its the main async task and move a cloned value of FdbDatabase into the main Tokio task.

let rt = Runtime::new()?;

let cloned_fdb_database = fdb_database.clone();

rt.block_on(async {
    let fdb_database = cloned_fdb_database;

    // your main async app here
    
    Result::<(), Box<dyn Error>>::Ok(())
})?;

At this point, rt.block_on will block the main thread. In your application you will have multiple running threads. They would include threads launched by Tokio runtime and FoundationDB client network thread.

Stop Client Network Thread

Once rt.block_on returns, you can gracefully stop the client network thread by doing the following.

drop(fdb_database);

unsafe {
    fdb::stop_network();
}

This should allow you to cleanly exit your application.

Edit this page on GitHub