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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
// SPDX-License-Identifier: MIT OR Apache-2.0
//! A thread-pool executor for async Rust that runs the same code on OS threads natively
//! and on web workers on wasm32.
//!
//! 
//!
//! This crate is the reference executor for the [`some_executor`] framework: if you write
//! code against the [`SomeExecutor`] trait and want one real executor to run it
//! everywhere, this is it.
//!
//! # Why this crate exists
//!
//! Rust ships no async executor in std, and no trait for executors to implement, so most
//! async code is written directly against one specific runtime. The [`some_executor`]
//! crate fixes this by defining a small interface between the code that *has* futures and
//! the code that *runs* them: libraries spawn onto "some" executor through a trait, and
//! applications decide which executor that actually is.
//!
//! That framework needs a production-quality executor to point at, and this crate is it.
//! `some_global_executor` implements the [`SomeExecutor`] trait for `Send + 'static`
//! futures with a resizable pool of workers, and can install itself as the process-wide
//! global executor or as a per-thread executor — which is exactly what
//! [`some_executor`]'s `current_executor()` discovery hierarchy looks for. Out of the
//! box, [`some_executor`] falls back to a built-in toy executor that warns when used;
//! installing this crate is the intended way to replace it.
//!
//! # What it does
//!
//! - **One API, two platforms.** On native targets, tasks run on a pool of OS threads fed
//! by a `crossbeam-channel` queue. On wasm32, the same public API runs tasks on web
//! workers, with a custom async channel for distribution (workers can't block). The
//! platform switch is conditional compilation; your code doesn't change.
//! - **Task observation.** Spawning returns an observer from the [`some_executor`]
//! framework: await it for the result, poll it, detach it, or drop it to request
//! cooperative cancellation.
//! - **Graceful shutdown.** [`Executor::drain`] blocks until every spawned task has
//! finished; [`Executor::drain_async`] is the awaitable version for async contexts.
//! - **Runtime resizing.** [`Executor::resize`] grows or shrinks the worker pool while
//! the executor is running.
//! - **Structured logging.** Internal operations are logged through
//! [`logwise`](https://github.com/drewcrawford/logwise), with optional diagnostic,
//! forensic, and performance feature flags. An optional `exfiltrate` feature exposes a
//! registry of live pools for external debugging tools.
//!
//! # Quick start
//!
//! ```
//! use some_global_executor::Executor;
//! use some_executor::SomeExecutor;
//! use some_executor::task::{Task, Configuration};
//! # if cfg!(target_arch = "wasm32") { return; }
//!
//! // A named pool with 4 worker threads (or web workers on wasm32).
//! let mut executor = Executor::new("my-executor".to_string(), 4);
//!
//! let task = Task::without_notifications(
//! "example-task".to_string(),
//! Configuration::default(),
//! async { 42 }
//! );
//!
//! let observer = executor.spawn(task);
//! // Await the observer for the result, or drop it to cancel the task.
//!
//! // Optionally make this the executor that some_executor's
//! // current_executor() / global spawning resolves to:
//! executor.set_as_global_executor();
//!
//! // Block until all spawned tasks finish.
//! executor.drain();
//! ```
//!
//! # Where it fits in the ecosystem
//!
//! The [`some_executor`] family divides the work like this:
//!
//! - [`some_executor`] — the trait layer. Defines [`Task`],
//! observers, cancellation, priorities, task-locals, and the global/thread-local
//! executor registry. No real scheduling of its own beyond a fallback.
//! - **`some_global_executor`** (this crate) — the reference executor for `Send` tasks:
//! a thread pool natively, web workers on wasm32.
//! - [`some_local_executor`](https://github.com/drewcrawford/some_local_executor) — runs
//! non-`Send` tasks on the current thread, and can receive tasks from other threads.
//! - [`test_executors`](https://github.com/drewcrawford/test_executors) — toy executors
//! for unit tests.
//!
//! So: libraries depend on [`some_executor`] and stay executor-agnostic; applications
//! depend on this crate (or another implementation) and install it once at startup.
//!
//! # Alternatives
//!
//! If you aren't committed to the [`some_executor`] interface, the field looks like this:
//!
//! | Crate | What it is | Trade-off vs. this crate |
//! |---|---|---|
//! | [tokio](https://crates.io/crates/tokio) | Full runtime: executor plus async I/O, timers, sync primitives, and a huge ecosystem | The default choice if you need its I/O stack — but your code becomes tokio-specific, and there is no multithreaded wasm32 story. This crate is executor-only and trait-first. |
//! | [async-executor](https://crates.io/crates/async-executor) (smol) | Small, composable executor; bring your own reactor | Closest in spirit (executor without a bundled runtime), but no common spawning trait for libraries, no observer/cancellation model, and no web-worker pool on wasm32. |
//! | [futures-executor](https://crates.io/crates/futures-executor) | The minimal `ThreadPool`/`LocalPool` in the futures crate | Fine for gluing a future into sync code; no task metadata, draining, resizing, or wasm parallelism. |
//! | [wasm-bindgen-futures](https://crates.io/crates/wasm-bindgen-futures) | `spawn_local` onto the browser event loop | The standard wasm answer, but single-threaded and wasm-only. This crate gives you actual parallelism via web workers and the same API natively. |
//! | [rayon](https://crates.io/crates/rayon) | Data-parallelism for synchronous code | Not an async executor at all; complementary rather than competing. |
//! | async-std | Formerly a full alternative runtime | Discontinued (deprecated in 2025); its maintainers point to smol. |
//! | [`some_executor`]'s built-in fallback | Zero-config executor included in the trait crate | Always available so libraries work with no setup, but deliberately not production quality — it exists to be replaced by this crate. |
//!
//! Pick this crate when you want executor-agnostic code (or already have it via
//! [`some_executor`]), need the same spawning code to work natively and on wasm32 with
//! real parallelism, and don't need a bundled I/O reactor. Pick tokio when you're
//! building on its networking stack and wasm isn't a target.
//!
//! # More examples
//!
//! ## Observing task progress
//!
//! Tasks can be observed to monitor their execution state:
//!
//! ```
//! use some_global_executor::Executor;
//! use some_executor::SomeExecutor;
//! use some_executor::task::{Task, Configuration};
//! use some_executor::observer::{Observer, Observation};
//! # if cfg!(target_arch = "wasm32") { return; }
//!
//! let mut executor = Executor::new("observer-example".to_string(), 2);
//!
//! let task = Task::without_notifications(
//! "monitored-task".to_string(),
//! Configuration::default(),
//! async { "result" }
//! );
//!
//! let observer = executor.spawn(task);
//!
//! // Poll the observer to check task state
//! loop {
//! match observer.observe() {
//! Observation::Ready(value) => {
//! println!("Task completed with: {}", value);
//! break;
//! }
//! Observation::Pending => {
//! // Task still running
//! std::thread::yield_now();
//! }
//! _ => break,
//! }
//! }
//!
//! executor.drain();
//! ```
//!
//! ## Global executor pattern
//!
//! Set an executor as the global default for the application:
//!
//! ```
//! use some_global_executor::Executor;
//! # if cfg!(target_arch = "wasm32") { return; }
//!
//! // Create and configure the global executor
//! let executor = Executor::new("global".to_string(), num_cpus::get());
//! executor.set_as_global_executor();
//!
//! // Now tasks can be spawned using the global executor from anywhere
//! // in the application without passing executor references
//!
//! # executor.drain();
//! ```
//!
//! ## Dynamic thread pool management
//!
//! Adjust executor capacity based on workload:
//!
//! ```
//! use some_global_executor::Executor;
//!
//! let mut executor = Executor::new("dynamic".to_string(), 2);
//!
//! // Scale up for heavy workload
//! executor.resize(8);
//!
//! // Scale down during idle periods
//! executor.resize(2);
//!
//! executor.drain();
//! ```
//!
//! # Performance considerations
//!
//! - Thread pool sizing: Default to `num_cpus::get()` for CPU-bound work
//! - For I/O-bound tasks, consider using more threads than CPU cores
//! - WASM targets have platform-specific limitations on parallelism
//! - Use `drain_async()` in async contexts to avoid blocking
//!
//! # Logging
//!
//! This crate uses the `logwise` framework for structured logging. Internal operations
//! are logged at various levels for debugging and monitoring:
//!
//! ```
//! # use some_global_executor::Executor;
//! // Executor creation and operations are automatically logged
//! let executor = Executor::new("logged-executor".to_string(), 4);
//! // Logs: "Creating executor with name logged-executor and 4 threads"
//! # executor.drain();
//! ```
//!
//! # Requirements
//!
//! Rust 1.95+ (edition 2024). Native targets need only stable Rust; running the wasm32
//! test suite requires nightly.
use DynExecutor;
use SomeExecutor;
use ;
use ;
use Any;
use Infallible;
use Future;
use Hash;
use Pin;
use AtomicUsize;
/// re-exports the `SomeExecutor` crate for convenience.
pub use some_executor;
/// A thread pool-based executor for running asynchronous tasks.
///
/// The `Executor` manages a pool of worker threads that execute submitted tasks.
/// It provides both synchronous and asynchronous draining capabilities, allowing
/// you to wait for all tasks to complete before shutdown.
///
/// # Platform Support
///
/// This executor automatically adapts to the target platform:
/// - On standard platforms, it uses OS threads via `crossbeam-channel`
/// - On WASM targets, it uses web workers for parallelism
///
/// # Examples
///
/// ```
/// use some_global_executor::Executor;
///
/// // Create an executor named "worker-pool" with 4 threads
/// let executor = Executor::new("worker-pool".to_string(), 4);
///
/// // Get the executor's name
/// assert_eq!(executor.name(), "worker-pool");
///
/// // Clean up when done
/// executor.drain();
/// ```
/// A future that completes when all tasks in an executor have finished.
///
/// `ExecutorDrain` is returned by [`Executor::drain_async()`] and implements
/// `Future<Output = ()>`. It polls the executor's internal state to determine
/// when all tasks have completed execution.
///
/// # Examples
///
/// ```
/// # // This example shows async draining but requires an async runtime
/// # // which is not available in doctests, so we use synchronous drain
/// use some_global_executor::Executor;
/// use some_executor::SomeExecutor;
/// use some_executor::task::{Task, Configuration};
/// # if cfg!(target_arch = "wasm32") { return; }
///
/// let mut executor = Executor::new("async-drain".to_string(), 2);
///
/// // Spawn some work
/// let task = Task::without_notifications(
/// "work".to_string(),
/// Configuration::default(),
/// async {
/// // Simulate some work
/// 42
/// }
/// );
/// executor.spawn(task);
///
/// // In async context, you would use:
/// // executor.drain_async().await;
/// // Here we use synchronous drain for the example
/// executor.drain();
/// ```
pub use DrainNotify;
pub use ExecutorDrain;
/// Platform-specific executor implementations
/// Waker implementation for task notification
/// Internal representation of a spawned task.
///
/// Wraps the platform-specific task implementation and provides
/// a uniform interface for task management across different platforms.
/// Implementation of the [`SomeExecutor`] trait from the `some_executor` framework.
///
/// This implementation provides the core task spawning functionality, supporting
/// both synchronous and asynchronous task submission with type-safe observers
/// for monitoring task execution.
// Conversion implementations for ergonomic API usage