6
6
import enum
7
7
import logging
8
8
import typing
9
- import uuid
10
9
from functools import cached_property
11
10
from time import sleep
12
11
55
54
# The unique Charmhub library identifier, never change it
56
55
LIBID = "4de21f1a022c4e2c87ac8e672ec16f6a"
57
56
LIBAPI = 0
58
- LIBPATCH = 3
57
+ LIBPATCH = 4
59
58
60
59
RELATION_OFFER = "replication-offer"
61
60
RELATION_CONSUMER = "replication"
@@ -129,10 +128,9 @@ def cluster_set_name(self) -> str:
129
128
@property
130
129
def relation (self ) -> Optional [Relation ]:
131
130
"""Relation."""
132
- if isinstance (self , MySQLAsyncReplicationOffer ):
133
- return self .model .get_relation (RELATION_OFFER )
134
-
135
- return self .model .get_relation (RELATION_CONSUMER )
131
+ return self .model .get_relation (RELATION_OFFER ) or self .model .get_relation (
132
+ RELATION_CONSUMER
133
+ )
136
134
137
135
@property
138
136
def relation_data (self ) -> Optional [RelationDataContent ]:
@@ -168,6 +166,10 @@ def _on_promote_to_primary(self, event: ActionEvent) -> None:
168
166
logger .info (message )
169
167
event .set_results ({"message" : message })
170
168
self ._charm ._on_update_status (None )
169
+ # write counter to propagate status update on the other side
170
+ self .relation_data ["switchover" ] = str (
171
+ int (self .relation_data .get ("switchover" , 0 )) + 1
172
+ )
171
173
except MySQLPromoteClusterToPrimaryError :
172
174
logger .exception ("Failed to promote cluster to primary" )
173
175
event .fail ("Failed to promote cluster to primary" )
@@ -388,6 +390,9 @@ def state(self) -> Optional[States]:
388
390
return States .INITIALIZING
389
391
else :
390
392
return States .RECOVERING
393
+ if self .role .relation_side == RELATION_CONSUMER :
394
+ # if on the consume and is primary, the cluster is ready
395
+ return States .READY
391
396
392
397
@property
393
398
def idle (self ) -> bool :
@@ -570,6 +575,11 @@ def _on_offer_relation_changed(self, event):
570
575
# Recover replica cluster
571
576
self ._charm .unit .status = MaintenanceStatus ("Replica cluster in recovery" )
572
577
578
+ elif state == States .READY :
579
+ # trigger update status on relation update when ready
580
+ # speeds up status on switchover
581
+ self ._charm ._on_update_status (None )
582
+
573
583
def _on_offer_relation_broken (self , event : RelationBrokenEvent ):
574
584
"""Handle the async_primary relation being broken."""
575
585
if self ._charm .unit .is_leader ():
@@ -642,11 +652,15 @@ def state(self) -> Optional[States]:
642
652
# and did not synced credentials
643
653
return States .SYNCING
644
654
645
- if self .replica_initialized :
646
- # cluster added to cluster-set by primary cluster
647
- if self ._charm .cluster_fully_initialized :
648
- return States .READY
649
- return States .RECOVERING
655
+ if self .model .get_relation (RELATION_CONSUMER ):
656
+ if self .replica_initialized :
657
+ # cluster added to cluster-set by primary cluster
658
+ if self ._charm .cluster_fully_initialized :
659
+ return States .READY
660
+ return States .RECOVERING
661
+ else :
662
+ return States .READY
663
+
650
664
return States .INITIALIZING
651
665
652
666
@property
@@ -672,7 +686,7 @@ def returning_cluster(self) -> bool:
672
686
673
687
@property
674
688
def replica_initialized (self ) -> bool :
675
- """Whether the replica cluster is initialized as such ."""
689
+ """Whether the replica cluster was initialized."""
676
690
return self .remote_relation_data .get ("replica-state" ) == "initialized"
677
691
678
692
def _check_version (self ) -> bool :
@@ -685,7 +699,8 @@ def _check_version(self) -> bool:
685
699
686
700
if remote_version != local_version :
687
701
logger .error (
688
- f"Primary cluster MySQL version { remote_version } is not compatible with this cluster MySQL version { local_version } "
702
+ f"Primary cluster MySQL version { remote_version } is not compatible with this"
703
+ f"cluster MySQL version { local_version } "
689
704
)
690
705
return False
691
706
@@ -824,11 +839,12 @@ def _on_consumer_changed(self, event): # noqa: C901
824
839
825
840
if self .remote_relation_data ["cluster-name" ] == self .cluster_name : # pyright: ignore
826
841
# this cluster need a new cluster name
842
+ # we append the model uuid, trimming to a max of 63 characters
827
843
logger .warning (
828
- "Cluster name is the same as the primary cluster. Appending generated value "
844
+ "Cluster name is the same as the primary cluster. Appending model uuid "
829
845
)
830
846
self ._charm .app_peer_data ["cluster-name" ] = (
831
- f"{ self .cluster_name } { uuid .uuid4 (). hex [: 4 ] } "
847
+ f"{ self .cluster_name } { self . model . uuid .replace ( '-' , '' ) } " [: 63 ]
832
848
)
833
849
834
850
self ._charm .unit .status = MaintenanceStatus ("Populate endpoint" )
0 commit comments