2009-09-16 7 views

Répondre

3

Si vous avez besoin de ce type de contrôle à expiration, vous devrez reporter l'heure d'expiration de l'élément stocké à côté de l'élément lui-même.

La façon dont cela est généralement réalisé passe par une couche de sérialisation. Les entrées écrites dans memcached sont stockées sous la forme de l'entrée elle-même et d'un horodatage. Lorsque l'entrée est désérialisée, l'horodatage est vérifié et, s'il a expiré, l'entrée de lecture est rejetée et traitée comme un échec de cache.

[ entry, expiresAt ] 

Le TTL sur les entrées brutes memcached est généralement définie à l'infini et les entrées ne sont effacés à partir du cache manuellement ou via la politique LRU.

Dans la FAQ memcached, il y a une section sur preventing stampeding requests qui touche à cette technique.

0

Vous devrez stocker lorsque la valeur a été mise en cache, avec sa valeur de délai d'expiration d'origine. Voici une implémentation Python:

class ExpiringCache(BaseCache): 
    """A cache that allows you to update values without changing when the 
    data will expire. We do this by storing when the value was 
    inserted in the cache and decrementing the timeout when we update. 

    """ 
    def get(self, key, *args, **kwargs): 
     raw_value = super(ExpiringCache, self).get(key, *args, **kwargs) 

     # we get None on a cache miss, but otherwise it's a 3-tuple 
     if raw_value is None: 
      return None 

     value, start_time, timeout = raw_value 
     return value 

    def set(self, key, value, *args, **kwargs): 
     timeout = kwargs.get('timeout') 

     raw_value = (value, now(), timeout) 
     super(ExpiringCache, self).set(key, raw_value, *args, **kwargs) 

    def update(self, key, value, timeout=None): 
     """If this value is still in the cache, update it but reduce the 
     timeout. If it's not present, just set it. 

     """ 
     raw_value = super(ExpiringCache, self).get(key) 

     if raw_value is None: 
      self.set(key, value, timeout=timeout) 
      return 

     original_value, start_time, original_timeout = raw_value 

     if not original_timeout: 
      # we are caching without a timeout, so just set the new value 
      self.set(key, value, timeout=original_timeout) 
      return 

     elapsed_time = (now() - start_time).total_seconds() 
     remaining_timeout = timeout - elapsed_time 

     if remaining_timeout > 0: 
      self.set(key, value, timeout=remaining_timeout) 
Questions connexes