Expand description
tower::Service integeration + thread-pool.
§service
The service module implements the tower integration,
along with the reader/writer thread-pool system.
The thread-pool allows outside crates to communicate with it by
sending database Requests and receiving Responses asynchronously -
without having to actually worry and handle the database themselves.
The system is managed by this crate, and only requires init by the user.
§Handles
The 2 handles to the database are:
The 1st allows any caller to send ReadRequests.
The 2nd allows any caller to send WriteRequests.
The BlockchainReadHandle can be shared as it is cheaply Cloneable, however,
the BlockchainWriteHandle cannot be cloned. There is only 1 place in Cuprate that
writes, so it is passed there and used.
§Initialization
The database & thread-pool system can be initialized with init().
This causes the underlying database/threads to be setup and returns a read/write handle to that database.
§Shutdown
Upon the above handles being dropped, the corresponding thread(s) will automatically exit, i.e:
- The last
BlockchainReadHandleis dropped => reader thread-pool exits - The last
BlockchainWriteHandleis dropped => writer thread exits
TODO: update this when ConcreteEnv is removed
Upon dropping the cuprate_database::ConcreteEnv:
- All un-processed database transactions are completed
- All data gets flushed to disk (caused by
Drop::dropimpl onConcreteEnv)
§Request and Response
To interact with the database (whether reading or writing data),
a Request can be sent using one of the above handles.
Both the handles implement tower::Service, so they can be tower::Service::called.
An asynchronous channel will be returned from the call.
This channel can be .awaited upon to (eventually) receive
the corresponding Response to your Request.
§Example
Simple usage of service.
use hex_literal::hex;
use tower::{Service, ServiceExt};
use cuprate_types::{blockchain::{BlockchainReadRequest, BlockchainWriteRequest, BlockchainResponse}, Chain};
use cuprate_test_utils::data::BLOCK_V16_TX0;
use cuprate_blockchain::{
cuprate_database::Env,
config::ConfigBuilder,
};
// Create a configuration for the database environment.
let tmp_dir = tempfile::tempdir()?;
let db_dir = tmp_dir.path().to_owned();
let config = ConfigBuilder::new()
.data_directory(db_dir.into())
.build();
// Initialize the database thread-pool.
let (mut read_handle, mut write_handle, _) = cuprate_blockchain::service::init(config)?;
// Prepare a request to write block.
let mut block = BLOCK_V16_TX0.clone();
let request = BlockchainWriteRequest::WriteBlock(block);
// Send the request.
// We receive back an `async` channel that will
// eventually yield the result when `service`
// is done writing the block.
let response_channel = write_handle.ready().await?.call(request);
// Block write was OK.
let response = response_channel.await?;
assert_eq!(response, BlockchainResponse::Ok);
// Now, let's try getting the block hash
// of the block we just wrote.
let request = BlockchainReadRequest::BlockHash(0, Chain::Main);
let response_channel = read_handle.ready().await?.call(request);
let response = response_channel.await?;
assert_eq!(
response,
BlockchainResponse::BlockHash(
hex!("43bd1f2b6556dcafa413d8372974af59e4e8f37dbf74dc6b2a9b7212d0577428")
)
);
// This causes the writer thread on the
// other side of this handle to exit...
drop(write_handle);
// ...and this causes the reader thread-pool to exit.
drop(read_handle);Functions§
- init
- Initialize a database & thread-pool, and return a read/write handle to it.
- init_
read_ service - Initialize the
BlockchainReadHandlethread-pool backed byrayon. - init_
read_ service_ with_ pool - Initialize the blockchain database read service, with a specific rayon thread-pool instead of creating a new one.
- init_
with_ pool - Initialize a database, and return a read/write handle to it.
- init_
write_ service - Initialize the blockchain write service from a
ConcreteEnv.
Type Aliases§
- Blockchain
Read Handle - The blockchain database read service.
- Blockchain
Write Handle - The blockchain database write service.