예제 #1
0
    def renew(self, new_timeout):
        """
        Sets a new timeout for an already acquired lock.

        ``new_timeout`` can be specified as an integer or a float, both
        representing the number of seconds.
        """
        if self.local.token is None:
            raise LockError("Cannot extend an unlocked lock")
        if self.timeout is None:
            raise LockError("Cannot extend a lock with no timeout")
        return self.do_renew(new_timeout)
예제 #2
0
 def __enter__(self):
     if self.acquire():
         return self
     else:
         if not self.mute_ex:
             raise LockError(
                 f"key: {self.name} still locking, please retry it later")
예제 #3
0
    def do_renew(self, new_timeout):
        pipe = self.redis.pipeline()
        pipe.watch(self.name)
        lock_value = pipe.get(self.name)
        if lock_value != self.local.token:
            raise LockError("Cannot extend a lock that's no longer owned")
        pipe.multi()
        pipe.pexpire(self.name, int(new_timeout * 1000))

        try:
            response = pipe.execute()
        except WatchError:
            # someone else acquired the lock
            raise LockError("Cannot extend a lock that's no longer owned")
        if not response[0]:
            # pexpire returns False if the key doesn't exist
            raise LockError("Cannot extend a lock that's no longer owned")
        return True
예제 #4
0
 def acquire(self, **kwargs):
     if not self.__lock_acquired_time:
         self.__lock_acquired_time = time.time()
         acquired = self.acquire(**kwargs)
         wait_time = (time.time() - self.__lock_acquired_time) * 1000
         if not acquired:
             self.__metrics['acquired_fail'] += 1
             self.__metrics['wait_{}'.format(
                 self.get_interval_for_time(wait_time))] += 1
             raise LockError('Can\'t acquire lock {}'.format(self.name))
         self.__metrics['acquired'] += 1
         self.__metrics['wait_{}'.format(
             self.get_interval_for_time(wait_time))] += 1
     return True
예제 #5
0
    def __init__(self, redis, name, timeout=None, sleep=0.1):
        """
        Create a new Lock instance named ``name`` using the Redis client
        supplied by ``redis``.

        ``timeout`` indicates a maximum life for the lock.
        By default, it will remain locked until release() is called.

        ``sleep`` indicates the amount of time to sleep per loop iteration
        when the lock is in blocking mode and another client is currently
        holding the lock.

        Note: If using ``timeout``, you should make sure all the hosts
        that are running clients have their time synchronized with a network
        time service like ntp.
        """
        self.redis = redis
        self.name = name
        self.acquired_until = None
        self.timeout = timeout
        self.sleep = sleep
        if self.timeout and self.sleep > self.timeout:
            raise LockError("'sleep' must be less than 'timeout'")
예제 #6
0
 def __enter__(self):
     if not self.acquire():
         raise LockError('Can\'t acquire lock {}'.format(self.name))
     return self