@@ -26,7 +26,7 @@ use std::sync::atomic::{
2626} ;
2727use std:: time:: Duration ;
2828
29- use parking_lot :: RwLock ;
29+ use once_cell :: sync :: OnceCell ;
3030use time:: OffsetDateTime ;
3131use tonic:: transport:: {
3232 Channel ,
@@ -141,7 +141,7 @@ pub(crate) struct Network {
141141 map : HashMap < AccountId , usize > ,
142142 nodes : Vec < AccountId > ,
143143 addresses : Vec < Vec < Cow < ' static , str > > > ,
144- channels : Vec < RwLock < Option < Channel > > > ,
144+ channels : Vec < OnceCell < Channel > > ,
145145 healthy : Vec < AtomicI64 > ,
146146 last_pinged : Vec < AtomicI64 > ,
147147}
@@ -173,7 +173,7 @@ impl Network {
173173 map. insert ( node_account_id, i) ;
174174 nodes. push ( node_account_id) ;
175175 addresses. push ( address. iter ( ) . map ( |address| Cow :: Borrowed ( * address) ) . collect ( ) ) ;
176- channels. push ( RwLock :: new ( None ) ) ;
176+ channels. push ( OnceCell :: new ( ) ) ;
177177 healthy. push ( AtomicI64 :: new ( 0 ) ) ;
178178 last_pinged. push ( AtomicI64 :: new ( 0 ) ) ;
179179 }
@@ -236,39 +236,23 @@ impl Network {
236236 pub ( crate ) fn channel ( & self , index : usize ) -> ( AccountId , Channel ) {
237237 let id = self . nodes [ index] ;
238238
239- // Double lock check: We'd really rather not take a write lock if possible.
240- // (paired with the below comment)
241- if let Some ( channel) = & * self . channels [ index] . read_recursive ( ) {
242- return ( id, channel. clone ( ) ) ;
243- }
244-
245- let mut slot = self . channels [ index] . write ( ) ;
246-
247- // Double lock check: We'd rather not replace the channel if one exists already, they aren't free.
248- // (paired with the above comment)
249- // Between returning `None` in the above `read` and getting
250- // the `WriteGuard` some *other* write to this channel could've happened
251- // causing the channel to be `Some` here, despite this thread not
252- // changing it.
253- if let Some ( channel) = & * slot {
254- return ( id, channel. clone ( ) ) ;
255- }
256-
257- let addresses = & self . addresses [ index] ;
258-
259- let endpoints = addresses. iter ( ) . map ( |address| {
260- let uri = format ! ( "tcp://{address}:50211" ) ;
261- Endpoint :: from_shared ( uri)
262- . unwrap ( )
263- . keep_alive_timeout ( Duration :: from_secs ( 10 ) )
264- . keep_alive_while_idle ( true )
265- . tcp_keepalive ( Some ( Duration :: from_secs ( 10 ) ) )
266- . connect_timeout ( Duration :: from_secs ( 10 ) )
267- } ) ;
268-
269- let channel = Channel :: balance_list ( endpoints) ;
270-
271- * slot = Some ( channel. clone ( ) ) ;
239+ let channel = self . channels [ index]
240+ . get_or_init ( || {
241+ let addresses = & self . addresses [ index] ;
242+
243+ let endpoints = addresses. iter ( ) . map ( |address| {
244+ let uri = format ! ( "tcp://{address}:50211" ) ;
245+ Endpoint :: from_shared ( uri)
246+ . unwrap ( )
247+ . keep_alive_timeout ( Duration :: from_secs ( 10 ) )
248+ . keep_alive_while_idle ( true )
249+ . tcp_keepalive ( Some ( Duration :: from_secs ( 10 ) ) )
250+ . connect_timeout ( Duration :: from_secs ( 10 ) )
251+ } ) ;
252+
253+ Channel :: balance_list ( endpoints)
254+ } )
255+ . clone ( ) ;
272256
273257 ( id, channel)
274258 }
0 commit comments