use crate::interrupt::InterruptSignal;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use tokio::sync::mpsc;
#[derive(Clone, Debug)]
pub struct InterruptContext {
resume_values: Arc<[Option<serde_json::Value>]>,
current_index: Arc<AtomicUsize>,
interrupt_tx: mpsc::UnboundedSender<InterruptSignal>,
}
impl InterruptContext {
#[must_use]
pub fn new(
resume_values: Vec<Option<serde_json::Value>>,
interrupt_tx: mpsc::UnboundedSender<InterruptSignal>,
) -> Self {
Self {
resume_values: resume_values.into_boxed_slice().into(),
current_index: Arc::new(AtomicUsize::new(0)),
interrupt_tx,
}
}
#[must_use]
pub fn next_index(&self) -> usize {
self.current_index.fetch_add(1, Ordering::Relaxed)
}
#[must_use]
pub fn get_resume_value(&self, index: usize) -> Option<serde_json::Value> {
self.resume_values
.get(index)
.and_then(std::clone::Clone::clone)
}
#[must_use]
pub fn current_index(&self) -> usize {
self.current_index.load(Ordering::Relaxed)
}
pub fn send_interrupt(
&self,
signal: InterruptSignal,
) -> Result<(), mpsc::error::SendError<InterruptSignal>> {
self.interrupt_tx.send(signal)
}
}