1
1
use graph:: {
2
2
blockchain:: ChainHeadUpdateStream ,
3
- parking_lot:: RwLock ,
4
3
prelude:: {
5
4
futures03:: { self , FutureExt } ,
6
5
tokio, StoreError ,
7
6
} ,
8
7
prometheus:: { CounterVec , GaugeVec } ,
8
+ util:: timed_rw_lock:: TimedRwLock ,
9
9
} ;
10
10
use std:: str:: FromStr ;
11
11
use std:: sync:: Arc ;
@@ -87,7 +87,7 @@ struct ChainHeadUpdate {
87
87
88
88
pub struct ChainHeadUpdateListener {
89
89
/// Update watchers keyed by network.
90
- watchers : Arc < RwLock < BTreeMap < String , Watcher > > > ,
90
+ watchers : Arc < TimedRwLock < BTreeMap < String , Watcher > > > ,
91
91
_listener : NotificationListener ,
92
92
}
93
93
@@ -113,7 +113,10 @@ impl ChainHeadUpdateListener {
113
113
// Create a Postgres notification listener for chain head updates
114
114
let ( mut listener, receiver) =
115
115
NotificationListener :: new ( & logger, postgres_url, CHANNEL_NAME . clone ( ) ) ;
116
- let watchers = Arc :: new ( RwLock :: new ( BTreeMap :: new ( ) ) ) ;
116
+ let watchers = Arc :: new ( TimedRwLock :: new (
117
+ BTreeMap :: new ( ) ,
118
+ "chain_head_listener_watchers" ,
119
+ ) ) ;
117
120
118
121
Self :: listen (
119
122
logger,
@@ -139,7 +142,7 @@ impl ChainHeadUpdateListener {
139
142
metrics : Arc < BlockIngestorMetrics > ,
140
143
listener : & mut NotificationListener ,
141
144
mut receiver : Receiver < JsonNotification > ,
142
- watchers : Arc < RwLock < BTreeMap < String , Watcher > > > ,
145
+ watchers : Arc < TimedRwLock < BTreeMap < String , Watcher > > > ,
143
146
counter : CounterVec ,
144
147
) {
145
148
// Process chain head updates in a dedicated task
@@ -169,8 +172,10 @@ impl ChainHeadUpdateListener {
169
172
. set_chain_head_number ( & update. network_name , * & update. head_block_number as i64 ) ;
170
173
171
174
// If there are subscriptions for this network, notify them.
172
- if let Some ( watcher) = watchers. read ( ) . get ( & update. network_name ) {
173
- watcher. send ( )
175
+ if let Some ( watcher) = watchers. read ( & logger) . get ( & update. network_name ) {
176
+ debug ! ( logger, "sending chain head update" ; "network" => & update. network_name) ;
177
+ watcher. send ( ) ;
178
+ debug ! ( logger, "chain head update sent" ; "network" => & update. network_name) ;
174
179
}
175
180
}
176
181
} ) ;
@@ -186,7 +191,7 @@ impl ChainHeadUpdateListenerTrait for ChainHeadUpdateListener {
186
191
187
192
let update_receiver = {
188
193
let existing = {
189
- let watchers = self . watchers . read ( ) ;
194
+ let watchers = self . watchers . read ( & logger ) ;
190
195
watchers. get ( & network_name) . map ( |w| w. receiver . clone ( ) )
191
196
} ;
192
197
@@ -199,7 +204,7 @@ impl ChainHeadUpdateListenerTrait for ChainHeadUpdateListener {
199
204
// Race condition: Another task could have simoultaneously entered this branch and
200
205
// inserted a writer, so we should check the entry again after acquiring the lock.
201
206
self . watchers
202
- . write ( )
207
+ . write ( & logger )
203
208
. entry ( network_name)
204
209
. or_insert_with ( || Watcher :: new ( ) )
205
210
. receiver
0 commit comments