By utilizing a barrier to guard thread local data destruction until runtime threads rendezvous during shutdown, it becomes possible to create thread-safe pointers to thread-local data owned by runtime worker threads and in doing so this facilitates heapless allocations where otherwise an std::sync::Arc
would be necessitated (see async-local for more details). Building on top of barrier-protected thread-owned buffers, stack-queue delivers a set of algorithms for asynchronously batching tasks in a way that allows for constant-time deferrable take-all batch collection by negotiating exclusive access over a range of tasks. By using a fixed-size circular buffer, writes can cycle without atomic indexing with write confirmations then synchronizing while observing interlaced batch boundaries under a data-race free relaxed atomic model. Not only does this cut in half the number of atomic calls per write operation, but this also creates an asymmetrical performance profile with task ranges bounded by a single atomic operation per batch, making this ideal for use-cases in which it's desireable for task batches to grow while awaiting resources, such as for deferring batch bounding until after a database connection is available for a batched query. As push operations enqueue within an async context, receivers are already pinned and can be written to directly without heap allocation and should the current threads queue be full, work-stealing will redistribute tasks.
In order for async-local to protect thread local data within an async context, the provided barrier-protected Tokio Runtime must be used to ensure tasks never outlive thread local data owned by worker threads. By default, this crate makes no assumptions about the runtime used, and comes with the leaky-context
feature flag enabled which prevents Contextleaky-context
and configure the runtime using the tokio::main or tokio::test macro with the crate
attribute set to async_local
while only the barrier-protected-runtime
feature flag set on async-local
.
| crossbeam
| flume
| stack-queue::TaskQueue
| stack-queue::BackgroundQueue
| tokio::mpsc
|
|:------------------------|:-------------------------------|:----------------------------------|:----------------------------------------|:------------------------------- |
| 1.74 us
(✅ 1.00x) | 2.01 us
(❌ 1.16x slower) | 974.99 ns
(✅ 1.78x faster) | 644.55 ns
(🚀 2.69x faster) | 1.96 us
(❌ 1.13x slower) |
This crate conditionally makes use of the nightly only feature typealiasimpltrait to allow async fns in traits to be unboxed. To compile on stable
the boxed
feature flag can be used to downgrade asynct::asynctrait to asynctrait::async_trait.