1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Provides access to the current executor in various contexts.
//!
//! This module implements the executor discovery mechanism that allows async code
//! to spawn tasks without explicitly passing an executor reference.
use crateDynExecutor;
/// Retrieves the executor associated with the current task, if any.
///
/// This function checks if the current code is running within a task context
/// and whether that task has an associated executor.
///
/// # Returns
///
/// - `Some(executor)` if running within a task that has an associated executor
/// - `None` if not running within a task, or if the task has no associated executor
///
/// # Implementation Details
///
/// This accesses the task-local `TASK_EXECUTOR` variable which is set when a task
/// is polled with an executor context.
/// Accesses the current executor using a hierarchical discovery mechanism.
///
/// This function provides a convenient way to obtain an executor without explicitly
/// passing one through function parameters. It searches for an executor in the
/// following order:
///
/// 1. **Task executor**: If the current code is running within a task that has
/// an associated executor, that executor is returned.
/// 2. **Thread executor**: If the current thread has a thread-local executor set,
/// that executor is returned.
/// 3. **Global executor**: If a global executor has been configured for the
/// application, that executor is returned.
/// 4. **Last resort executor**: A built-in fallback executor is returned. This
/// executor provides basic functionality but may not be optimal for production use.
///
/// # Returns
///
/// Always returns a boxed executor. The function is guaranteed to return an executor,
/// falling back to the last resort executor if no other executor is available.
///
/// # Examples
///
/// ```
/// use some_executor::current_executor::current_executor;
/// use some_executor::SomeExecutor;
/// use some_executor::task::{Task, Configuration};
/// use crate::some_executor::observer::Observer;
///
/// # async fn example() {
/// // Get the current executor
/// let mut executor = current_executor();
///
/// // Use it to spawn a task
/// let task = Task::without_notifications(
/// "example task".to_string(),
/// Configuration::default(),
/// async {
/// println!("Hello from spawned task");
/// },
/// );
///
/// let _observer = executor.spawn(task).detach();
/// # }
/// ```
///
/// # Performance Considerations
///
/// Each call to this function performs the full discovery process. If you need
/// to spawn multiple tasks, consider storing the executor in a variable rather
/// than calling this function repeatedly.
///
/// ```
/// use some_executor::current_executor::current_executor;
/// use some_executor::SomeExecutor;
/// use some_executor::task::{Task, Configuration};
/// use crate::some_executor::observer::Observer;
///
/// # async fn spawn_many_tasks() {
/// // Good: Store the executor
/// let mut executor = current_executor();
/// for i in 0..100 {
/// let task = Task::without_notifications(
/// format!("task-{}", i),
/// Configuration::default(),
/// async move {
/// println!("Task {}", i);
/// },
/// );
/// executor.spawn(task);
/// }
///
/// // Less efficient: Repeated discovery
/// for i in 0..100 {
/// let mut executor = current_executor(); // Performs discovery each time
/// let task = Task::without_notifications(
/// format!("task-{}", i),
/// Configuration::default(),
/// async move {
/// println!("Task {}", i);
/// },
/// );
/// executor.spawn(task).detach();
/// }
/// # }
/// ```
///
/// # Last Resort Executor
///
/// The last resort executor is a simple, built-in executor that ensures async code
/// can always make progress. However, it may not be optimal for production use as
/// it lacks advanced features like work stealing, priority scheduling, or
/// sophisticated thread management. It's recommended to configure a proper executor
/// for production applications.