Expand description
A fast, concurrent, lock-free, and sometimes wait-free, pool implementation.
§Quick overview
A pool is a limited-sized collection of objects. When an object is fetched from the pool, the number of available objects decreases by one. Once the fetched object is dropped, it goes back into the pool, and the number of available objects increases by one. Being as fast as possible, avoiding blocking, and, whenever possible, avoiding waiting, is the name of the game.
All objects are lazily created with a builder, which can be synchronous or asynchronous, fallible or infallible. Objects are recycled, i.e. when an object has been built and fetched once, it can be mutated, and when it goes back in the pool, it stays as is, untouched.
use flaque::Pool;
// Let's define what the pool will hold.
struct T {
x: u8,
}
impl Default for T {
fn default() -> Self {
Self { x: 0 }
}
}
// Let's create the pool: capacity of 8, and the builder for the `T`s.
let pool = Pool::new(8, T::default);
// Let's try to get an object from the pool.
let object_0 = pool.try_get().unwrap();
// Or, let's wait to get an object from the pool.
let object_1 = pool.get().await;The main methods are:
Pool::newto build aPoolwith a synchronous builder,Pool::new_with_async_builderto build aPoolwith an asynchronous builder,Pool::try_getif one wants to synchronously, atomically get an object from the pool,Pool::getif one wants to asynchronously get an object from the pool, waiting for one to become available.
An object is represented by the Object<T, _> type, which derefs and
deref_muts to T. When it drops, the value returns immediately to the
pool.
§Features
§Lock- and wait-free
This pool implementation is lock-free and sometimes wait-free. It is designed to be fast and consistent.
| Operation | Lock-free | Wait-free |
|---|---|---|
Pool::try_get | yes | yes |
Pool::get | yes | no |
Object::drop | yes | yes |
Pool::close | yes | no |
Pool::reopen | yes | yes |
If you’re not familiar with these definitions, please read Non-blocking algorithm.
§Get and Close futures
Pool::get returns a Get future. It resolves to Ok(object) once one is
available in the pool, otherwise it returns to Err(GetError) if the pool
is closed or if the builder failed to build an object.
Pool::close returns a Close future. It resolves once all Objects are
back into the pool, i.e. when they are all dropped. Pool::close takes
self, i.e. it takes ownership of the pool. It will be returned back once
the future resolves. This guarantees that it is impossible to reopen the
pool, and to fetch new Objects, while waiting for all Objects to return
back into the pool. Thus, this is not unusual to see:
let pool = pool.close().await;Structs§
- Async
- A “marker” to represent a
Poolthat uses an asynchronous object builder (i.e.AsyncBuilder). - Async
Get - Async-flavour of
Get, built automatically by<Get<T, Async<B>> as IntoFuture>. - Close
- The future returned by
Pool::close. - Get
- The future returned by
Pool::get. - Object
- An
Objectacquired from aPoolwithPool::try_getorPool::get. - Pool
- The almighty pool!
- Sync
- A “marker” to represent a
Poolthat uses a synchronous object builder (i.e.SyncBuilder).
Enums§
- GetError
- Error returned by
GetviaPool::get. - TryGet
Error - Error returned by
Pool::try_get.
Traits§
- Async
Builder - A trait representing any kind of asynchronous builders, used to produce new
object for the
Pool. - Into
Result - A trait to transform any
Tinto aResult<T, Self::Error>. - Sync
Builder - A trait representing any kind of synchronous builders, used to produce new
object for the
Pool.