auralis_task/lib.rs
1//! auralis-task: Scoped async task runtime with explicit [`TaskScope`]
2//! hierarchy, iterative cancellation, and priority scheduling.
3//!
4//! # Architecture
5//!
6//! - **Global executor** — a [`thread_local!`] singleton with
7//! high- and low-priority queues.
8//! - **`TaskScope`** — owns spawned futures; dropping a scope cancels
9//! all descendant scopes and their tasks **iteratively** (no
10//! recursion), preventing stack overflows in deeply nested UI trees.
11//! - **`set_deferred`** — safe signal mutation from [`Drop`] contexts.
12//! - **Pluggable storage** — [`ScopeStore`] and [`Executor::new_instance`]
13//! enable multi-request isolation for SSR or multi-threaded runtimes.
14//! - **Diagnostics** — `dump_reactive_graph()` (behind the `debug`
15//! feature) provides a unified snapshot of all signals, memos, and
16//! tasks. [`TaskScope`] supports optional labels for diagnostic output.
17//!
18//! # Quick example
19//!
20//! ```
21//! use auralis_task::{TaskScope, spawn_global};
22//!
23//! let scope = TaskScope::new();
24//! scope.spawn(async { /* ... */ });
25//! ```
26//!
27//! # Design decisions
28//!
29//! The crate shares `auralis_signal`'s single-threaded-by-default
30//! philosophy (`Rc` over `Arc`, `RefCell` over `Mutex`). For
31//! multi-threaded use-cases, create an isolated [`Executor`] instance
32//! per thread or per request. See the repository design docs for the
33//! full rationale.
34
35#![forbid(unsafe_code)]
36#![warn(missing_docs, clippy::all, clippy::pedantic)]
37#![allow(clippy::module_name_repetitions)]
38
39mod executor;
40mod scope;
41pub mod timer;
42
43#[cfg(feature = "debug")]
44mod debug;
45
46#[cfg(feature = "debug")]
47pub use debug::{dump_reactive_graph, dump_task_tree};
48pub use executor::{
49 init_flush_scheduler, init_time_source, remove_panic_hook, reset_executor_for_test,
50 schedule_callback, set_deferred, set_global_max_deferred_callbacks, set_global_time_budget,
51 set_panic_hook, spawn_global, spawn_global_with_priority, with_executor, yield_now, Executor,
52 PanicInfo, ScheduleFlush, TimeSource, YieldNow,
53};
54#[cfg(test)]
55pub use executor::{TestScheduleFlush, TestTimeSource};
56#[cfg(feature = "debug")]
57pub use scope::scope_debug_label;
58pub use scope::{
59 clear_scope_registry, current_scope, find_scope, set_scope_store, with_current_scope,
60 CallbackHandle, JoinHandle, ScopeStore, TaskScope,
61};
62
63#[cfg(feature = "ssr-tokio")]
64pub use scope::init_scope_store_tokio;
65
66/// Task priority.
67///
68/// High-priority tasks are dequeued before low-priority ones within a
69/// single flush cycle.
70#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
71pub enum Priority {
72 /// Dequeued first during flush.
73 High,
74 /// Dequeued after all high-priority tasks.
75 Low,
76}