Skip to content

Commit

Permalink
Return "demote reason" more precise depending on cluster state
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Kukushkin committed Mar 24, 2016
1 parent 9c41ce9 commit d4cb151
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 12 deletions.
13 changes: 6 additions & 7 deletions patroni/ha.py
Expand Up @@ -115,25 +115,25 @@ def recover(self):
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))
Expand Down Expand Up @@ -277,7 +277,6 @@ def demote(self, delete_leader=True):
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:
Expand Down
10 changes: 5 additions & 5 deletions tests/test_ha.py
Expand Up @@ -110,25 +110,25 @@ def test_touch_member(self):

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))
Expand Down

0 comments on commit d4cb151

Please sign in to comment.