Implement Failover.is_failover/switchover properties

This commit is contained in:
Polina Bungina
2023-09-12 14:02:17 +02:00
parent 5b4291bfab
commit 03d9226633
3 changed files with 15 additions and 7 deletions

View File

@@ -451,7 +451,7 @@ class Leader(NamedTuple):
class Failover(NamedTuple):
"""Immutable object (namedtuple) representing configuration information required for failover/switchover capability.
"""Immutable object (namedtuple) which represents failover key.
:ivar version: version of the object.
:ivar leader: name of the leader. If value isn't empty we treat it as a switchover from the specified node.
@@ -547,6 +547,13 @@ class Failover(NamedTuple):
"""
return int(bool(self.leader)) + int(bool(self.candidate))
@property
def is_switchover(self) -> bool:
return bool(self.leader)
@property
def is_failover(self) -> bool:
return not self.is_switchover
class ClusterConfig(NamedTuple):
"""Immutable object (namedtuple) which represents cluster configuration.

View File

@@ -234,7 +234,7 @@ class Ha(object):
"""
if not self.cluster.failover:
return 'failover'
return 'switchover' if self.cluster.failover.leader else 'manual failover'
return 'switchover' if self.cluster.failover.is_switchover else 'manual failover'
def load_cluster_from_dcs(self) -> None:
cluster = self.dcs.get_cluster()
@@ -1044,7 +1044,7 @@ class Ha(object):
return False
# try to pick some other members for switchover and check that they are healthy
if failover.leader:
if failover.is_switchover:
if self.state_handler.name == failover.leader: # I was the leader
# exclude desired member which is unhealthy if it was specified
if self.is_failover_possible(exclude_failover_candidate=bool(failover.candidate)):
@@ -1101,7 +1101,7 @@ class Ha(object):
if self.cluster.failover:
# When doing a switchover in synchronous mode only synchronous nodes and former leader are allowed to race
if self.cluster.failover.leader and self.sync_mode_is_active() \
if self.cluster.failover.is_switchover and self.sync_mode_is_active() \
and not self.cluster.sync.matches(self.state_handler.name, True):
return False
return self.manual_failover_process_no_leader() or False
@@ -2022,7 +2022,7 @@ class Ha(object):
def is_eligible(node: Member) -> bool:
# in synchronous mode we allow failover (not switchover!) to async node
if self.sync_mode_is_active() and not self.cluster.sync.matches(node.name)\
and not (failover and not failover.leader):
and not (failover and failover.is_failover):
return False
# Don't spend time on "nofailover" nodes checking.
# We also don't need nodes which we can't query with the api in the list.

View File

@@ -839,8 +839,9 @@ def cluster_as_json(cluster: 'Cluster', global_config: Optional['GlobalConfig']
ret['pause'] = True
if cluster.failover and cluster.failover.scheduled_at:
ret['scheduled_switchover'] = {'at': cluster.failover.scheduled_at.isoformat()}
if cluster.failover.leader:
ret['scheduled_switchover']['from'] = cluster.failover.leader
if TYPE_CHECKING: # pragma: no cover
assert cluster.failover.leader
ret['scheduled_switchover']['from'] = cluster.failover.leader
if cluster.failover.candidate:
ret['scheduled_switchover']['to'] = cluster.failover.candidate
return ret