@classmethod
    def load(cls, region, namespace, key, regenerate=True, callable=None,
             statistics=None):
        """Load a value from Redis, and possibly recreate it

        This method is used to load a value from Redis, and usually
        regenerates the value using the callable when provided.

        If ``regenerate`` is ``False`` and a ``callable`` is not passed
        in, then :obj:`~retools.cache.NoneMarker` will be returned.

        :param region: Region name
        :type region: string
        :param namespace: Namespace for the value
        :type namespace: string
        :param key: Key for this value under the namespace
        :type key: string
        :param regenerate: If False, then existing keys will always be
                           returned regardless of cache expiration. In the
                           event that there is no existing key and no
                           callable was provided, then a NoneMarker will
                           be returned.
        :type regenerate: bool
        :param callable: A callable to use when the cached value needs to be
                         created
        :param statistics: Whether or not hit/miss statistics should be
                           updated
        :type statistics: bool

        """
        if statistics is None:
            statistics = cls.statistics
        redis = global_connection.redis
        now = time.time()
        region_settings = cls.regions[region]
        expires = region_settings['expires']
        redis_expiration = region_settings['redis_expiration']

        keys = CacheKey(region=region, namespace=namespace, key=key)

        # Create a transaction to update our hit counter for today and
        # retrieve the current value.
        if statistics:
            p = redis.pipeline(transaction=True)
            p.hgetall(keys.redis_key)
            p.get(keys.redis_hit_key)
            p.incr(keys.redis_hit_key)
            results = p.execute()
            result, existing_hits = results[0], results[1]
            if existing_hits is None:
                existing_hits = 0
            else:
                existing_hits = int(existing_hits)
        else:
            result = redis.hgetall(keys.redis_key)

        expired = True
        if result and now - float(result['created']) < expires:
            expired = False

        if (result and not regenerate) or not expired:
            # We have a result and were told not to regenerate so
            # we always return it immediately regardless of expiration,
            # or its not expired
            return cPickle.loads(result['value'])

        if not result and not regenerate:
            # No existing value, but we were told not to regenerate it and
            # there's no callable, so we return a NoneMarker
            return NoneMarker

        # Don't wait for the lock if we have an old value
        if result and 'value' in result:
            timeout = 0
        else:
            timeout = 60 * 60

        try:
            with Lock(keys.lock_key, expires=expires, timeout=timeout):
                # Did someone else already create it?
                result = redis.hgetall(keys.redis_key)
                now = time.time()
                if result and 'value' in result and \
                   now - float(result['created']) < expires:
                    return cPickle.loads(result['value'])

                value = callable()

                p = redis.pipeline(transaction=True)
                p.hmset(keys.redis_key, {'created': now,
                                    'value': cPickle.dumps(value)})
                p.expire(keys.redis_key, redis_expiration)
                cls._add_tracking(p, region, namespace, key)
                if statistics:
                    p.getset(keys.redis_hit_key, 0)
                    new_hits = int(p.execute()[0])
                else:
                    p.execute()
        except LockTimeout:
            if result:
                return cPickle.loads(result['value'])
            else:
                # log some sort of error?
                return NoneMarker

        # Nothing else to do if not recording stats
        if not statistics:
            return value

        misses = new_hits - existing_hits
        if misses:
            p = redis.pipeline(transaction=True)
            p.incr(keys.redis_hit_key, amount=existing_hits)
            p.incr(keys.redis_miss_key, amount=misses)
            p.execute()
        else:
            redis.incr(keys.redis_hit_key, amount=existing_hits)
        return value
dataset/ETHPy150Open bbangert/retools/retools/cache.py/CacheRegion.load/original