1use std::sync::{Arc, Mutex};
16
17use common_base::cancellation::CancellationHandle;
18
19pub mod remote_job_scheduler;
20pub mod scheduler;
21
22#[derive(Debug, Clone)]
24pub(crate) struct CancellableTaskState {
25 cancel_handle: Arc<CancellationHandle>,
26 commit_started: Arc<Mutex<bool>>,
27}
28
29impl CancellableTaskState {
30 pub(crate) fn new() -> Self {
31 Self {
32 cancel_handle: Arc::new(CancellationHandle::default()),
33 commit_started: Arc::new(Mutex::new(false)),
34 }
35 }
36
37 pub(crate) fn cancel_handle(&self) -> Arc<CancellationHandle> {
38 self.cancel_handle.clone()
39 }
40
41 pub(crate) fn is_cancelled(&self) -> bool {
42 self.cancel_handle.is_cancelled()
43 }
44
45 pub(crate) fn commit_started(&self) -> bool {
47 *self.commit_started.lock().unwrap()
48 }
49
50 pub(crate) fn mark_commit_started(&self) -> bool {
54 let mut commit_started = self.commit_started.lock().unwrap();
55 if self.cancel_handle.is_cancelled() {
56 return false;
57 }
58 *commit_started = true;
59 true
60 }
61
62 pub(crate) fn request_cancel(&self) -> RequestCancelResult {
63 let commit_started = self.commit_started.lock().unwrap();
65 if *commit_started {
66 return RequestCancelResult::TooLateToCancel;
67 }
68 if self.cancel_handle.is_cancelled() {
69 return RequestCancelResult::AlreadyCancelling;
70 }
71
72 self.cancel_handle.cancel();
73 RequestCancelResult::CancelIssued
74 }
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
78pub(crate) enum RequestCancelResult {
79 CancelIssued,
80 AlreadyCancelling,
81 TooLateToCancel,
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_cancellable_task_state_transitions() {
90 let state = CancellableTaskState::new();
91 assert_eq!(RequestCancelResult::CancelIssued, state.request_cancel());
92 assert!(state.is_cancelled());
93 assert_eq!(
94 RequestCancelResult::AlreadyCancelling,
95 state.request_cancel()
96 );
97 assert!(!state.mark_commit_started());
98
99 let state = CancellableTaskState::new();
100 assert!(state.mark_commit_started());
101 assert_eq!(RequestCancelResult::TooLateToCancel, state.request_cancel());
102 }
103}