From d4cb15179f2f29ceb5bbdee310febf146df63c65 Mon Sep 17 00:00:00 2001 From: Alexander Kukushkin Date: Thu, 24 Mar 2016 14:52:27 +0100 Subject: [PATCH] Return "demote reason" more precise depending on cluster state --- patroni/ha.py | 13 ++++++------- tests/test_ha.py | 10 +++++----- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/patroni/ha.py b/patroni/ha.py index f85064fc..d4d7fb93 100644 --- a/patroni/ha.py +++ b/patroni/ha.py @@ -115,25 +115,25 @@ class Ha(object): if pg_controldata and pg_controldata.get('Database cluster state', '') == 'in production': # crashed master self.state_handler.require_rewind() self.recovering = True - return self.follow("started as readonly because i had the session lock", "started as a secondary", True, True) + return self.follow("starting as readonly because i had the session lock", "starting as a secondary", True, True) def follow(self, demote_reason, follow_reason, refresh=True, recovery=False): if refresh: self.load_cluster_from_dcs() - if not recovery and self.state_handler.is_leader() or recovery and self.state_handler.role == 'master': - ret = demote_reason - else: - ret = follow_reason + ret = demote_reason if not recovery and self.state_handler.is_leader() else follow_reason # determine the node to follow. If replicatefrom tag is set, # try to follow the node mentioned there, otherwise, follow the leader. + if self.patroni.replicatefrom: node_to_follow = [m for m in self.cluster.members if m.name == self.patroni.replicatefrom] node_to_follow = node_to_follow[0] if node_to_follow else self.cluster.leader else: node_to_follow = self.cluster.leader - node_to_follow = None if node_to_follow and node_to_follow.name == self.state_handler.name else node_to_follow + if node_to_follow and node_to_follow.name == self.state_handler.name: + ret = demote_reason + node_to_follow = None if not self.state_handler.check_recovery_conf(node_to_follow) or recovery: self._async_executor.schedule('changing primary_conninfo and restarting') self._async_executor.run_async(self.state_handler.follow, (node_to_follow, recovery)) @@ -277,7 +277,6 @@ class Ha(object): self.dcs.delete_leader() self.touch_member() self.dcs.reset_cluster() - self.state_handler.set_role('replica') sleep(2) # Give a time to somebody to promote self.recover() else: diff --git a/tests/test_ha.py b/tests/test_ha.py index 8ee8748b..d81d5bbd 100644 --- a/tests/test_ha.py +++ b/tests/test_ha.py @@ -110,25 +110,25 @@ class TestHa(unittest.TestCase): def test_start_as_replica(self): self.p.is_healthy = false - self.assertEquals(self.ha.run_cycle(), 'started as a secondary') + self.assertEquals(self.ha.run_cycle(), 'starting as a secondary') def test_recover_replica_failed(self): self.p.controldata = lambda: {'Database cluster state': 'in production'} self.p.is_healthy = false self.p.is_running = false self.p.follow = false - self.assertEquals(self.ha.run_cycle(), 'started as a secondary') + self.assertEquals(self.ha.run_cycle(), 'starting as a secondary') self.assertEquals(self.ha.run_cycle(), 'failed to start postgres') def test_recover_master_failed(self): self.p.follow = false self.p.is_healthy = false self.p.is_running = false - self.ha.has_lock = true + self.p.name = 'leader' self.p.set_role('master') self.p.controldata = lambda: {'Database cluster state': 'in production'} - self.assertEquals(self.ha.run_cycle(), 'started as readonly because i had the session lock') - self.assertEquals(self.ha.run_cycle(), 'removed leader key after trying and failing to start postgres') + self.ha.cluster = get_cluster_initialized_with_leader() + self.assertEquals(self.ha.run_cycle(), 'starting as readonly because i had the session lock') @patch('sys.exit', return_value=1) @patch('patroni.ha.Ha.sysid_valid', MagicMock(return_value=True))