forked from github-starred/komodo
KL-8 modify action state internal behavior comments
This commit is contained in:
@@ -1,3 +1,16 @@
|
||||
//! # Action State Management
|
||||
//!
|
||||
//! This module provides thread-safe state management for resource exections.
|
||||
//! It prevents concurrent execution of exections on the same resource using
|
||||
//! a Mutex-based locking mechanism with RAII guards.
|
||||
//!
|
||||
//! ## Safety
|
||||
//!
|
||||
//! - Uses RAII pattern to ensure locks are always released
|
||||
//! - Handles lock poisoning gracefully
|
||||
//! - Prevents race conditions through per-resource locks
|
||||
//! - No deadlock risk: each resource has independent locks
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use anyhow::anyhow;
|
||||
@@ -29,7 +42,16 @@ pub struct ActionStates {
|
||||
CloneCache<String, Arc<ActionState<ResourceSyncActionState>>>,
|
||||
}
|
||||
|
||||
/// Need to be able to check "busy" with write lock acquired.
|
||||
/// Thread-safe state container for resource executions.
|
||||
///
|
||||
/// Uses a Mutex to prevent concurrent executions and provides
|
||||
/// RAII-based locking through [UpdateGuard].
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - Each resource has its own ActionState instance
|
||||
/// - State is reset to default when [UpdateGuard] is dropped
|
||||
/// - Lock poisoning error handling is handled gracefully with anyhow::Error
|
||||
#[derive(Default)]
|
||||
pub struct ActionState<States: Default + Send + 'static>(
|
||||
Mutex<States>,
|
||||
@@ -43,7 +65,7 @@ impl<States: Default + Busy + Copy + Send + 'static>
|
||||
*self
|
||||
.0
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("action state lock poisoned | {e:?}"))?,
|
||||
.map_err(|e| anyhow!("Action state lock poisoned | {e:?}"))?,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -52,14 +74,33 @@ impl<States: Default + Busy + Copy + Send + 'static>
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("action state lock poisoned | {e:?}"))?
|
||||
.map_err(|e| anyhow!("Action state lock poisoned | {e:?}"))?
|
||||
.busy(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Will acquire lock, check busy, and if not will
|
||||
/// run the provided update function on the states.
|
||||
/// Returns a guard that returns the states to default (not busy) when dropped.
|
||||
/// Acquires lock, checks if resource is busy, and if not,
|
||||
/// runs the provided update function on the states.
|
||||
///
|
||||
/// Returns an `UpdateGuard` that automatically resets the state
|
||||
/// to default (not busy) when dropped.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if:
|
||||
/// - The lock is poisoned
|
||||
/// - The resource is currently busy
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// let guard = action_state.update(|state| {
|
||||
/// *state = SomeNewState;
|
||||
/// })?;
|
||||
/// // State is locked and marked as busy
|
||||
/// // ... perform work ...
|
||||
/// drop(guard) // Guard is dropped, state returns to default
|
||||
/// ```
|
||||
pub fn update(
|
||||
&self,
|
||||
update_fn: impl Fn(&mut States),
|
||||
@@ -92,10 +133,22 @@ impl<States: Default + Busy + Copy + Send + 'static>
|
||||
}
|
||||
}
|
||||
|
||||
/// When dropped will return the inner state to default.
|
||||
/// The inner mutex guard must already be dropped BEFORE this is dropped,
|
||||
/// which is guaranteed as the inner guard is dropped by all public methods before
|
||||
/// user could drop UpdateGuard.
|
||||
/// RAII guard that automatically resets the action state when dropped.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The inner mutex guard is guaranteed to be dropped before this guard
|
||||
/// is dropped, preventing deadlocks. This is ensured by all public methods
|
||||
/// that create UpdateGuard instances.
|
||||
///
|
||||
/// # Behavior
|
||||
///
|
||||
/// When dropped, this guard will:
|
||||
/// 1. Re-acquire the lock
|
||||
/// 2. Call the provided return function (typically resetting to default)
|
||||
/// 3. Release the lock
|
||||
///
|
||||
/// If the lock is poisoned, an error is logged but the drop continues.
|
||||
pub struct UpdateGuard<'a, States: Default + Send + 'static>(
|
||||
&'a Mutex<States>,
|
||||
Box<dyn Fn(&mut States) + Send>,
|
||||
|
||||
Reference in New Issue
Block a user