summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--memcache.py22
2 files changed, 25 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index e3f89f3..4387de6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+ * Bug: #741090: cas cache can grow unbounded. Default now is that the
+ cache is not used, unless the "Client()" object is created with
+ "cache_cas=True". In that case, you need to have your own cas clearing
+ code, a simple one would be to use Client().reset_cas() to completely
+ clear the cas_ids cache. Problem pointed out by Shaun Cutts.
+
* Bug: #794456: Spaces in memcache keynames
Now allow spaces in keys. Proposed by cpaetzel.
diff --git a/memcache.py b/memcache.py
index 53e52b3..1baa11b 100644
--- a/memcache.py
+++ b/memcache.py
@@ -159,7 +159,8 @@ class Client(local):
pickler=pickle.Pickler, unpickler=pickle.Unpickler,
pload=None, pid=None, server_max_key_length=SERVER_MAX_KEY_LENGTH,
server_max_value_length=SERVER_MAX_VALUE_LENGTH,
- dead_retry=_DEAD_RETRY, socket_timeout=_SOCKET_TIMEOUT):
+ dead_retry=_DEAD_RETRY, socket_timeout=_SOCKET_TIMEOUT,
+ cache_cas = False):
"""
Create a new Client object with the given list of servers.
@@ -177,6 +178,10 @@ class Client(local):
server. Default to 30 s.
@param socket_timeout: timeout in seconds for all calls to a server. Defaults
to 3 seconds.
+ @param cache_cas: (default False) If true, cas operations will be
+ cached. WARNING: This cache is not expired internally, if you have
+ a long-running process you will need to expire it manually via
+ "client.reset_cas(), or the cache can grow unlimited.
"""
local.__init__(self)
self.debug = debug
@@ -184,7 +189,8 @@ class Client(local):
self.socket_timeout = socket_timeout
self.set_servers(servers)
self.stats = {}
- self.cas_ids = {}
+ self.cache_cas = cache_cas
+ self.reset_cas()
# Allow users to modify pickling/unpickling behavior
self.pickleProtocol = pickleProtocol
@@ -203,6 +209,16 @@ class Client(local):
except TypeError:
self.picklerIsKeyword = False
+ def reset_cas(self):
+ """
+ Reset the cas cache. This is only used if the Client() object
+ was created with "cache_cas=True". If used, this cache does not
+ expire internally, so it can grow unbounded if you do not clear it
+ yourself.
+ """
+ self.cas_ids = {}
+
+
def set_servers(self, servers):
"""
Set the pool of servers used by this client.
@@ -803,7 +819,7 @@ class Client(local):
if cmd == 'gets':
rkey, flags, rlen, cas_id, = self._expect_cas_value(server)
- if rkey:
+ if rkey and self.cache_cas:
self.cas_ids[rkey] = cas_id
else:
rkey, flags, rlen, = self._expectvalue(server)