mssf_core/runtime/executor.rs
1// ------------------------------------------------------------
2// Copyright (c) Microsoft Corporation. All rights reserved.
3// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4// ------------------------------------------------------------
5
6use std::{fmt::Debug, future::Future, pin::Pin};
7
8// Executor is used by rs to post jobs to execute in the background
9// Sync is needed due to we use the executor across await boundary.
10pub trait Executor: Clone + Sync + Send + 'static {
11 // Required functions
12
13 /// spawns the task to run in background.
14 /// This is primarily used by mssf Bridge to execute user app async callbacks/notifications.
15 fn spawn<F>(&self, future: F)
16 where
17 F: Future + Send + 'static,
18 F::Output: Send;
19
20 /// Runs the provided function on an executor dedicated to blocking
21 /// operations.
22 fn spawn_blocking<F, R>(&self, func: F)
23 where
24 F: FnOnce() -> R + Send + 'static,
25 R: Send + 'static;
26}
27
28/// Runtime independent sleep trait.
29pub trait Timer: Send + Sync + 'static {
30 /// Returns a future that is ready after duration.
31 fn sleep(&self, duration: std::time::Duration) -> Pin<Box<dyn EventFuture>>;
32}
33
34/// Runtime independent event future.
35pub trait EventFuture: Send + Future<Output = ()> {}
36
37impl<T> EventFuture for T where T: Future<Output = ()> + Send {}
38
39pub trait CancelToken: Send + Sync + 'static {
40 /// Get a future to wait for cancellation.
41 fn wait(&self) -> Pin<Box<dyn EventFuture>>;
42
43 /// Is the token cancelled
44 fn is_cancelled(&self) -> bool;
45
46 /// Cancel the token.
47 fn cancel(&self);
48
49 /// Register a callback to be invoked when this token is cancelled.
50 /// If this token is already cancelled, the callback is invoked immediately.
51 ///
52 /// # Panics (debug builds only)
53 /// Panics if a callback has already been registered.
54 fn on_cancel(&self, callback: Box<dyn FnOnce() + Send + Sync>);
55
56 /// Clone the cancel token.
57 /// Because the dyn requirement, CancelToken cannot be cloned directly.
58 fn clone_box(&self) -> Box<dyn CancelToken>;
59}
60
61pub type BoxedCancelToken = Box<dyn CancelToken>;
62
63impl Clone for BoxedCancelToken {
64 fn clone(&self) -> Self {
65 self.clone_box()
66 }
67}
68
69impl Debug for dyn CancelToken {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 f.debug_struct("CancelToken")
72 .field("cancelled", &self.is_cancelled())
73 .finish()
74 }
75}