Output, Errors, and Early Exit
Parallel work is only half of the design. Ripgrep must also decide what becomes observable when work completes out of order, fails, or is no longer needed.
Atomic output units
Each worker prints into a private termcolor::Buffer. After one file finishes,
BufferWriter::print writes the completed buffer to stdout. The synchronization
boundary is therefore one file’s rendered result, not one match and not the
whole search.
This is a useful general pattern:
compute concurrently → stage result privately → commit as one visible unit
It preserves throughput without holding a global stdout lock throughout file I/O and matching.
Determinism costs parallelism
Parallel workers finish in scheduler- and filesystem-dependent order. Ripgrep
therefore cannot promise stable file ordering in its normal parallel mode.
When sorting is requested, HiArgs forces the effective thread count to one;
the sequential path can then sort before searching.
Source: HiArgs thread selection,
walk_builder
The important tradeoff is not “sorting is slow.” Global order requires knowing which result comes next, so the existing immediate-commit architecture cannot retain both its bounded buffering and arbitrary parallel completion.
Most file errors are partial failures
An unreadable directory or failed file search is reported, but other workers continue. A shared error indicator later influences the process exit code. This lets a search produce useful matches even when one subtree is inaccessible.
Fatal initialization errors still return through anyhow::Result; per-entry
operational errors are logged and converted into WalkState::Continue.
Broken pipe is successful termination
If a downstream consumer closes the pipe—rg pattern | head, for example—an
output write returns BrokenPipe. The parallel visitor returns
WalkState::Quit, and top-level error handling treats a propagated broken pipe
as exit code zero.
Source: search_parallel output handling,
main error mapping
Quiet mode coordinates early exit
When one worker finds a match, it stores true in the shared matched atomic.
If the selected mode permits stopping after a match, that worker returns
WalkState::Quit. Worker::run sets the global quit flag, so peers stop taking
ordinary work at their next coordination point.
This is cooperative cancellation. A worker already inside a synchronous file read is not forcibly interrupted; shutdown happens at explicit boundaries.
Panic cleanup
Traversal uses scoped threads and joins every handle. If a Worker is dropped
while its thread is panicking, its Drop implementation sets the same global
quit flag, encouraging peers to stop rather than continue unrelated work.
Source: Worker::drop