mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-01-27 10:20:10 +00:00
Implement Failover.is_failover/switchover properties
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user