retrace/spawner.rs
1/// The default task spawner used by Retrace if the parameter is omitted.
2///
3/// This is currently [`NativeSpawner`] if `feature = "std"` is enabled, or
4/// [`DropSpawner`] if not.
5#[cfg(feature = "std")]
6pub type DefaultSpawner = NativeSpawner;
7
8/// The default task spawner used by Retrace if the parameter is omitted.
9///
10/// This is currently [`NativeSpawner`] if `feature = "std"` is enabled, or
11/// [`DropSpawner`] if not.
12#[cfg(not(feature = "std"))]
13pub type DefaultSpawner = DropSpawner;
14
15/// Trait for any spawner that supports spawning an unsupervised background task.
16///
17/// Retrace only uses the spawner for non-essential tasks. It does not depend on the
18/// closures actually being run to function as expected. See [`DropSpawner`] for a spawner
19/// that simply drops everything passed to it.
20///
21/// The default spawner is available as the type alias [`DefaultSpawner`].
22pub trait Spawner: 'static + Send + Sync {
23 /// Spawns the task `f` on another thread
24 fn spawn<F>(&self, f: F)
25 where
26 F: 'static + FnOnce() + Send;
27}
28
29#[cfg(feature = "std")]
30pub use native_spawner::NativeSpawner;
31
32#[cfg(feature = "std")]
33mod native_spawner {
34 use super::Spawner;
35
36 /// A task spawner that delegates to [`std::thread::spawn`].
37 #[derive(Clone, Copy, Debug, Default)]
38 pub struct NativeSpawner {
39 _private: (),
40 }
41
42 impl Spawner for NativeSpawner {
43 fn spawn<F>(&self, f: F)
44 where
45 F: 'static + FnOnce() + Send,
46 {
47 std::thread::spawn(f);
48 }
49 }
50}
51
52/// A task "spawner" that simply drops the closure.
53///
54/// This can be used to disable all background tasks, when they are undesirable or if an actual
55/// spawner is unavailable.
56#[derive(Clone, Copy, Debug, Default)]
57pub struct DropSpawner {
58 _private: (),
59}
60
61impl Spawner for DropSpawner {
62 fn spawn<F>(&self, _f: F)
63 where
64 F: 'static + FnOnce() + Send,
65 {
66 }
67}
68
69/// A task spawner that invokes the closure immediately on the current thread. This is usually a
70/// *very bad idea* except in tests, where its deterministic behavior can be helpful.
71#[derive(Clone, Copy, Debug, Default)]
72pub struct ImmediateSpawner {
73 _private: (),
74}
75
76impl Spawner for ImmediateSpawner {
77 fn spawn<F>(&self, f: F)
78 where
79 F: 'static + FnOnce() + Send,
80 {
81 f();
82 }
83}