Expand description
§Read-only Supplier Types
Provides read-only supplier implementations that generate and return values without modifying their own state.
§Overview
A ReadonlySupplier is a functional abstraction that
generates values without accepting input or modifying its own
state. Unlike Supplier, it uses &self instead of &mut self, enabling usage in read-only contexts and lock-free
concurrent access.
§Key Differences from Supplier
| Aspect | Supplier | ReadonlySupplier |
|---|---|---|
| self signature | &mut self | &self |
| Closure type | FnMut() -> T | Fn() -> T |
| Can modify state | Yes | No |
| Arc implementation | Arc<Mutex<FnMut>> | Arc<Fn> (lock-free!) |
| Use cases | Counter, generator | Factory, constant, high concurrency |
§Three Implementations
-
BoxReadonlySupplier<T>: Single ownership usingBox<dyn Fn() -> T>. Zero overhead, cannot be cloned. Best for one-time use in read-only contexts. -
ArcReadonlySupplier<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. -
RcReadonlySupplier<T>: Single-threaded shared ownership usingRc<dyn Fn() -> T>. Can be cloned but not sent across threads. Lightweight alternative toArcReadonlySupplier.
§Use Cases
§1. Calling in &self Methods
use prism3_function::{ArcReadonlySupplier, ReadonlySupplier};
struct Executor<E> {
error_supplier: ArcReadonlySupplier<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 prism3_function::{ArcReadonlySupplier, ReadonlySupplier};
use std::thread;
let factory = ArcReadonlySupplier::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 prism3_function::{BoxReadonlySupplier, ReadonlySupplier};
#[derive(Clone)]
struct Config {
timeout: u64,
}
let config_factory = BoxReadonlySupplier::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:
ArcSupplier<T>: RequiresMutex, lock contention on everyget()callArcReadonlySupplier<T>: Lock-free, can callget()concurrently without contention
Benchmark results show ArcReadonlySupplier can be 10x
faster than ArcSupplier in high-concurrency scenarios.
§Author
Haixing Hu
Structs§
- ArcReadonly
Supplier - Thread-safe shared ownership read-only supplier.
- BoxReadonly
Supplier - Box-based single ownership read-only supplier.
- RcReadonly
Supplier - Single-threaded shared ownership read-only supplier.
Traits§
- Readonly
Supplier - Read-only supplier trait: generates values without modifying state.