The app shall define distinct executors — UI, GPU submission, decode pool, I/O pool, network — with stated thread counts and the invariant that no blocking call occurs on the UI executor. What exists is one tokio runtime for network workers (ui/dr-ui/src/net_runtime.rs), a job runner in dr-catalog, and rayon wherever a crate reached for it; nothing states the set or the counts, and the only mention of NFR-ARCH-1 in source is a comment.
Why
R4 and NFR-P9 assert an outcome — the UI never blocks — with no stated means. The face sweep, the thumbnail sweep, the segmentation pass and sync all compete for the same cores today with no priority between them, which is the case NFR-ARCH-2 says makes NFR-P5's slider latency fail during a batch.
Deliverable
One module that constructs the executors, names them, and states each thread count with the reason (docs/architecture.md §7.1 is where the design says they live).
Every spawn, ThreadPoolBuilder and block_on in ui/ and core/ routed through it.
A debug assertion or lint that a blocking call — block_on, a sync file read, a catalog query — on the UI thread fails a test.
Acceptance
The executor set and counts are stated in one place and in architecture.md §7.1
A test fails when block_on is called on the UI executor
TRACES: NFR-ARCH-1 on the module; NFR-P9 gains a tag on the assertion
**The app shall define distinct executors — UI, GPU submission, decode pool, I/O pool, network — with stated thread counts and the invariant that no blocking call occurs on the UI executor.** What exists is one tokio runtime for network workers (`ui/dr-ui/src/net_runtime.rs`), a job runner in `dr-catalog`, and rayon wherever a crate reached for it; nothing states the set or the counts, and the only mention of NFR-ARCH-1 in source is a comment.
## Why
R4 and NFR-P9 assert an outcome — the UI never blocks — with no stated means. The face sweep, the thumbnail sweep, the segmentation pass and sync all compete for the same cores today with no priority between them, which is the case NFR-ARCH-2 says makes NFR-P5's slider latency fail during a batch.
## Deliverable
- One module that constructs the executors, names them, and states each thread count with the reason (`docs/architecture.md` §7.1 is where the design says they live).
- Every `spawn`, `ThreadPoolBuilder` and `block_on` in `ui/` and `core/` routed through it.
- A debug assertion or lint that a blocking call — `block_on`, a sync file read, a catalog query — on the UI thread fails a test.
## Acceptance
- [ ] The executor set and counts are stated in one place and in architecture.md §7.1
- [ ] A test fails when `block_on` is called on the UI executor
- [ ] `TRACES: NFR-ARCH-1` on the module; NFR-P9 gains a tag on the assertion
Progress check (2026-09-24). Only the docs half of item 1 is met, and it predates the issue: architecture.md §7.1 states the executors and their counts (UI 1, GPU submit 1, Decode cores−2, I/O 4, Network 2; 82a5e21).
Still to do: no code module constructs or names the executors (net_runtime.rs is the only runtime), no test fails on a UI-thread block_on, no TRACES: NFR-ARCH-1.
Progress check (2026-09-24). Only the docs half of item 1 is met, and it predates the issue: `architecture.md §7.1` states the executors and their counts (UI 1, GPU submit 1, Decode cores−2, I/O 4, Network 2; 82a5e21).
Still to do: no code module constructs or names the executors (`net_runtime.rs` is the only runtime), no test fails on a UI-thread `block_on`, no `TRACES: NFR-ARCH-1`.
Shipped in v0.18.2 (7be1efff, b1d1c472, 3912bc0d, 8df3dda9): ui/dr-ui/src/executors.rs names the five executors of architecture §7.1 (ui, gpu, decode, io, net) with their stated counts, and 40 worker-thread spawn sites start through it, named <executor>:<role>. A block_on on the UI thread panics in debug builds (assert_not_ui in the net runtime), with a test for the UI thread and one for a worker; an app run with the guard on never tripped it. TRACES: NFR-ARCH-1. Not done, and recorded in the register's status note: the counts are stated, not enforced (that needs pooling); the guard covers block_on, not synchronous file or catalog reads; the two mask worker threads were left alone while the mask code was being reworked.
Shipped in v0.18.2 (7be1efff, b1d1c472, 3912bc0d, 8df3dda9): `ui/dr-ui/src/executors.rs` names the five executors of architecture §7.1 (ui, gpu, decode, io, net) with their stated counts, and 40 worker-thread spawn sites start through it, named `<executor>:<role>`. A `block_on` on the UI thread panics in debug builds (`assert_not_ui` in the net runtime), with a test for the UI thread and one for a worker; an app run with the guard on never tripped it. TRACES: NFR-ARCH-1. Not done, and recorded in the register's status note: the counts are stated, not enforced (that needs pooling); the guard covers `block_on`, not synchronous file or catalog reads; the two mask worker threads were left alone while the mask code was being reworked.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The app shall define distinct executors — UI, GPU submission, decode pool, I/O pool, network — with stated thread counts and the invariant that no blocking call occurs on the UI executor. What exists is one tokio runtime for network workers (
ui/dr-ui/src/net_runtime.rs), a job runner indr-catalog, and rayon wherever a crate reached for it; nothing states the set or the counts, and the only mention of NFR-ARCH-1 in source is a comment.Why
R4 and NFR-P9 assert an outcome — the UI never blocks — with no stated means. The face sweep, the thumbnail sweep, the segmentation pass and sync all compete for the same cores today with no priority between them, which is the case NFR-ARCH-2 says makes NFR-P5's slider latency fail during a batch.
Deliverable
docs/architecture.md§7.1 is where the design says they live).spawn,ThreadPoolBuilderandblock_oninui/andcore/routed through it.block_on, a sync file read, a catalog query — on the UI thread fails a test.Acceptance
block_onis called on the UI executorTRACES: NFR-ARCH-1on the module; NFR-P9 gains a tag on the assertionProgress check (2026-09-24). Only the docs half of item 1 is met, and it predates the issue:
architecture.md §7.1states the executors and their counts (UI 1, GPU submit 1, Decode cores−2, I/O 4, Network 2;82a5e21).Still to do: no code module constructs or names the executors (
net_runtime.rsis the only runtime), no test fails on a UI-threadblock_on, noTRACES: NFR-ARCH-1.Shipped in v0.18.2 (
7be1efff,b1d1c472,3912bc0d,8df3dda9):ui/dr-ui/src/executors.rsnames the five executors of architecture §7.1 (ui, gpu, decode, io, net) with their stated counts, and 40 worker-thread spawn sites start through it, named<executor>:<role>. Ablock_onon the UI thread panics in debug builds (assert_not_uiin the net runtime), with a test for the UI thread and one for a worker; an app run with the guard on never tripped it. TRACES: NFR-ARCH-1. Not done, and recorded in the register's status note: the counts are stated, not enforced (that needs pooling); the guard coversblock_on, not synchronous file or catalog reads; the two mask worker threads were left alone while the mask code was being reworked.