| Crates.io | setup_read_cleanup |
| lib.rs | setup_read_cleanup |
| version | 0.6.0 |
| created_at | 2025-09-10 12:29:09.071527+00 |
| updated_at | 2026-01-04 12:25:16.606282+00 |
| description | A library for safely transitioning through the three phases of shared resource access: setup, read, and cleanup. |
| homepage | |
| repository | https://github.com/sttk/setup_read_cleanup-rust |
| max_upload_size | |
| id | 1832450 |
| size | 368,588 |
A library for managing data through distinct lifecycle phases: Setup -> Read -> Cleanup.
This crate provides "phased cells", a collection of smart pointer types that enforce a specific lifecycle for the data they manage. This is useful for data that is initialized once, read by multiple threads or tasks for a period, and then explicitly destroyed.
The lifecycle is divided into three phases:
Setup: The initial phase. The data can be mutably accessed for initialization.Read: The operational phase. The data can only be accessed immutably. This phase is optimized for concurrent, lock-free reads.Cleanup: The final phase. The data can be mutably accessed again for deconstruction or resource cleanup.The transition_to_read and transition_to_cleanup methods execute user-provided closures. If a panic occurs within these closures, PhasedCell ensures the following behavior across all its variants:
transition_to_read: If the closure panics, the cell's phase is safely reverted to Setup.transition_to_cleanup: If the closure panics, the cell's phase is safely transitioned to Cleanup.In both cases, any acquired internal mutexes are released before the panic is resumed, preventing deadlocks. The original panic is re-propagated, maintaining Rust's panic-safety guarantees while ensuring internal consistency.
This crate offers several cell variants to suit different concurrency needs:
PhasedCell: The basic cell. It is Sync, allowing it to be shared across threads for reading. However, mutable access via get_mut_unlocked is not thread-safe and requires the caller to ensure exclusive access.PhasedCellSync: A thread-safe version that uses a std::sync::Mutex to allow for safe concurrent mutable access during the Setup and Cleanup phases.PhasedCellAsync: (Requires the tokio feature) An async version of PhasedCellSync that uses a tokio::sync::Mutex.(Requires the graceful feature)
The graceful module provides wrappers that add graceful capabilities to phased cells:
Cleanup phase.Setup phase and transitioning to Read, the read operation
will wait for the transition to complete and for the cell to enter the Read phase.It provides the following cells:
GracefulPhasedCellGracefulPhasedCellSyncGracefulPhasedCellAsync (Requires graceful and tokio features)tokio: Enables the async cell variants (PhasedCellAsync, GracefulPhasedCellAsync) which use tokio::sync.graceful: Enables the graceful module, which provides cells with graceful cleanup capabilities.Using a static PhasedCellSync to initialize data, read it from multiple threads, and then clean it up.
use setup_read_cleanup::{PhasedCellSync, Phase};
use std::thread;
struct MyData {
items: Vec<i32>,
}
// Declare a static PhasedCellSync instance
static CELL: PhasedCellSync<MyData> = PhasedCellSync::new(MyData { items: Vec::new() });
fn main() {
// --- Setup Phase ---
assert_eq!(CELL.phase(), Phase::Setup);
{
let mut data = CELL.lock().unwrap();
data.items.push(10);
data.items.push(20);
} // Lock is released here
// --- Transition to Read Phase ---
CELL.transition_to_read(|data| {
data.items.push(30);
Ok::<(), std::io::Error>(())
}).unwrap();
assert_eq!(CELL.phase(), Phase::Read);
// --- Read Phase ---
// Now, multiple threads can read the data concurrently.
let mut handles = Vec::new();
for i in 0..3 {
handles.push(thread::spawn(move || {
let data = CELL.read().unwrap(); // Access the static CELL
println!("Thread {} reads: {:?}", i, data.items);
assert_eq!(data.items, &[10, 20, 30]);
}));
}
for handle in handles {
handle.join().unwrap();
}
// --- Transition to Cleanup Phase ---
CELL.transition_to_cleanup(|data| {
println!("Cleaning up. Final item: {:?}", data.items.pop());
Ok::<(), std::io::Error>(())
}).unwrap();
assert_eq!(CELL.phase(), Phase::Cleanup);
println!("Example finished successfully!");
}
In Cargo.toml, write this crate as a dependency:
[dependencies]
setup_read_cleanup = "0.6.0"
This crate supports Rust 1.74.1 or later.
% ./build.sh msrv
[Meta] cargo-msrv 0.18.4
Compatibility Check #1: Rust 1.74.1
[OK] Is compatible
Compatibility Check #2: Rust 1.65.0
[FAIL] Is incompatible
Compatibility Check #3: Rust 1.69.0
[FAIL] Is incompatible
Compatibility Check #4: Rust 1.71.1
[FAIL] Is incompatible
Compatibility Check #5: Rust 1.72.1
[FAIL] Is incompatible
Compatibility Check #6: Rust 1.73.0
[FAIL] Is incompatible
Result:
Considered (min … max): Rust 1.56.1 … Rust 1.91.1
Search method: bisect
MSRV: 1.74.1
Target: x86_64-apple-darwin
Copyright (C) 2025 Takayuki Sato
This program is free software under MIT License.
See the file LICENSE in this distribution for more details.