Skip to content

Commit

Permalink
share deaduntils between hosts
Browse files Browse the repository at this point in the history
This will help avoid many socket timeout especially when we use
python-memcached with eventlet.

For example,When use eventlet,for each greenlet we call client.get
first time,the client will be rebuild,and client.servers[*].deaduntil
will be 0.For each http request,we will have one greenlet.So we get
a socket timeout for each request.
This could be fixed in application,but i believe it's better to fix
it in python-memcached.
  • Loading branch information
octupszhang committed Jun 10, 2016
1 parent b13d6fc commit 52c4c91
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion memcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -1330,6 +1330,9 @@ def check_key(self, key, key_extra_len=0):
"Control/space characters not allowed (key=%r)" % key)


_host_last_deaduntils = {}


class _Host(object):

def __init__(self, host, debug=0, dead_retry=_DEAD_RETRY,
Expand Down Expand Up @@ -1371,7 +1374,7 @@ def __init__(self, host, debug=0, dead_retry=_DEAD_RETRY,
self.port = int(hostData.get('port') or 11211)
self.address = (self.ip, self.port)

self.deaduntil = 0
self.deaduntil = _host_last_deaduntils.get(self.ip, 0)
self.socket = None
self.flush_on_next_connect = 0

Expand All @@ -1395,6 +1398,7 @@ def connect(self):
def mark_dead(self, reason):
self.debuglog("MemCache: %s: %s. Marking dead." % (self, reason))
self.deaduntil = time.time() + self.dead_retry

if self.flush_on_reconnect:
self.flush_on_next_connect = 1
self.close_socket()
Expand All @@ -1411,6 +1415,7 @@ def _get_socket(self):
s.connect(self.address)
except socket.timeout as msg:
self.mark_dead("connect: %s" % msg)
_host_last_deaduntils[self.ip] = self.deaduntil
return None
except socket.error as msg:
if isinstance(msg, tuple):
Expand Down

0 comments on commit 52c4c91

Please sign in to comment.