qubit_executor/service/executor_service.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use std::future::Future;
11
12use qubit_function::{
13 Callable,
14 Runnable,
15};
16
17use super::{
18 RejectedExecution,
19 ShutdownReport,
20};
21
22/// Managed task service with submission and lifecycle control.
23///
24/// `ExecutorService` is intentionally separate from
25/// [`Executor`](crate::executor::Executor). An executor describes an
26/// execution strategy; an executor service accepts tasks into a managed service
27/// that may queue, schedule, assign workers, and track lifecycle.
28///
29/// `submit` and `submit_callable` return `Result` values whose outer `Ok`
30/// means only that the service accepted the task. It does **not** mean the task
31/// has started or succeeded. The task's final result is observed through the
32/// returned handle.
33///
34pub trait ExecutorService: Send + Sync {
35 /// Handle returned for an accepted task.
36 type Handle<R, E>
37 where
38 R: Send + 'static,
39 E: Send + 'static;
40
41 /// Future returned when waiting for service termination.
42 type Termination<'a>: Future<Output = ()> + Send + 'a
43 where
44 Self: 'a;
45
46 /// Submits a runnable task to this service.
47 ///
48 /// # Parameters
49 ///
50 /// * `task` - A fallible background action with no business return value.
51 ///
52 /// # Returns
53 ///
54 /// `Ok(handle)` if the service accepts the task. This only reports
55 /// acceptance; it does not report task start or task success. Returns
56 /// `Err(RejectedExecution)` if the service refuses the task before
57 /// accepting it.
58 ///
59 /// # Errors
60 ///
61 /// Returns [`RejectedExecution`] when the service refuses the task before
62 /// accepting it.
63 #[inline]
64 fn submit<T, E>(&self, task: T) -> Result<Self::Handle<(), E>, RejectedExecution>
65 where
66 T: Runnable<E> + Send + 'static,
67 E: Send + 'static,
68 {
69 let mut task = task;
70 self.submit_callable(move || task.run())
71 }
72
73 /// Submits a callable task to this service.
74 ///
75 /// # Parameters
76 ///
77 /// * `task` - A fallible computation whose success value should be captured
78 /// in the returned handle.
79 ///
80 /// # Returns
81 ///
82 /// `Ok(handle)` if the service accepts the task. This only reports
83 /// acceptance; task success, task failure, panic, or cancellation must be
84 /// observed through the returned handle. Returns `Err(RejectedExecution)` if
85 /// the service refuses the task before accepting it.
86 ///
87 /// # Errors
88 ///
89 /// Returns [`RejectedExecution`] when the service refuses the task before
90 /// accepting it.
91 fn submit_callable<C, R, E>(&self, task: C) -> Result<Self::Handle<R, E>, RejectedExecution>
92 where
93 C: Callable<R, E> + Send + 'static,
94 R: Send + 'static,
95 E: Send + 'static;
96
97 /// Initiates an orderly shutdown.
98 ///
99 /// After shutdown starts, new tasks are rejected. Already accepted tasks are
100 /// allowed to complete unless the concrete service documents stronger
101 /// cancellation behavior.
102 fn shutdown(&self);
103
104 /// Attempts to stop accepting and running tasks immediately.
105 ///
106 /// # Returns
107 ///
108 /// A count-based shutdown report describing the state observed at the time
109 /// of the request.
110 fn shutdown_now(&self) -> ShutdownReport;
111
112 /// Returns whether shutdown has been requested.
113 ///
114 /// # Returns
115 ///
116 /// `true` if this service is no longer accepting new tasks.
117 fn is_shutdown(&self) -> bool;
118
119 /// Returns whether the service has terminated.
120 ///
121 /// # Returns
122 ///
123 /// `true` only after shutdown has been requested and all accepted tasks have
124 /// completed or been cancelled.
125 fn is_terminated(&self) -> bool;
126
127 /// Waits until the service has terminated.
128 ///
129 /// # Returns
130 ///
131 /// A future that completes after shutdown has been requested and no accepted
132 /// tasks remain active.
133 fn await_termination(&self) -> Self::Termination<'_>;
134}