Module readonly_supplier

Module readonly_supplier 

Source
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

AspectSupplierReadonlySupplier
self signature&mut self&self
Closure typeFnMut() -> TFn() -> T
Can modify stateYesNo
Arc implementationArc<Mutex<FnMut>>Arc<Fn> (lock-free!)
Use casesCounter, generatorFactory, constant, high concurrency

§Three Implementations

  • BoxReadonlySupplier<T>: Single ownership using Box<dyn Fn() -> T>. Zero overhead, cannot be cloned. Best for one-time use in read-only contexts.

  • ArcReadonlySupplier<T>: Thread-safe shared ownership using Arc<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 using Rc<dyn Fn() -> T>. Can be cloned but not sent across threads. Lightweight alternative to ArcReadonlySupplier.

§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>: Requires Mutex, lock contention on every get() call
  • ArcReadonlySupplier<T>: Lock-free, can call get() concurrently without contention

Benchmark results show ArcReadonlySupplier can be 10x faster than ArcSupplier in high-concurrency scenarios.

§Author

Haixing Hu

Structs§

ArcReadonlySupplier
Thread-safe shared ownership read-only supplier.
BoxReadonlySupplier
Box-based single ownership read-only supplier.
RcReadonlySupplier
Single-threaded shared ownership read-only supplier.

Traits§

ReadonlySupplier
Read-only supplier trait: generates values without modifying state.