@@ -20,12 +20,13 @@ use std::{
2020 net:: { IpAddr , SocketAddr } ,
2121 sync:: {
2222 Arc ,
23- atomic:: { AtomicU64 , Ordering :: Relaxed } ,
23+ atomic:: { AtomicBool , AtomicU64 , Ordering :: Relaxed } ,
2424 } ,
2525 time:: Duration ,
2626} ;
2727
2828use base64_serde:: base64_serde_type;
29+ use once_cell:: sync:: Lazy ;
2930use schemars:: JsonSchema ;
3031use serde:: { Deserialize , Serialize } ;
3132use uuid:: Uuid ;
@@ -53,6 +54,21 @@ pub(crate) const BACKOFF_INITIAL_DELAY: Duration = Duration::from_millis(500);
5354
5455pub type ConfigMap = typemap_rev:: TypeMap < dyn typemap_rev:: CloneDebuggableStorage > ;
5556
57+ #[ derive( Debug , Clone , Default ) ]
58+ #[ repr( transparent) ]
59+ pub ( crate ) struct LeaderLock ( Arc < Lazy < Arc < AtomicBool > > > ) ;
60+
61+ impl LeaderLock {
62+ pub ( crate ) fn load ( & self ) -> bool {
63+ self . 0 . load ( Relaxed )
64+ }
65+
66+ pub ( crate ) fn store ( & self , is_leader : bool ) {
67+ crate :: metrics:: leader_election ( is_leader) ;
68+ self . 0 . store ( is_leader, Relaxed ) ;
69+ }
70+ }
71+
5672base64_serde_type ! ( pub Base64Standard , base64:: engine:: general_purpose:: STANDARD ) ;
5773#[ derive( Clone ) ]
5874#[ cfg_attr( test, derive( Debug ) ) ]
@@ -172,6 +188,8 @@ impl<'de> Deserialize<'de> for Config {
172188 } ) ;
173189 } ;
174190
191+ typemap. insert :: < LeaderLock > ( <_ >:: default ( ) ) ;
192+
175193 Ok ( Config {
176194 dyn_cfg : DynamicConfig {
177195 version : version. unwrap_or_default ( ) ,
@@ -309,6 +327,7 @@ impl<'de> Deserialize<'de> for DynamicConfig {
309327 } ) ;
310328 } ;
311329
330+ typemap. insert :: < LeaderLock > ( <_ >:: default ( ) ) ;
312331 Ok ( DynamicConfig {
313332 version : version. unwrap_or_default ( ) ,
314333 id : id. map_or_else ( default_id, |id| Slot :: new ( Some ( id) ) ) ,
@@ -337,6 +356,10 @@ impl typemap_rev::TypeMapKey for Agent {
337356 type Value = Agent ;
338357}
339358
359+ impl typemap_rev:: TypeMapKey for LeaderLock {
360+ type Value = LeaderLock ;
361+ }
362+
340363impl DynamicConfig {
341364 pub fn filters ( & self ) -> Option < & Slot < FilterChain > > {
342365 self . typemap . get :: < FilterChain > ( )
@@ -353,6 +376,16 @@ impl DynamicConfig {
353376 pub fn agent ( & self ) -> Option < & Agent > {
354377 self . typemap . get :: < Agent > ( )
355378 }
379+
380+ pub ( crate ) fn init_leader_lock ( & self ) -> LeaderLock {
381+ self . typemap . get :: < LeaderLock > ( ) . unwrap ( ) . clone ( )
382+ }
383+
384+ pub ( crate ) fn leader_lock ( & self ) -> Option < & LeaderLock > {
385+ self . typemap
386+ . get :: < LeaderLock > ( )
387+ . filter ( |ll| Lazy :: get ( & * ll. 0 ) . is_some ( ) )
388+ }
356389}
357390
358391#[ cfg( test) ]
@@ -383,6 +416,10 @@ impl quilkin_xds::config::Configuration for Config {
383416 String :: clone ( & self . id ( ) )
384417 }
385418
419+ fn is_leader ( & self ) -> Option < bool > {
420+ self . dyn_cfg . leader_lock ( ) . map ( |ll| ll. load ( ) )
421+ }
422+
386423 fn allow_request_processing ( & self , resource_type : & str ) -> bool {
387424 resource_type. parse :: < ResourceType > ( ) . is_ok ( )
388425 }
0 commit comments