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,12 @@ 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
395
+ # the cluster is ready when fully initialized
396
+ if self ._charm .cluster_fully_initialized :
397
+ return States .READY
398
+ return States .RECOVERING
391
399
392
400
@property
393
401
def idle (self ) -> bool :
@@ -570,6 +578,11 @@ def _on_offer_relation_changed(self, event):
570
578
# Recover replica cluster
571
579
self ._charm .unit .status = MaintenanceStatus ("Replica cluster in recovery" )
572
580
581
+ elif state == States .READY :
582
+ # trigger update status on relation update when ready
583
+ # speeds up status on switchover
584
+ self ._charm ._on_update_status (None )
585
+
573
586
def _on_offer_relation_broken (self , event : RelationBrokenEvent ):
574
587
"""Handle the async_primary relation being broken."""
575
588
if self ._charm .unit .is_leader ():
@@ -642,11 +655,15 @@ def state(self) -> Optional[States]:
642
655
# and did not synced credentials
643
656
return States .SYNCING
644
657
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
658
+ if self .model .get_relation (RELATION_CONSUMER ):
659
+ if self .replica_initialized :
660
+ # cluster added to cluster-set by primary cluster
661
+ if self ._charm .cluster_fully_initialized :
662
+ return States .READY
663
+ return States .RECOVERING
664
+ else :
665
+ return States .READY
666
+
650
667
return States .INITIALIZING
651
668
652
669
@property
@@ -672,7 +689,7 @@ def returning_cluster(self) -> bool:
672
689
673
690
@property
674
691
def replica_initialized (self ) -> bool :
675
- """Whether the replica cluster is initialized as such ."""
692
+ """Whether the replica cluster was initialized."""
676
693
return self .remote_relation_data .get ("replica-state" ) == "initialized"
677
694
678
695
def _check_version (self ) -> bool :
@@ -685,7 +702,8 @@ def _check_version(self) -> bool:
685
702
686
703
if remote_version != local_version :
687
704
logger .error (
688
- f"Primary cluster MySQL version { remote_version } is not compatible with this cluster MySQL version { local_version } "
705
+ f"Primary cluster MySQL version { remote_version } is not compatible with this"
706
+ f"cluster MySQL version { local_version } "
689
707
)
690
708
return False
691
709
@@ -824,11 +842,12 @@ def _on_consumer_changed(self, event): # noqa: C901
824
842
825
843
if self .remote_relation_data ["cluster-name" ] == self .cluster_name : # pyright: ignore
826
844
# this cluster need a new cluster name
845
+ # we append the model uuid, trimming to a max of 63 characters
827
846
logger .warning (
828
- "Cluster name is the same as the primary cluster. Appending generated value "
847
+ "Cluster name is the same as the primary cluster. Appending model uuid "
829
848
)
830
849
self ._charm .app_peer_data ["cluster-name" ] = (
831
- f"{ self .cluster_name } { uuid .uuid4 (). hex [: 4 ] } "
850
+ f"{ self .cluster_name } { self . model . uuid .replace ( '-' , '' ) } " [: 63 ]
832
851
)
833
852
834
853
self ._charm .unit .status = MaintenanceStatus ("Populate endpoint" )
0 commit comments