Skip to main content

query_runtime/attempt/
cancellation.rs

1//! Attempt-scoped cooperative cancellation and deadline helpers.
2
3use std::time::Instant;
4
5use query_planning::error::Result;
6
7use crate::runtime::ExecutionCancellation;
8
9/// The attempt's cooperative cancellation signal and optional deadline.
10///
11/// All clones, and the `ExecutionCancellation` that native execution receives
12/// through `execution_cancellation`, share one token. `cancel` is
13/// irreversible: it stops the next native boundary from starting work and
14/// leaves already submitted GPU work to settle, preserving cleanup and terminal
15/// report completion.
16#[derive(Debug, Clone)]
17pub struct AttemptCancellation {
18    execution: ExecutionCancellation,
19    deadline: Option<Instant>,
20}
21
22impl AttemptCancellation {
23    pub(crate) fn new(deadline: Option<Instant>) -> Self {
24        Self { execution: ExecutionCancellation::with_deadline(deadline), deadline }
25    }
26
27    /// Requests cooperative cancellation; cleanup still completes.
28    pub fn cancel(&self) {
29        self.execution.cancel()
30    }
31    /// Returns whether caller cancellation was requested or the deadline expired.
32    /// Use [`Self::check`] to distinguish the reasons.
33    pub fn is_cancelled(&self) -> bool {
34        self.execution.is_cancelled()
35    }
36    /// Returns the absolute deadline in the process monotonic clock domain.
37    /// `None` means that the attempt has no deadline.
38    pub fn deadline(&self) -> Option<Instant> {
39        self.deadline
40    }
41
42    /// Returns whether the optional absolute deadline has expired.
43    pub fn is_expired(&self) -> bool {
44        self.execution.is_expired()
45    }
46
47    /// The same token for the native engine's boundary checks; cancelling
48    /// either side cancels both.
49    pub fn execution_cancellation(&self) -> ExecutionCancellation {
50        self.execution.clone()
51    }
52
53    /// Cooperative cancellation check at adapter-owned boundaries (planning,
54    /// pre-execution, and result drain). Caller cancellation wins first; an
55    /// expired deadline reports the distinct `deadline_expired` reason.
56    pub fn check(&self, operation: &'static str) -> Result<()> {
57        self.execution.check(operation)
58    }
59}