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}