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}