2011-11-01 14 views
7

Related to this question.opinión Django Código Memcache: Comparar y establecer

Estoy tratando de implementar un incremento del contador en memcached usando Memcache’s compare and set.

Puede alguien revisar el código para posibles lagunas?

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 

Además, ya estoy usando una API memcached interna no está disponible a través de Django, ¿esto añada el prefijo clave me puse a través de la configuración. Si no, ¿cómo puedo agregar la clave para esta llamada API interna?

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

Respuesta

4

Realmente no estoy respondiendo a su pregunta directamente, pero no puedo evitar preguntar por qué no es justo con el método incr() atómicamente para incrementar un valor - que es para lo que sirve. Tal vez acabas de publicar un ejemplo, pero si es así, es una pregunta engañosa.

+0

Guido responde esto: http://neopythonic.blogspot.com/2011/08/compare-and-set-in-memcache.html. incr no aumenta cuando no hay ningún valor establecido. Ahora cuando intentas establecer un valor, hay una condición de carrera. CAS intenta resolver esa condición de carrera. –

+0

El protocolo binario 'incr' le permite especificar un valor de inicio. Antes de eso, acaba de hacer un agregar y luego incr. – Dustin

+0

@Dustin Incr no hace eso en la implementación de memcache python 'incr (self, key, delta = 1) método de memcache.Client instancia Envía un comando al servidor para incrementar atómicamente el valor para C {key} por C {delta}, o por 1 si C {delta} no está especificado. Devuelve None si C {key} no existe en el servidor; de lo contrario, devuelve el nuevo valor después de incrementarse. Tenga en cuenta que el valor de C {clave} ya debe existir en la Memcache, y debe ser la representación de cadena de un entero. –

2

Aparte de algunos de los comentarios anteriores, descubrí que, por defecto, la compatibilidad con cas está deshabilitada en el cliente de python-memcached. Dado que Django no admite una forma de agregar atributos al constructor, he tenido que añadir:

client._cache.cache_cas = True

el fin de obtener cas() para utilizar realmente el comando cas. Además, lea acerca de los reset_cas en la fuente: http://bazaar.launchpad.net/~python-memcached-team/python-memcached/trunk/view/head:/memcache.py