Start every worker thread through the executors module

Thirty-nine spawn sites in dr-ui, and one in the Android entry point,
called std::thread::spawn or a Builder of their own, and most of the
threads they started were <unnamed> in a panic message or a profiler.
Each now calls executors::spawn with its executor and a role, so the thread is
named <executor>:<role> — net:sync, decode:thumbs, io:catalog-open —
and knows which executor it is on. The three that already set a name
(automation, import, prefetch) keep their name as the role.

Behaviour is unchanged: each job still gets a thread of its own when it
starts, and spawn panics where std::thread::spawn did.

The module's documentation now says how a job is assigned: by what it
spends its time on, so a sweep that fetches bytes and then decodes them
is Decode, and a sidecar write that touches the catalog is Network.

Left as they were: the segmentation and refine workers in masks_ui.rs,
which another change is reworking, and test-only threads.
This commit is contained in:
2026-09-27 07:08:37 -04:00
parent 7be1efff32
commit b1d1c47261
24 changed files with 87 additions and 63 deletions
+9 -8
View File
@@ -2,6 +2,7 @@
//! cache, dehydration, and the prefetcher that keeps the grid ahead of
//! scrolling.
use crate::executors::{self, Executor};
use crate::sidecar_cache::SidecarCache;
use dr_catalog::Catalog;
#[cfg(test)]
@@ -136,7 +137,7 @@ pub fn spawn_pin_fetch(
) -> Receiver<PinMessage> {
let (tx, rx) = std::sync::mpsc::channel();
std::thread::spawn(move || {
executors::spawn(Executor::Network, "pin", move || {
let (store, catalog) = match (
dr_catalog::Cache::open(&cache_dir, budget),
Catalog::open(&catalog_path),
@@ -324,7 +325,7 @@ pub fn spawn_dehydrate(
) -> Receiver<usize> {
let (tx, rx) = std::sync::mpsc::channel();
std::thread::spawn(move || {
executors::spawn(Executor::Network, "dehydrate", move || {
let Ok(catalog) = Catalog::open(&catalog_path) else {
return;
};
@@ -442,7 +443,7 @@ pub fn spawn_sidecar_fetch(
) -> Receiver<Option<dr_pipeline::Sidecar>> {
let (tx, rx) = std::sync::mpsc::channel();
std::thread::spawn(move || {
executors::spawn(Executor::Network, "sidecars", move || {
let cache = SidecarCache::open(cache_dir);
let path_str = sidecar_path(&image_path);
@@ -565,7 +566,7 @@ pub fn spawn_full_fetch(
cache: Option<CacheContext>,
) -> Receiver<Result<Vec<u8>, FetchFailure>> {
let (tx, rx) = std::sync::mpsc::channel();
std::thread::spawn(move || {
executors::spawn(Executor::Network, "fetch", move || {
let _ = tx.send(fetch_original(conn, &path, cache.as_ref()));
});
rx
@@ -845,10 +846,10 @@ impl Prefetcher {
let shared = std::sync::Arc::new(PrefetchShared::default());
let (tx, events) = std::sync::mpsc::channel();
let worker = shared.clone();
std::thread::Builder::new()
.name("prefetch".into())
.spawn(move || serve_prefetches(&worker, &tx))
.expect("spawning the prefetch worker");
executors::try_spawn(Executor::Network, "prefetch", move || {
serve_prefetches(&worker, &tx)
})
.expect("spawning the prefetch worker");
Self { shared, events }
}