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
// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Dependency-inversion trait for supervised blocking thread spawns.
//!
//! Crates that cannot depend on `zeph-core` (e.g. `zeph-index`) accept an
//! `Option<Arc<dyn BlockingSpawner>>` and fall back to raw
//! `tokio::task::spawn_blocking` when `None`. This breaks the cyclic
//! dependency that would otherwise arise from `zeph-index` importing
//! `TaskSupervisor` from `zeph-core`.
/// Trait for spawning CPU-bound work on a supervised blocking thread pool.
///
/// Implementors register each spawned task in their supervision layer so it
/// is visible to lifecycle management (snapshots, graceful shutdown, metrics).
/// Callers that do not have a supervised spawner may fall back to
/// `tokio::task::spawn_blocking` directly.
///
/// The trait is object-safe: it accepts a `Box<dyn FnOnce() + Send + 'static>`
/// and returns a `JoinHandle<()>`. Callers that need a typed return value
/// must communicate results through a channel or shared state.
///
/// # Examples
///
/// ```no_run
/// use std::sync::Arc;
/// use zeph_common::BlockingSpawner;
///
/// fn do_work(spawner: Arc<dyn BlockingSpawner>) {
/// let handle = spawner.spawn_blocking_named(Arc::from("my_task"), Box::new(|| {
/// // CPU-bound work
/// }));
/// // Caller can `.await` the handle.
/// let _ = handle;
/// }
/// ```