orb/lib.rs
1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![cfg_attr(docsrs, allow(unused_attributes))]
3#![doc = include_str!("../README.md")]
4
5//! ## Runtime Varieties Note
6//!
7//! ### Task Detach
8//!
9//! The drop behavior of task handle is unified to "detach", task will not be cancel unless
10//! [abort](AsyncJoiner::abort) is called.
11//!
12//! ### Panic
13//!
14//! - tokio will issolate panic between tasks, a task handle may return Err() on join.
15//! - smol will not issolate panic. Although a panic hook will work, the program might panic if one
16//! of the task panic. You may use feature `unwind` to enable panic capturing.
17//!
18//! ### thread local context
19//!
20//! When the first time enter block_on in `current()` runtime, or threaded worker spawn,
21//! we have maintain thread local ref for the runtime, so that you can use [AsyncRuntime::spawn()] static method directly.
22//! (Note that calling `AsyncRuntime::spawn()` from non-async context will panic (just like `tokio::spawn` behavior)
23//!
24//! ## Cloning the runtime
25//!
26//! [AsyncExec] is a cloneable runtime handle, can be initiated by [AsyncRuntime::current()], [AsyncRuntime::one()], [AsyncRuntime::multi()]
27
28pub mod io;
29pub mod net;
30pub mod runtime;
31pub mod time;
32pub mod utils;
33#[cfg(feature = "worker")]
34pub mod worker_pool;
35
36/// Re-export all the traits you need
37///
38/// This module contains all the essential traits needed to work with Orb.
39/// Importing this prelude is the recommended way to use Orb in your code.
40pub mod prelude {
41 pub use crate::AsyncRuntime;
42 pub use crate::io::{AsyncBufRead, AsyncBufWrite, AsyncFd, AsyncIO, AsyncRead, AsyncWrite};
43 pub use crate::net::AsyncListener;
44 pub use crate::runtime::{AsyncExec, AsyncJoiner, ThreadJoiner};
45 pub use crate::time::{AsyncTime, TimeInterval};
46 // Re-export the Stream trait so users can import it
47 pub use futures_lite::stream::Stream;
48 pub use futures_lite::stream::StreamExt;
49}
50
51use prelude::*;
52
53/// A marker trait that combines all the core async runtime capabilities,
54/// including [`AsyncIO`], and [`AsyncTime`]. It serves as a convenient
55/// way to specify that a type provides all the core async runtime functionality.
56///
57/// You can write your own trait by inheriting AsyncRuntime or any other trait, to provide extra
58/// functions along with the runtime object.
59/// There's an blanket trait to auto impl AsyncRuntime on anything that is `Deref<Target>` to an AsyncRuntime.
60pub trait AsyncRuntime: AsyncIO + AsyncTime + 'static + Send + Sync {
61 type Exec: AsyncExec;
62
63 /// Initiate executor using current thread.
64 ///
65 /// # Safety
66 ///
67 /// You should run [AsyncExec::block_on()] with this executor.
68 ///
69 /// If spawn without a `block_on()` running, it's possible
70 /// the runtime just init future without scheduling.
71 fn current() -> Self::Exec;
72
73 /// Initiate executor with one background thread.
74 ///
75 /// # NOTE
76 ///
77 /// [AsyncExec::block_on()] is optional, you can directly call [AsyncExec::spawn] with it.
78 fn one() -> Self::Exec;
79
80 /// Initiate executor with multiple background threads.
81 ///
82 /// # NOTE
83 ///
84 /// When `num` == 0, start threads that match cpu number.
85 ///
86 /// [AsyncExec::block_on()] is optional, you can directly call [AsyncExec::spawn] with it.
87 fn multi(num: usize) -> Self::Exec;
88
89 /// Spawn a task with Self::Exec in the thread context, returning a handle to await its result.
90 ///
91 /// This method creates a new task that runs concurrently with the current
92 /// task. The returned handle can be used to wait for the task's completion
93 /// and retrieve its result.
94 ///
95 /// # NOTE:
96 ///
97 /// The return AsyncJoiner adopts the behavior of tokio.
98 ///
99 /// The behavior of panic varies for runtimes:
100 /// - tokio will capture handle to task result,
101 /// - async-executor (smol) will not capture panic, the program will exit
102 ///
103 /// # Type Parameters
104 ///
105 /// * `F` - The future type to spawn
106 /// * `R` - The return type of the future
107 ///
108 /// # Parameters
109 ///
110 /// * `f` - The future to spawn
111 ///
112 /// # Returns
113 ///
114 /// A handle that implements [`AsyncJoiner`] and can be used to await
115 /// the task's result.
116 ///
117 /// # Panic
118 ///
119 /// Panic when not called in the runtime worker context.
120 fn spawn<F, R>(f: F) -> <Self::Exec as AsyncExec>::AsyncJoiner<R>
121 where
122 F: Future<Output = R> + Send + 'static,
123 R: Send + 'static;
124
125 /// Spawn a task with Self::Exec in the thread context, and detach it (no handle returned).
126 ///
127 /// This method creates a new task that runs in the background without
128 /// providing a way to wait for its completion. The task will continue
129 /// running until it completes or the program exits.
130 ///
131 /// # NOTE:
132 ///
133 /// The behavior of panic varies for runtimes:
134 /// - tokio will ignore other tasks panic after detached,
135 /// - async-executor (smol) will not capture panic by default, the program will exit. There's a
136 /// feature switch in [orb-smol](https://docs.rs/orb-smol) to change this behavior.
137 ///
138 /// # Type Parameters
139 ///
140 /// * `F` - The future type to spawn
141 /// * `R` - The return type of the future
142 ///
143 /// # Parameters
144 ///
145 /// * `f` - The future to spawn
146 ///
147 /// # Panic
148 ///
149 /// Panic when not called in the runtime worker context.
150 fn spawn_detach<F, R>(f: F)
151 where
152 F: Future<Output = R> + Send + 'static,
153 R: Send + 'static;
154
155 /// Run blocking code with the thread context in blocking thread pool,
156 /// and return an async join handle
157 ///
158 /// # NOTE:
159 ///
160 /// This method spawn with threal pool provide by runtime in current context, globally.
161 /// In order for ResolveAddr job which does not have a AsyncExec handle, so this method is static.
162 ///
163 /// # Type Parameters
164 ///
165 /// * `F` - The future type to spawn
166 /// * `R` - The return type of the future
167 ///
168 /// # Parameters
169 ///
170 /// * `f` - The future to spawn
171 ///
172 /// # Returns
173 ///
174 /// A handle that implements [`ThreadJoiner`] and can be used to await
175 /// the call result.
176 ///
177 /// # Panic
178 ///
179 /// Panic when not called in the runtime worker context.
180 fn spawn_blocking<F, R>(f: F) -> <Self::Exec as AsyncExec>::ThreadJoiner<R>
181 where
182 F: FnOnce() -> R + Send + 'static,
183 R: Send + 'static;
184}