adds a generic implementation of Gossip{Read,Write}Lock (#18559)
This commit is contained in:
		@@ -14,7 +14,9 @@
 | 
				
			|||||||
//! Bank needs to provide an interface for us to query the stake weight
 | 
					//! Bank needs to provide an interface for us to query the stake weight
 | 
				
			||||||
use {
 | 
					use {
 | 
				
			||||||
    crate::{
 | 
					    crate::{
 | 
				
			||||||
        cluster_info_metrics::{submit_gossip_stats, Counter, GossipStats, ScopedTimer},
 | 
					        cluster_info_metrics::{
 | 
				
			||||||
 | 
					            submit_gossip_stats, Counter, GossipStats, ScopedTimer, TimedGuard,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        contact_info::ContactInfo,
 | 
					        contact_info::ContactInfo,
 | 
				
			||||||
        crds::{Crds, Cursor},
 | 
					        crds::{Crds, Cursor},
 | 
				
			||||||
        crds_gossip::CrdsGossip,
 | 
					        crds_gossip::CrdsGossip,
 | 
				
			||||||
@@ -73,7 +75,7 @@ use {
 | 
				
			|||||||
        io::BufReader,
 | 
					        io::BufReader,
 | 
				
			||||||
        iter::repeat,
 | 
					        iter::repeat,
 | 
				
			||||||
        net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, UdpSocket},
 | 
					        net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, UdpSocket},
 | 
				
			||||||
        ops::{Deref, DerefMut, Div},
 | 
					        ops::{Deref, Div},
 | 
				
			||||||
        path::{Path, PathBuf},
 | 
					        path::{Path, PathBuf},
 | 
				
			||||||
        result::Result,
 | 
					        result::Result,
 | 
				
			||||||
        sync::{
 | 
					        sync::{
 | 
				
			||||||
@@ -137,78 +139,6 @@ pub enum ClusterInfoError {
 | 
				
			|||||||
    BadGossipAddress,
 | 
					    BadGossipAddress,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct GossipWriteLock<'a> {
 | 
					 | 
				
			||||||
    gossip: RwLockWriteGuard<'a, CrdsGossip>,
 | 
					 | 
				
			||||||
    timer: Measure,
 | 
					 | 
				
			||||||
    counter: &'a Counter,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> GossipWriteLock<'a> {
 | 
					 | 
				
			||||||
    fn new(
 | 
					 | 
				
			||||||
        gossip: RwLockWriteGuard<'a, CrdsGossip>,
 | 
					 | 
				
			||||||
        label: &'static str,
 | 
					 | 
				
			||||||
        counter: &'a Counter,
 | 
					 | 
				
			||||||
    ) -> Self {
 | 
					 | 
				
			||||||
        Self {
 | 
					 | 
				
			||||||
            gossip,
 | 
					 | 
				
			||||||
            timer: Measure::start(label),
 | 
					 | 
				
			||||||
            counter,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> Deref for GossipWriteLock<'a> {
 | 
					 | 
				
			||||||
    type Target = RwLockWriteGuard<'a, CrdsGossip>;
 | 
					 | 
				
			||||||
    fn deref(&self) -> &Self::Target {
 | 
					 | 
				
			||||||
        &self.gossip
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> DerefMut for GossipWriteLock<'a> {
 | 
					 | 
				
			||||||
    fn deref_mut(&mut self) -> &mut Self::Target {
 | 
					 | 
				
			||||||
        &mut self.gossip
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> Drop for GossipWriteLock<'a> {
 | 
					 | 
				
			||||||
    fn drop(&mut self) {
 | 
					 | 
				
			||||||
        self.counter.add_measure(&mut self.timer);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct GossipReadLock<'a> {
 | 
					 | 
				
			||||||
    gossip: RwLockReadGuard<'a, CrdsGossip>,
 | 
					 | 
				
			||||||
    timer: Measure,
 | 
					 | 
				
			||||||
    counter: &'a Counter,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> GossipReadLock<'a> {
 | 
					 | 
				
			||||||
    fn new(
 | 
					 | 
				
			||||||
        gossip: RwLockReadGuard<'a, CrdsGossip>,
 | 
					 | 
				
			||||||
        label: &'static str,
 | 
					 | 
				
			||||||
        counter: &'a Counter,
 | 
					 | 
				
			||||||
    ) -> Self {
 | 
					 | 
				
			||||||
        Self {
 | 
					 | 
				
			||||||
            gossip,
 | 
					 | 
				
			||||||
            timer: Measure::start(label),
 | 
					 | 
				
			||||||
            counter,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> Deref for GossipReadLock<'a> {
 | 
					 | 
				
			||||||
    type Target = RwLockReadGuard<'a, CrdsGossip>;
 | 
					 | 
				
			||||||
    fn deref(&self) -> &Self::Target {
 | 
					 | 
				
			||||||
        &self.gossip
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> Drop for GossipReadLock<'a> {
 | 
					 | 
				
			||||||
    fn drop(&mut self) {
 | 
					 | 
				
			||||||
        self.counter.add_measure(&mut self.timer);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub struct ClusterInfo {
 | 
					pub struct ClusterInfo {
 | 
				
			||||||
    /// The network
 | 
					    /// The network
 | 
				
			||||||
    pub gossip: RwLock<CrdsGossip>,
 | 
					    pub gossip: RwLock<CrdsGossip>,
 | 
				
			||||||
@@ -986,16 +916,16 @@ impl ClusterInfo {
 | 
				
			|||||||
        &'a self,
 | 
					        &'a self,
 | 
				
			||||||
        label: &'static str,
 | 
					        label: &'static str,
 | 
				
			||||||
        counter: &'a Counter,
 | 
					        counter: &'a Counter,
 | 
				
			||||||
    ) -> GossipReadLock<'a> {
 | 
					    ) -> TimedGuard<'a, RwLockReadGuard<CrdsGossip>> {
 | 
				
			||||||
        GossipReadLock::new(self.gossip.read().unwrap(), label, counter)
 | 
					        TimedGuard::new(self.gossip.read().unwrap(), label, counter)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn time_gossip_write_lock<'a>(
 | 
					    fn time_gossip_write_lock<'a>(
 | 
				
			||||||
        &'a self,
 | 
					        &'a self,
 | 
				
			||||||
        label: &'static str,
 | 
					        label: &'static str,
 | 
				
			||||||
        counter: &'a Counter,
 | 
					        counter: &'a Counter,
 | 
				
			||||||
    ) -> GossipWriteLock<'a> {
 | 
					    ) -> TimedGuard<'a, RwLockWriteGuard<CrdsGossip>> {
 | 
				
			||||||
        GossipWriteLock::new(self.gossip.write().unwrap(), label, counter)
 | 
					        TimedGuard::new(self.gossip.write().unwrap(), label, counter)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn push_message(&self, message: CrdsValue) {
 | 
					    pub fn push_message(&self, message: CrdsValue) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ use {
 | 
				
			|||||||
    solana_sdk::pubkey::Pubkey,
 | 
					    solana_sdk::pubkey::Pubkey,
 | 
				
			||||||
    std::{
 | 
					    std::{
 | 
				
			||||||
        collections::HashMap,
 | 
					        collections::HashMap,
 | 
				
			||||||
 | 
					        ops::{Deref, DerefMut},
 | 
				
			||||||
        sync::{
 | 
					        sync::{
 | 
				
			||||||
            atomic::{AtomicU64, Ordering},
 | 
					            atomic::{AtomicU64, Ordering},
 | 
				
			||||||
            RwLock,
 | 
					            RwLock,
 | 
				
			||||||
@@ -28,6 +29,12 @@ impl Counter {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub(crate) struct TimedGuard<'a, T> {
 | 
				
			||||||
 | 
					    guard: T,
 | 
				
			||||||
 | 
					    timer: Measure,
 | 
				
			||||||
 | 
					    counter: &'a Counter,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) struct ScopedTimer<'a> {
 | 
					pub(crate) struct ScopedTimer<'a> {
 | 
				
			||||||
    clock: Instant,
 | 
					    clock: Instant,
 | 
				
			||||||
    metric: &'a AtomicU64,
 | 
					    metric: &'a AtomicU64,
 | 
				
			||||||
@@ -52,6 +59,35 @@ impl Drop for ScopedTimer<'_> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'a, T> TimedGuard<'a, T> {
 | 
				
			||||||
 | 
					    pub(crate) fn new(guard: T, label: &'static str, counter: &'a Counter) -> Self {
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            guard,
 | 
				
			||||||
 | 
					            timer: Measure::start(label),
 | 
				
			||||||
 | 
					            counter,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'a, T> Deref for TimedGuard<'a, T> {
 | 
				
			||||||
 | 
					    type Target = T;
 | 
				
			||||||
 | 
					    fn deref(&self) -> &Self::Target {
 | 
				
			||||||
 | 
					        &self.guard
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'a, T> DerefMut for TimedGuard<'a, T> {
 | 
				
			||||||
 | 
					    fn deref_mut(&mut self) -> &mut Self::Target {
 | 
				
			||||||
 | 
					        &mut self.guard
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'a, T> Drop for TimedGuard<'a, T> {
 | 
				
			||||||
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
 | 
					        self.counter.add_measure(&mut self.timer);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Default)]
 | 
					#[derive(Default)]
 | 
				
			||||||
pub(crate) struct GossipStats {
 | 
					pub(crate) struct GossipStats {
 | 
				
			||||||
    pub(crate) all_tvu_peers: Counter,
 | 
					    pub(crate) all_tvu_peers: Counter,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user