pub async fn with_metadata_file_lock<T, F, Fut>(
metadata_path: &Path,
cycle: F,
) -> StorageResult<T>Expand description
The blessed recipe for a multi-process consumer’s metadata
read-modify-write cycle (#100, review composition fix): the advisory
file lock (lock_file_for_metadata) is held across the whole
awaited commit-actor cycle — cross-process exclusion and in-process
actor serialization are both active for the duration of cycle.
The closure is async: a full load → mutate → publish cycle (including
any save_*-style actor work) runs inside, while independent processes
taking the same lock file serialize behind it. Lock acquisition runs on
the blocking pool (the flock can park on a competing holder); the lock
is released when the cycle’s future completes.
For consumers whose RMW is entirely synchronous, with_file_lock
wraps the same lock file — but a sync closure cannot await the commit
actor; only this helper composes the two locks.
§Operational caution (blocking-pool waits)
The flock wait is unbounded and runs through spawn_blocking, which
Tokio documents for blocking work that is bounded and eventually
completes: a waiter that has already parked cannot be reliably
aborted, and many long-lived blocked waiters can exhaust the runtime’s
blocking-thread capacity. This design is reasonable for metadata
commits when:
- commit cycles are short — the hold scope is a JSON load → mutate → publish, not compute;
- contention is normally brief;
- callers do not hold the lock across lengthy compute, network I/O, user interaction, or indefinite waits;
- shutdown behavior with a stuck lock holder is understood: blocked
spawn_blockingtasks are not aborted by task cancellation;tokio::runtime::Runtime::shutdown_timeoutabandons them after a grace period whiletokio::runtime::Runtime::shutdown_backgroundwaits them out — and process exit always closes the descriptor, releasing the flock.
If lock waits could be prolonged or numerous, prefer a dedicated
lock-management thread, an explicit timeout/cancellation strategy
(bounded wait before acquisition), or a storage system with
transactional coordination over unbounded flock waits here.