Expand description
§Supplier Types
Provides stateless supplier implementations that generate and return values without taking input.
§Overview
A Supplier is a functional abstraction equivalent to
Fn() -> T: it generates values without accepting input or
requiring mutable access to itself. The get method uses &self,
enabling use in read-only contexts and lock-free concurrent access
for the Arc implementation.
For generators that need mutable internal state, such as counters
or sequences, use StatefulSupplier.
§Key Differences from StatefulSupplier
| Aspect | Supplier<T> | StatefulSupplier<T> |
|---|---|---|
| self signature | &self | &mut self |
| Closure type | Fn() -> T | FnMut() -> T |
| Can modify internal state | No | Yes |
| Arc implementation | Arc<dyn Fn() -> T + Send + Sync> | Arc<Mutex<dyn FnMut() -> T + Send>> |
| Use cases | Factory, constant, high concurrency | Counter, sequence, generator |
§Three Implementations
-
BoxSupplier<T>: Single ownership usingBox<dyn Fn() -> T>. Zero overhead, cannot be cloned. Best for one-time use in read-only contexts. -
ArcSupplier<T>: Thread-safe shared ownership usingArc<dyn Fn() -> T + Send + Sync>. Lock-free - no Mutex needed! Can be cloned and sent across threads with excellent performance. -
RcSupplier<T>: Single-threaded shared ownership usingRc<dyn Fn() -> T>. Can be cloned but not sent across threads. Lightweight alternative toArcSupplier.
§Use Cases
§1. Calling in &self Methods
use qubit_function::{ArcSupplier, Supplier};
struct Executor<E> {
error_supplier: ArcSupplier<E>,
}
impl<E> Executor<E> {
fn execute(&self) -> Result<(), E> {
// Can call directly in &self method!
Err(self.error_supplier.get())
}
}§2. High-Concurrency Lock-Free Access
use qubit_function::{ArcSupplier, Supplier};
use std::thread;
let factory = ArcSupplier::new(|| {
String::from("Hello, World!")
});
let handles: Vec<_> = (0..10)
.map(|_| {
let f = factory.clone();
thread::spawn(move || f.get()) // Lock-free!
})
.collect();
for h in handles {
assert_eq!(h.join().unwrap(), "Hello, World!");
}§3. Fixed Factories
use qubit_function::{BoxSupplier, Supplier};
#[derive(Clone)]
struct Config {
timeout: u64,
}
let config_factory = BoxSupplier::new(|| Config {
timeout: 30,
});
assert_eq!(config_factory.get().timeout, 30);
assert_eq!(config_factory.get().timeout, 30);§Performance Comparison
For stateless scenarios in multi-threaded environments:
ArcStatefulSupplier<T>: RequiresMutex, lock contention on everyget()call.ArcSupplier<T>: Lock-free, can callget()concurrently without contention.
Benchmark results show ArcSupplier can be 10x
faster than ArcStatefulSupplier in high-concurrency stateless
scenarios.
§Author
Haixing Hu
Structs§
- ArcSupplier
- Thread-safe shared ownership stateless supplier.
- BoxSupplier
- Box-based single ownership stateless supplier.
- RcSupplier
- Single-threaded shared ownership stateless supplier.
Traits§
- Supplier
- Stateless supplier trait: generates values without modifying state.