@@ -224,17 +224,10 @@ def _change_owner(self, path: str) -> None:
224
224
os .chown (path , uid = user_database .pw_uid , gid = user_database .pw_gid )
225
225
226
226
@property
227
- @retry (stop = stop_after_attempt (10 ), wait = wait_exponential (multiplier = 1 , min = 2 , max = 10 ))
228
227
def cluster_members (self ) -> set :
229
228
"""Get the current cluster members."""
230
229
# Request info from cluster endpoint (which returns all members of the cluster).
231
- cluster_status = requests .get (
232
- f"{ self ._patroni_url } /{ PATRONI_CLUSTER_STATUS_ENDPOINT } " ,
233
- verify = self .verify ,
234
- timeout = API_REQUEST_TIMEOUT ,
235
- auth = self ._patroni_auth ,
236
- )
237
- return {member ["name" ] for member in cluster_status .json ()["members" ]}
230
+ return {member ["name" ] for member in self .cached_cluster_status }
238
231
239
232
def _create_directory (self , path : str , mode : int ) -> None :
240
233
"""Creates a directory.
@@ -256,6 +249,11 @@ def get_postgresql_version(self) -> str:
256
249
if snp ["name" ] == charm_refresh .snap_name ():
257
250
return snp ["version" ]
258
251
252
+ @property
253
+ def cached_cluster_status (self ):
254
+ """Cached cluster status."""
255
+ return self .cluster_status ()
256
+
259
257
def cluster_status (self , alternative_endpoints : list | None = None ) -> list [ClusterMember ]:
260
258
"""Query the cluster status."""
261
259
# Request info from cluster endpoint (which returns all members of the cluster).
@@ -411,27 +409,22 @@ def are_all_members_ready(self) -> bool:
411
409
# Request info from cluster endpoint
412
410
# (which returns all members of the cluster and their states).
413
411
try :
414
- for attempt in Retrying (stop = stop_after_delay (10 ), wait = wait_fixed (3 )):
415
- with attempt :
416
- cluster_status = requests .get (
417
- f"{ self ._patroni_url } /{ PATRONI_CLUSTER_STATUS_ENDPOINT } " ,
418
- verify = self .verify ,
419
- timeout = API_REQUEST_TIMEOUT ,
420
- auth = self ._patroni_auth ,
421
- )
412
+ members = self .cluster_status ()
422
413
except RetryError :
423
414
return False
424
415
425
416
# Check if all members are running and one of them is a leader (primary) or
426
417
# a standby leader, because sometimes there may exist (for some period of time)
427
418
# only replicas after a failed switchover.
428
- return all (
429
- member ["state" ] in STARTED_STATES for member in cluster_status .json ()["members" ]
430
- ) and any (
431
- member ["role" ] in ["leader" , "standby_leader" ]
432
- for member in cluster_status .json ()["members" ]
419
+ return all (member ["state" ] in STARTED_STATES for member in members ) and any (
420
+ member ["role" ] in ["leader" , "standby_leader" ] for member in members
433
421
)
434
422
423
+ @property
424
+ def cached_patroni_health (self ) -> dict [str , str ]:
425
+ """Cached local unit health."""
426
+ return self .get_patroni_health ()
427
+
435
428
def get_patroni_health (self ) -> dict [str , str ]:
436
429
"""Gets, retires and parses the Patroni health endpoint."""
437
430
for attempt in Retrying (stop = stop_after_delay (60 ), wait = wait_fixed (7 )):
@@ -452,20 +445,12 @@ def is_creating_backup(self) -> bool:
452
445
# cluster member; the "is_creating_backup" tag means that the member is creating
453
446
# a backup).
454
447
try :
455
- for attempt in Retrying (stop = stop_after_delay (10 ), wait = wait_fixed (3 )):
456
- with attempt :
457
- r = requests .get (
458
- f"{ self ._patroni_url } /cluster" ,
459
- verify = self .verify ,
460
- auth = self ._patroni_auth ,
461
- timeout = PATRONI_TIMEOUT ,
462
- )
448
+ members = self .cached_cluster_status
463
449
except RetryError :
464
450
return False
465
451
466
452
return any (
467
- "tags" in member and member ["tags" ].get ("is_creating_backup" )
468
- for member in r .json ()["members" ]
453
+ "tags" in member and member ["tags" ].get ("is_creating_backup" ) for member in members
469
454
)
470
455
471
456
def is_replication_healthy (self ) -> bool :
@@ -509,7 +494,7 @@ def member_started(self) -> bool:
509
494
if not self .is_patroni_running ():
510
495
return False
511
496
try :
512
- response = self .get_patroni_health ()
497
+ response = self .cached_patroni_health
513
498
except RetryError :
514
499
return False
515
500
@@ -524,7 +509,7 @@ def member_inactive(self) -> bool:
524
509
seconds times to allow server time to start up.
525
510
"""
526
511
try :
527
- response = self .get_patroni_health ()
512
+ response = self .cached_patroni_health
528
513
except RetryError :
529
514
return True
530
515
@@ -535,27 +520,6 @@ def member_inactive(self) -> bool:
535
520
"restarting" ,
536
521
]
537
522
538
- @property
539
- def member_replication_lag (self ) -> str :
540
- """Member replication lag."""
541
- try :
542
- for attempt in Retrying (stop = stop_after_delay (60 ), wait = wait_fixed (3 )):
543
- with attempt :
544
- cluster_status = requests .get (
545
- f"{ self ._patroni_url } /{ PATRONI_CLUSTER_STATUS_ENDPOINT } " ,
546
- verify = self .verify ,
547
- timeout = API_REQUEST_TIMEOUT ,
548
- auth = self ._patroni_auth ,
549
- )
550
- except RetryError :
551
- return "unknown"
552
-
553
- for member in cluster_status .json ()["members" ]:
554
- if member ["name" ] == self .member_name :
555
- return member .get ("lag" , "unknown" )
556
-
557
- return "unknown"
558
-
559
523
@property
560
524
def is_member_isolated (self ) -> bool :
561
525
"""Returns whether the unit is isolated from the cluster."""
@@ -589,16 +553,8 @@ def online_cluster_members(self) -> list[ClusterMember]:
589
553
def are_replicas_up (self ) -> dict [str , bool ] | None :
590
554
"""Check if cluster members are running or streaming."""
591
555
try :
592
- response = requests .get (
593
- f"{ self ._patroni_url } /cluster" ,
594
- verify = self .verify ,
595
- auth = self ._patroni_auth ,
596
- timeout = PATRONI_TIMEOUT ,
597
- )
598
- return {
599
- member ["host" ]: member ["state" ] in ["running" , "streaming" ]
600
- for member in response .json ()["members" ]
601
- }
556
+ members = self .cluster_status ()
557
+ return {member ["host" ]: member ["state" ] in STARTED_STATES for member in members }
602
558
except Exception :
603
559
logger .exception ("Unable to get the state of the cluster" )
604
560
return
@@ -909,15 +865,8 @@ def reinitialise_raft_data(self) -> None:
909
865
def get_running_cluster_members (self ) -> list [str ]:
910
866
"""List running patroni members."""
911
867
try :
912
- members = requests .get (
913
- f"{ self ._patroni_url } /{ PATRONI_CLUSTER_STATUS_ENDPOINT } " ,
914
- verify = self .verify ,
915
- timeout = API_REQUEST_TIMEOUT ,
916
- auth = self ._patroni_auth ,
917
- ).json ()["members" ]
918
- return [
919
- member ["name" ] for member in members if member ["state" ] in ("streaming" , "running" )
920
- ]
868
+ members = self .cluster_status ()
869
+ return [member ["name" ] for member in members if member ["state" ] in STARTED_STATES ]
921
870
except Exception :
922
871
return []
923
872
0 commit comments