2011-11-01 27 views
7

Related to this question.Django的内存缓存代码审查:比较,并设置

我试图实现使用Memcache’s compare and set在memcached的计数器增量。

有人可以查看此代码潜在的漏洞

def increment(id): 
    client = get_cache('memcache') 
    i = 0 
    items = 0 
    while i <= 3: 
     counter = client._cache.gets(id) 
     if counter is not None: 
      items = client._cache.cas(id, counter+1) 
      if items: 
       break 
     else: 
      items = client._cache.add(id, 0) 
      if items: 
       break 
     i+= 1 
    return items 

此外,因为我使用的是内部的memcached API无法通过Django的,这是否追加键前缀我在设置中设置通过。如果不是我可以如何追加这个内部API调用的密钥?

'memcache': { 
    'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 
    'LOCATION': '127.0.0.1:11211', 
    'KEY_PREFIX': 'store_', 
} 

回答

4

我真的不直接回答你的问题,但我不禁要问,为什么你不只是使用incr()方法原子递增值 - 这就是它是。也许你只是举了一个例子,但如果是这样的话,那么这是一个误导性的问题。

+0

Guido解答了这个问题:http://neopythonic.blogspot.com/2011/08/compare-and-set-in-memcache.html。没有设置值时incr不增加。现在,当您尝试设置一个值时,就会出现竞争状态。 CAS试图解决这种竞争条件。 –

+0

二进制协议'incr'允许您指定一个起始值。在此之前,你只需要做一个增加然后incr。 – Dustin

+0

@Dustin Incr不会在python内存缓存实现中执行此操作 memcache.client实例的incr(self,key,delta = 1)方法 向服务器发送命令以原子方式递增C {key}的值 C {delta},如果C {delta}未指定,则加1。 如果服务器上不存在C {密钥},则返回None,否则在增量后 返回新值。 请注意,C {key}的值必须已经存在于内存缓存中, 并且它必须是整数的字符串表示形式。# –