use std::sync::{
Arc,
atomic::{AtomicBool, Ordering},
};
use qubit_dcl::{ArcMutex, DoubleCheckedLockExecutor, Lock};
#[derive(Debug, thiserror::Error)]
#[allow(dead_code)]
enum ServiceError {
#[error("Service is not running")]
NotRunning,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let running = Arc::new(AtomicBool::new(false));
let data = ArcMutex::new(42);
println!(
"Initial state: running = {}",
running.load(Ordering::Acquire)
);
println!("Initial data: {}", data.read(|d| *d));
let executor = DoubleCheckedLockExecutor::builder()
.on(data.clone())
.when({
let running = running.clone();
move || running.load(Ordering::Acquire)
})
.build();
let result = executor
.call_with(|value: &mut i32| {
*value += 1;
Ok::<_, ServiceError>(*value)
})
.get_result();
if result.is_success() {
println!("Unexpected success: {}", result.unwrap());
} else {
println!("Expected failure: Condition not met.");
}
running.store(true, Ordering::Release);
println!(
"Service started: running = {}",
running.load(Ordering::Acquire)
);
let result = executor
.call_with(|value: &mut i32| {
*value += 1;
Ok::<_, ServiceError>(*value)
})
.get_result();
if result.is_success() {
println!("Success: new value = {}", result.unwrap());
} else {
println!("Unexpected failure: {:?}", result);
}
println!("Final data: {}", data.read(|d| *d));
running.store(false, Ordering::Release);
println!(
"Service stopped: running = {}",
running.load(Ordering::Acquire)
);
let result = executor
.call_with(|value: &mut i32| {
*value += 1;
Ok::<_, ServiceError>(*value)
})
.get_result();
if result.is_success() {
println!("Unexpected success: {}", result.unwrap());
} else {
println!("Expected failure: Condition not met.");
}
Ok(())
}