setup_read_cleanup 0.3.1

A library for safely transitioning through the three phases of shared resource access: setup, read, and cleanup.
Documentation

setup_read_cleanup crates.io doc.rs CI Status MIT License

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.

Core Concepts

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.

Cell Variants

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 setup_read_cleanup-on-tokio feature) An async version of PhasedCellSync that uses a tokio::sync::Mutex.

Graceful Shutdown

(Requires the setup_read_cleanup-graceful feature)

The graceful module provides wrappers that add graceful shutdown capabilities. When transitioning to the Cleanup phase, these cells will wait for a specified duration for all active read operations to complete.

Features

  • setup_read_cleanup-on-tokio: Enables the async cell variants (PhasedCellAsync, GracefulPhasedCellAsync) which use tokio::sync.
  • setup_read_cleanup-graceful: Enables the graceful module, which provides cells with graceful shutdown capabilities.

Examples

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!");
}

Installation

In Cargo.toml, write this crate as a dependency:

[dependencies]
setup_read_cleanup = "0.3.1"

Supported Rust versions

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

License

Copyright (C) 2025 Takayuki Sato

This program is free software under MIT License. See the file LICENSE in this distribution for more details.