Files
viexp/docs/decisions/ADR-005-async-adoption.md
T

39 lines
1.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
type: decision
adr: 005
status: accepted
date: 2026-10-17
supersedes:
tags: [adr, async, tokio, threads]
---
# ADR-005: adopt async gradually — sync core, then threads, then tokio
## Context
Ranger's fatal flaw is a synchronous loop that stats every file inline ([[research/ranger-deep-dive]]).
yazi proves tokio solves it but is a lot of machinery to learn while also learning Rust.
lf (Go goroutines) shows threads alone already keep a UI responsive.
## Options considered
| Option | Pros | Cons |
|--------|------|------|
| Gradual: sync → std threads + channels → tokio | learnable steps; working product at every stage | one refactor of the preview pipeline in Sprint 8 |
| tokio from day 1 | final architecture sooner | async lifetimes + borrow checker + TUI at once = frustration barrier |
| threads-only forever | simpler mental model | ecosystem (notify bridges, timeouts, process spawning) is tokio-first |
## Decision
- **Sprints 1–5**: synchronous core. The TUI loop owns all state; directory loading and file
ops are fast enough synchronously for a first product.
- **Sprints 6–7**: previews move to `std::thread` + `std::sync::mpsc` — UI stays responsive,
ownership lessons are explicit.
- **Sprint 8**: adopt **tokio** for the full preview/media pipeline (yazi architecture:
runtime workers marshal results to the single-threaded UI actor via a channel). Introduce
cancellation via a generation-counter ("ticket") pattern before adopting tokio `abort`.
## Consequences
- Positive: each concurrency model is learned in isolation; no big-bang async rewrite of the UI.
- Negative: preview pipeline is written twice (thread → task) — accepted as a deliberate
learning repetition (Kaufman: quantity of practice beats premature perfection).
- Mitigations: keep the preview pipeline behind a small interface (`Previewer` trait, ADR-002)
so the swap is local, not global.