Module: Brute::FileMutationQueue
- Defined in:
- lib/brute/file_mutation_queue.rb
Overview
Per-file serialization queue for concurrent tool execution.
When tools run in parallel (via threads or async fibers), multiple tools may target the same file simultaneously. Without serialization, a sequence like [read → patch → write] on the same file would race and lose edits.
This module provides a single public method:
Brute::FileMutationQueue.serialize("/path/to/file") do
# snapshot + read + modify + write — all atomic for this path
end
Design (mirrors pi-mono’s withFileMutationQueue):
- Operations on the SAME file are serialized (run one at a time)
- Operations on DIFFERENT files run fully in parallel (independent mutexes)
- Symlink-aware: resolves real paths so aliases share one mutex
- Error-safe: mutex is always released in `ensure`, so failures never deadlock
- Self-cleaning: per-file mutexes are removed when no longer in use
Ruby 3.4’s Mutex is fiber-scheduler-aware, so this works correctly with both :thread and :task (Async) concurrency strategies.
Class Method Summary collapse
-
.clear! ⇒ Object
Clear all tracked mutexes.
-
.serialize(path) { ... } ⇒ Object
Serialize a block of work for a given file path.
-
.size ⇒ Object
Number of file paths currently tracked (for diagnostics).
Class Method Details
.clear! ⇒ Object
Clear all tracked mutexes. Used in tests and session resets.
51 52 53 54 55 56 |
# File 'lib/brute/file_mutation_queue.rb', line 51 def clear! @guard.synchronize do @mutexes.clear @waiters.clear end end |
.serialize(path) { ... } ⇒ Object
Serialize a block of work for a given file path.
Concurrent calls targeting the same canonical path will execute sequentially in FIFO order. Calls targeting different paths proceed in parallel with zero contention.
41 42 43 44 45 46 47 48 |
# File 'lib/brute/file_mutation_queue.rb', line 41 def serialize(path, &block) key = canonical_path(path) mutex = acquire_mutex(key) mutex.synchronize(&block) ensure release_mutex(key) end |
.size ⇒ Object
Number of file paths currently tracked (for diagnostics).
59 60 61 |
# File 'lib/brute/file_mutation_queue.rb', line 59 def size @guard.synchronize { @mutexes.size } end |