Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c28c233

Browse files
committed
chain head listener: change watcher deadlock detection to avoid spurious deadlock detection
1 parent 753cee7 commit c28c233

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

store/postgres/src/chain_head_listener.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ use graph::{
22
blockchain::ChainHeadUpdateStream,
33
prelude::{
44
futures03::{self, FutureExt},
5-
tokio, StoreError,
5+
tokio::{self, task::JoinHandle},
6+
StoreError,
67
},
78
prometheus::{CounterVec, GaugeVec},
89
util::timed_rw_lock::TimedRwLock,
910
};
10-
use std::sync::{atomic::AtomicBool, Arc};
11+
use std::str::FromStr;
12+
use std::sync::Arc;
1113
use std::{collections::BTreeMap, time::Duration};
12-
use std::{str::FromStr, sync::atomic};
1314

1415
use lazy_static::lazy_static;
1516

@@ -151,7 +152,7 @@ impl ChainHeadUpdateListener {
151152
) {
152153
// Process chain head updates in a dedicated task
153154
graph::spawn(async move {
154-
let sending_to_watcher = Arc::new(AtomicBool::new(false));
155+
let mut send_to_watcher: Option<JoinHandle<()>> = None;
155156
while let Some(notification) = receiver.recv().await {
156157
// Create ChainHeadUpdate from JSON
157158
let update: ChainHeadUpdate =
@@ -180,16 +181,16 @@ impl ChainHeadUpdateListener {
180181
if let Some(watcher) = watchers.read(&logger).get(&update.network_name) {
181182
// Due to a tokio bug, we must assume that the watcher can deadlock, see
182183
// https://github.com/tokio-rs/tokio/issues/4246.
183-
if !sending_to_watcher.load(atomic::Ordering::SeqCst) {
184-
let sending_to_watcher = sending_to_watcher.cheap_clone();
185-
let sender = watcher.sender.cheap_clone();
186-
tokio::task::spawn_blocking(move || {
187-
sending_to_watcher.store(true, atomic::Ordering::SeqCst);
188-
sender.send(()).unwrap();
189-
sending_to_watcher.store(false, atomic::Ordering::SeqCst);
190-
});
191-
} else {
192-
debug!(logger, "skipping chain head update, watcher is deadlocked"; "network" => &update.network_name);
184+
match send_to_watcher.as_mut().map(FutureExt::now_or_never) {
185+
None | Some(Some(_)) => {
186+
let sender = watcher.sender.cheap_clone();
187+
send_to_watcher = Some(tokio::task::spawn_blocking(move || {
188+
sender.send(()).unwrap()
189+
}));
190+
}
191+
Some(None) => {
192+
debug!(logger, "skipping chain head update, watcher is deadlocked"; "network" => &update.network_name)
193+
}
193194
}
194195
}
195196
}

0 commit comments

Comments
 (0)