mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
fix(notify): normalize lock ordering to prevent deadlock (#3199)
* fix(notify): normalize lock ordering to prevent deadlock replace_targets() and shutdown() acquired target_list before replay_workers, opposite to runtime_view.rs order. This is an ABBA deadlock pattern. - Swap to replay_workers -> target_list order (canonical) - Add lock order comments - 82 notify tests pass * docs(notify): update runtime facade lock order * docs(notify): clarify runtime facade lock order --------- Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
@@ -31,7 +31,7 @@ shared plugin/runtime primitives from `rustfs-targets`.
|
||||
## Concurrency
|
||||
|
||||
- `runtime_view.rs` acquires locks in order: `stream_cancellers` → `target_list`.
|
||||
- `runtime_facade.rs` acquires locks in order: `target_list` → `replay_workers`.
|
||||
- `runtime_facade.rs` acquires locks in order: `replay_workers` → `target_list`.
|
||||
- These orders must not be reversed in new code. When adding a function that needs both `target_list` and `stream_cancellers`, acquire `stream_cancellers` first (matching `runtime_view.rs` order).
|
||||
- Do not hold write guards across `.await` points unless the hold time is bounded and the operation is unavoidably async.
|
||||
|
||||
|
||||
@@ -81,8 +81,9 @@ impl NotifyRuntimeFacade {
|
||||
}
|
||||
|
||||
pub async fn replace_targets(&self, activation: RuntimeActivation<Event>) -> Result<(), NotificationError> {
|
||||
let mut target_list = self.target_list.write().await;
|
||||
// Lock order: replay_workers -> target_list (matches notify AGENTS.md).
|
||||
let mut replay_workers = self.replay_workers.write().await;
|
||||
let mut target_list = self.target_list.write().await;
|
||||
self.runtime_adapter
|
||||
.replace_runtime_targets(target_list.runtime_mut(), &mut replay_workers, activation)
|
||||
.await
|
||||
@@ -102,8 +103,9 @@ impl NotifyRuntimeFacade {
|
||||
info!("Stops {} active event stream processing tasks", active_targets);
|
||||
|
||||
{
|
||||
let mut target_list = self.target_list.write().await;
|
||||
// Lock order: replay_workers -> target_list (matches notify AGENTS.md).
|
||||
let mut replay_workers = self.replay_workers.write().await;
|
||||
let mut target_list = self.target_list.write().await;
|
||||
if let Err(err) = self
|
||||
.runtime_adapter
|
||||
.shutdown(target_list.runtime_mut(), &mut replay_workers)
|
||||
|
||||
Reference in New Issue
Block a user