Example #1
0
    async def test_destroy_lock_manager(self, lock_manager_redis_patched):
        lock_manager, redis = lock_manager_redis_patched
        lock_manager.unlock = MagicMock(side_effect=LockError('Can not lock'))

        await lock_manager.lock("resource", 1.0)
        await lock_manager.destroy()

        redis.clear_connections.assert_called_once_with()
Example #2
0
    async def test_extend_lock_error(self, lock_manager_redis_patched, locked_lock):
        lock_manager, redis = lock_manager_redis_patched
        lock = await lock_manager.lock('resource')

        redis.set_lock = CoroutineMock(side_effect=LockError('Can not lock'))

        with pytest.raises(LockError):
            await lock_manager.extend(lock)
Example #3
0
    async def test_lock_expire_retries(self, lock_manager_redis_patched, locked_lock):
        lock_manager, redis = lock_manager_redis_patched
        redis.set_lock = CoroutineMock(side_effect=[
            LockError('Can not lock'),
            LockError('Can not lock'),
            LockError('Can not lock')
        ])

        with pytest.raises(LockError):
            await lock_manager.lock('resource', 1.0)

        await real_sleep(0.1)  # wait until cleaning is completed

        calls = [
            call('resource', ANY, 1.0),
            call('resource', ANY, 1.0),
            call('resource', ANY, 1.0)
        ]
        redis.set_lock.assert_has_calls(calls)
        redis.unset_lock.assert_called_once_with('resource', ANY)
Example #4
0
    async def test_lock_one_retry(self, lock_manager_redis_patched,
                                  locked_lock):
        lock_manager, redis = lock_manager_redis_patched
        redis.set_lock = CoroutineMock(
            side_effect=[LockError('Can not lock'), 0.001])

        lock = await lock_manager.lock('resource')

        calls = [call('resource', ANY), call('resource', ANY)]
        redis.set_lock.assert_has_calls(calls)
        redis.unset_lock.assert_not_called()
        assert lock.resource == 'resource'
        assert lock.id == ANY
        assert lock.valid is True
Example #5
0
    async def handle_message(self, message: SQSMessage) -> tuple:
        """
        Method that hold logic to handle a certain type of mesage

        :param message: Message to handle
        :raises LockError: If lock could not be acquired for the message
        :raises Exception: General exception handler attaches the message and message handler
        :return: Returns a tuple of the message and result of the handler
        """
        lock = None

        try:
            lock = await self.lock_manager.lock(
                self.lock_key.format(message_id=message.message_id)
            )
            if not lock.valid:
                raise LockError(
                    f"Could not acquire lock for {message.message_id}"
                )

            if message.event in self.handlers:
                handler = self.handlers[message.event]
            elif default in self.handlers:
                handler = self.handlers[default]
            else:
                raise KeyError(f"{message.event} handler not found!")

        except Exception as e:
            e.message = message
            e.handler = None
            raise e
        else:
            try:
                result = handler(message)
                if isawaitable(result):
                    result = await result

                return message, result
            except Exception as e:
                e.message = message
                e.handler = handler
                raise e
        finally:
            if lock:
                await self.lock_manager.unlock(lock)
Example #6
0
    async def test_lock_one_retry(self, lock_manager_redis_patched,
                                  locked_lock):
        lock_manager, redis = lock_manager_redis_patched
        future = asyncio.Future()
        future.set_result(0.001)
        redis.set_lock = MagicMock(side_effect=[
            LockError('Can not lock'),
            future,
        ])

        lock = await lock_manager.lock('resource', 1.0)

        calls = [call('resource', ANY, 1.0), call('resource', ANY, 1.0)]
        redis.set_lock.assert_has_calls(calls)
        redis.unset_lock.assert_not_called()
        assert lock.resource == 'resource'
        assert lock.id == ANY
        assert lock.valid is True