29
29
//! ```
30
30
//!
31
31
//!
32
- use std:: { fmt:: Debug , future:: Future , pin:: Pin , sync:: Arc } ;
32
+ use std:: {
33
+ fmt:: Debug ,
34
+ future:: Future ,
35
+ pin:: Pin ,
36
+ sync:: { Arc , OnceLock } ,
37
+ } ;
33
38
34
- mod standard_spawn ;
39
+ mod standard_runtime ;
35
40
36
41
#[ cfg( feature = "tokio" ) ]
37
- mod tokio_spawn ;
42
+ mod tokio_runtime ;
38
43
39
44
#[ cfg( test) ]
40
45
mod tests;
@@ -61,9 +66,11 @@ pub type SpawnedTask = Pin<
61
66
pub type SpawnedTask =
62
67
Pin < Box < dyn Future < Output = std:: result:: Result < ( ) , Box < dyn std:: error:: Error > > > + ' static > > ;
63
68
64
- /// An async command runner .
69
+ /// An Asynchronous Runtime .
65
70
///
66
- pub trait TaskSpawner : Send + Sync + Debug {
71
+ /// This trait defines the various
72
+ ///
73
+ pub trait AsyncRuntime : Send + Sync + Debug {
67
74
/// Spawn a task that executes a given future and returns the output.
68
75
///
69
76
/// # Arguments
@@ -76,13 +83,13 @@ pub trait TaskSpawner: Send + Sync + Debug {
76
83
///
77
84
/// # Example
78
85
/// ```
79
- /// use azure_core::task ::{new_task_spawner , TaskSpawner};
86
+ /// use azure_core::async_runtime ::{get_async_runtime , TaskSpawner};
80
87
/// use futures::FutureExt;
81
88
///
82
89
/// #[tokio::main]
83
90
/// async fn main() {
84
- /// let spawner = new_task_spawner ();
85
- /// let future = spawner .spawn(async {
91
+ /// let async_runtime = get_async_runtime ();
92
+ /// let future = async_runtime .spawn(async {
86
93
/// // Simulate some work
87
94
/// std::thread::sleep(std::time::Duration::from_secs(1));
88
95
/// }.boxed());
@@ -99,41 +106,86 @@ pub trait TaskSpawner: Send + Sync + Debug {
99
106
/// that can be awaited.
100
107
///
101
108
fn spawn ( & self , f : TaskFuture ) -> SpawnedTask ;
109
+
110
+ fn sleep ( & self , duration : std:: time:: Duration ) -> TaskFuture ;
102
111
}
103
112
104
- /// Creates a new [`TaskSpawner`] to enable running tasks asynchronously.
113
+ static ASYNC_RUNTIME_IMPLEMENTATION : OnceLock < Arc < dyn AsyncRuntime > > = OnceLock :: new ( ) ;
114
+
115
+ /// Returns an [`AsyncRuntime`] to enable running operations which need to interact with an
116
+ /// asynchronous runtime.
105
117
///
106
118
///
107
119
/// The implementation depends on the target architecture and the features enabled:
108
- /// - If the `tokio` feature is enabled, it uses a tokio based spawner.
109
- /// - If the `tokio` feature is not enabled and the target architecture is not `wasm32`, it uses a std::thread based spawner.
120
+ /// - If the `tokio` feature is enabled, it uses a tokio based spawner and timer .
121
+ /// - If the `tokio` feature is not enabled and the target architecture is not `wasm32`, it uses a std::thread based spawner and timer .
110
122
///
111
123
/// # Returns
112
- /// A new instance of a [`TaskSpawner `] which can be used to spawn background tasks.
124
+ /// A new instance of a [`AsyncRuntime `] which can be used to spawn background tasks.
113
125
///
114
126
/// # Example
115
127
///
116
128
/// ```
117
- /// use azure_core::task::{new_task_spawner, TaskSpawner} ;
129
+ /// use azure_core::get_async_runtime ;
118
130
/// use futures::FutureExt;
119
131
///
120
132
/// #[tokio::main]
121
133
/// async fn main() {
122
- /// let spawner = new_task_spawner();
123
- /// let handle = spawner.spawn(async {
134
+ /// let async_runtime = get_async_runtime();
135
+ /// let handle = async_runtime.spawn(async {
136
+ /// // Simulate some work
137
+ /// std::thread::sleep(std::time::Duration::from_secs(1));
138
+ /// }.boxed());
139
+ /// }
140
+ /// ```
141
+ ///
142
+ pub fn get_async_runtime ( ) -> Arc < dyn AsyncRuntime > {
143
+ ASYNC_RUNTIME_IMPLEMENTATION
144
+ . get_or_init ( || create_async_runtime ( ) )
145
+ . clone ( )
146
+ }
147
+
148
+ /// Sets the current [`AsyncRuntime`] to enable running operations which need to interact with an
149
+ /// asynchronous runtime.
150
+ ///
151
+ ///
152
+ /// # Returns
153
+ /// Ok if the async runtime was set successfully, or an error if it has already been set.
154
+ ///
155
+ /// # Example
156
+ ///
157
+ /// ```
158
+ /// use azure_core::async_runtime::{get_async_runtime, AsyncRuntime};
159
+ /// use futures::FutureExt;
160
+ ///
161
+ /// async fn main() {
162
+ /// let async_runtime = set_async_runtime();
163
+ /// let handle = async_runtime.spawn(async {
124
164
/// // Simulate some work
125
165
/// std::thread::sleep(std::time::Duration::from_secs(1));
126
166
/// }.boxed());
127
167
/// }
128
168
/// ```
129
169
///
130
- pub fn new_task_spawner ( ) -> Arc < dyn TaskSpawner > {
170
+ pub fn set_async_runtime ( runtime : Arc < dyn AsyncRuntime > ) -> crate :: Result < ( ) > {
171
+ let result = ASYNC_RUNTIME_IMPLEMENTATION . set ( runtime) ;
172
+ if result. is_err ( ) {
173
+ Err ( crate :: Error :: message (
174
+ crate :: error:: ErrorKind :: Other ,
175
+ "Async runtime has already been set." ,
176
+ ) )
177
+ } else {
178
+ Ok ( ( ) )
179
+ }
180
+ }
181
+
182
+ fn create_async_runtime ( ) -> Arc < dyn AsyncRuntime > {
131
183
#[ cfg( not( feature = "tokio" ) ) ]
132
184
{
133
- Arc :: new ( standard_spawn :: StdSpawner )
185
+ Arc :: new ( standard_runtime :: StdRuntime )
134
186
}
135
187
#[ cfg( feature = "tokio" ) ]
136
188
{
137
- Arc :: new ( tokio_spawn :: TokioSpawner ) as Arc < dyn TaskSpawner >
189
+ Arc :: new ( tokio_runtime :: TokioRuntime ) as Arc < dyn AsyncRuntime >
138
190
}
139
191
}
0 commit comments