Bug fix: Memcached does not allow negative numbers passed to incr. Adding/using decr.
This commit is contained in:
commit
358f3740d9
@ -190,6 +190,32 @@ class MemcacheRing(object):
|
||||
except Exception, e:
|
||||
self._exception_occurred(server, e)
|
||||
|
||||
def decr(self, key, delta=1, timeout=0):
|
||||
"""
|
||||
Decrements a key which has a numeric value by delta.
|
||||
If the key can't be found, it's added as 0. Memcached
|
||||
will treat data values below 0 as 0 with incr/decr.
|
||||
|
||||
:param key: key
|
||||
:param delta: amount to subtract to the value of key (or set
|
||||
as the value if the key is not found)
|
||||
:param timeout: ttl in memcache
|
||||
"""
|
||||
key = md5hash(key)
|
||||
for (server, fp, sock) in self._get_conns(key):
|
||||
try:
|
||||
sock.sendall('decr %s %s\r\n' % (key, delta))
|
||||
line = fp.readline().strip().split()
|
||||
if line[0].upper() == 'NOT_FOUND':
|
||||
line[0] = '0'
|
||||
sock.sendall('add %s %d %d %s noreply\r\n%s\r\n' %
|
||||
(key, 0, timeout, len(line[0]), line[0]))
|
||||
ret = int(line[0].strip())
|
||||
self._return_conn(server, fp, sock)
|
||||
return ret
|
||||
except Exception, e:
|
||||
self._exception_occurred(server, e)
|
||||
|
||||
def delete(self, key):
|
||||
"""
|
||||
Deletes a key/value pair from memcache.
|
||||
|
@ -148,7 +148,7 @@ class RateLimitMiddleware(object):
|
||||
max_sleep_m = self.max_sleep_time_seconds * self.clock_accuracy
|
||||
if max_sleep_m - need_to_sleep_m <= self.clock_accuracy * 0.01:
|
||||
# treat as no-op decrement time
|
||||
self.memcache_client.incr(key, delta=-time_per_request_m)
|
||||
self.memcache_client.decr(key, delta=time_per_request_m)
|
||||
raise MaxSleepTimeHit("Max Sleep Time Exceeded: %s" %
|
||||
need_to_sleep_m)
|
||||
|
||||
|
@ -36,9 +36,19 @@ class FakeMemcache(object):
|
||||
return True
|
||||
|
||||
def incr(self, key, delta=1, timeout=0):
|
||||
if delta < 0:
|
||||
raise "Cannot incr by a negative number"
|
||||
self.store[key] = int(self.store.setdefault(key, 0)) + delta
|
||||
return int(self.store[key])
|
||||
|
||||
def decr(self, key, delta=1, timeout=0):
|
||||
if delta < 0:
|
||||
raise "Cannot decr by a negative number"
|
||||
self.store[key] = int(self.store.setdefault(key, 0)) - delta
|
||||
if self.store[key] < 0:
|
||||
self.store[key] = 0
|
||||
return int(self.store[key])
|
||||
|
||||
@contextmanager
|
||||
def soft_lock(self, key, timeout=0, retries=5):
|
||||
yield True
|
||||
|
Loading…
x
Reference in New Issue
Block a user