Skip to main content

rustferry_remote/
cancellation.rs

1use std::sync::{
2    Arc,
3    atomic::{AtomicBool, Ordering},
4};
5
6use crate::error::{RemoteBuildError, RemoteBuildResult};
7
8/// Cloneable cooperative-cancellation signal shared with provider futures.
9///
10/// Cancellation never terminates a process by itself. Implementations must check the token at
11/// bounded intervals and perform their own process-tree or network-request cleanup.
12#[derive(Clone, Debug, Default)]
13pub struct CancellationToken {
14    requested: Arc<AtomicBool>,
15}
16
17impl CancellationToken {
18    /// Create a token in the active state.
19    pub fn new() -> Self {
20        Self::default()
21    }
22
23    /// Request cancellation, returning `true` only for the first request.
24    pub fn cancel(&self) -> bool {
25        self.requested
26            .compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire)
27            .is_ok()
28    }
29
30    /// Whether cancellation has been requested.
31    pub fn is_cancelled(&self) -> bool {
32        self.requested.load(Ordering::Acquire)
33    }
34
35    /// Return a typed cancellation error after a request.
36    ///
37    /// # Errors
38    ///
39    /// Returns [`RemoteBuildError::Cancelled`] after cancellation is requested.
40    pub fn check(&self) -> RemoteBuildResult<()> {
41        if self.is_cancelled() {
42            Err(RemoteBuildError::Cancelled)
43        } else {
44            Ok(())
45        }
46    }
47}