summaryrefslogtreecommitdiff
path: root/pymemcache/client
diff options
context:
space:
mode:
authorLukasz Czaplinski <scoiatael@users.noreply.github.com>2020-04-04 20:58:47 +0200
committerGitHub <noreply@github.com>2020-04-04 11:58:47 -0700
commitda89f48496493bf9075d8531e26dae42e0fd0dd9 (patch)
treeaa67fd532fa1d49fda8c67adc236ddd7dc492414 /pymemcache/client
parentb5d586092fced9e5483fcd03f034c8478376ed72 (diff)
downloadpymemcache-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.py34
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