diff options
author | Lukasz Czaplinski <scoiatael@users.noreply.github.com> | 2020-04-04 20:58:47 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-04 11:58:47 -0700 |
commit | da89f48496493bf9075d8531e26dae42e0fd0dd9 (patch) | |
tree | aa67fd532fa1d49fda8c67adc236ddd7dc492414 /pymemcache/client | |
parent | b5d586092fced9e5483fcd03f034c8478376ed72 (diff) | |
download | pymemcache-da89f48496493bf9075d8531e26dae42e0fd0dd9.tar.gz |
Fix corner case with dead server coming back alive (#275)
Looks like clients/hash behaves incorrectly when dead server comes back alive - it's never removed from dead_clients and thus retried indefinitely.
Failing test and fix are visible in 35ee9de, rest of PR simply adds some test coverage and refactors existing code a little.
Diffstat (limited to 'pymemcache/client')
-rw-r--r-- | pymemcache/client/hash.py | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/pymemcache/client/hash.py b/pymemcache/client/hash.py index c2cb23e..fccb060 100644 --- a/pymemcache/client/hash.py +++ b/pymemcache/client/hash.py @@ -121,22 +121,28 @@ class HashClient(object): key = '%s:%s' % (server, port) self.hasher.remove_node(key) + def _retry_dead(self): + current_time = time.time() + ldc = self._last_dead_check_time + # We have reached the retry timeout + if current_time - ldc > self.dead_timeout: + candidates = [] + for server, dead_time in self._dead_clients.items(): + if current_time - dead_time > self.dead_timeout: + candidates.append(server) + for server in candidates: + logger.debug( + 'bringing server back into rotation %s', + server + ) + self.add_server(*server) + del self._dead_clients[server] + self._last_dead_check_time = current_time + def _get_client(self, key): check_key_helper(key, self.allow_unicode_keys, self.key_prefix) - if len(self._dead_clients) > 0: - current_time = time.time() - ldc = self._last_dead_check_time - # we have dead clients and we have reached the - # timeout retry - if current_time - ldc > self.dead_timeout: - for server, dead_time in self._dead_clients.items(): - if current_time - dead_time > self.dead_timeout: - logger.debug( - 'bringing server back into rotation %s', - server - ) - self.add_server(*server) - self._last_dead_check_time = current_time + if self._dead_clients: + self._retry_dead() server = self.hasher.get_node(key) # We've ran out of servers to try |