Skip to main content

qubit_executor/schedule/
scheduled_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::time::{
11    Duration,
12    Instant,
13};
14
15use qubit_function::{
16    Callable,
17    Runnable,
18};
19
20use crate::service::{
21    ExecutorService,
22    SubmissionError,
23};
24
25/// Managed executor service with delayed and instant-based submission support.
26///
27/// `ScheduledExecutorService` extends [`ExecutorService`] with per-task timing.
28/// A normal `submit` call is an immediate submission; `schedule` and
29/// `schedule_at` accept work now but delay the task start until the requested
30/// time. Successful submission only means the service accepted the scheduled
31/// task. Task success, failure, panic, or cancellation is observed through the
32/// returned tracked handle.
33pub trait ScheduledExecutorService: ExecutorService {
34    /// Schedules a runnable task to start after the supplied delay.
35    ///
36    /// # Parameters
37    ///
38    /// * `delay` - Minimum delay before the task becomes runnable.
39    /// * `task` - Runnable to execute after the delay elapses.
40    ///
41    /// # Returns
42    ///
43    /// A tracked handle for observing or cancelling the scheduled task.
44    ///
45    /// # Errors
46    ///
47    /// Returns [`SubmissionError`] when the service refuses the task before
48    /// accepting it.
49    #[inline]
50    fn schedule<T, E>(&self, delay: Duration, task: T) -> Result<Self::TrackedHandle<(), E>, SubmissionError>
51    where
52        T: Runnable<E> + Send + 'static,
53        E: Send + 'static,
54    {
55        let mut task = task;
56        self.schedule_callable(delay, move || task.run())
57    }
58
59    /// Schedules a callable task to start after the supplied delay.
60    ///
61    /// # Parameters
62    ///
63    /// * `delay` - Minimum delay before the task becomes runnable.
64    /// * `task` - Callable to execute after the delay elapses.
65    ///
66    /// # Returns
67    ///
68    /// A tracked handle for observing or cancelling the scheduled task.
69    ///
70    /// # Errors
71    ///
72    /// Returns [`SubmissionError`] when the service refuses the task before
73    /// accepting it.
74    #[inline]
75    fn schedule_callable<C, R, E>(&self, delay: Duration, task: C) -> Result<Self::TrackedHandle<R, E>, SubmissionError>
76    where
77        C: Callable<R, E> + Send + 'static,
78        R: Send + 'static,
79        E: Send + 'static,
80    {
81        self.schedule_callable_at(Instant::now() + delay, task)
82    }
83
84    /// Schedules a runnable task to start at a monotonic instant.
85    ///
86    /// # Parameters
87    ///
88    /// * `instant` - Monotonic instant at which the task becomes runnable.
89    /// * `task` - Runnable to execute at or after the instant.
90    ///
91    /// # Returns
92    ///
93    /// A tracked handle for observing or cancelling the scheduled task.
94    ///
95    /// # Errors
96    ///
97    /// Returns [`SubmissionError`] when the service refuses the task before
98    /// accepting it.
99    #[inline]
100    fn schedule_at<T, E>(&self, instant: Instant, task: T) -> Result<Self::TrackedHandle<(), E>, SubmissionError>
101    where
102        T: Runnable<E> + Send + 'static,
103        E: Send + 'static,
104    {
105        let mut task = task;
106        self.schedule_callable_at(instant, move || task.run())
107    }
108
109    /// Schedules a callable task to start at a monotonic instant.
110    ///
111    /// # Parameters
112    ///
113    /// * `instant` - Monotonic instant at which the task becomes runnable.
114    /// * `task` - Callable to execute at or after the instant.
115    ///
116    /// # Returns
117    ///
118    /// A tracked handle for observing or cancelling the scheduled task.
119    ///
120    /// # Errors
121    ///
122    /// Returns [`SubmissionError`] when the service refuses the task before
123    /// accepting it.
124    fn schedule_callable_at<C, R, E>(
125        &self,
126        instant: Instant,
127        task: C,
128    ) -> Result<Self::TrackedHandle<R, E>, SubmissionError>
129    where
130        C: Callable<R, E> + Send + 'static,
131        R: Send + 'static,
132        E: Send + 'static;
133}