async def decorator(self, f, *args, cache_read=True, cache_write=True, aiocache_wait_for_write=True, **kwargs): key = self.get_cache_key(f, args, kwargs) if cache_read: value = await self.get_from_cache(key) if value is not None: return value async with RedLock(self.cache, key, self.lease): value = await self.get_from_cache(key) if value is not None: return value result = await f(*args, **kwargs) if cache_write: if aiocache_wait_for_write: await self.set_in_cache(key, result) else: asyncio.ensure_future(self.set_in_cache(key, result)) return result
async def my_view(): async with RedLock(cache, 'key', lease=2): # Wait at most 2 seconds result = await cache.get('key') if result is not None: logger.info('Found the value in the cache hurray!') return result result = await expensive_function() await cache.set('key', result) return result
async def dummy(): res = await cache.get(pytest.KEY) if res is not None: return res async with RedLock(cache, pytest.KEY, lease=1): res = await cache.get(pytest.KEY) if res is not None: return res await asyncio.sleep(1.1) await cache.set(pytest.KEY, "value")
async def decorator(self, f, *args, **kwargs): key = self.get_cache_key(f, args, kwargs) value = await self.get_from_cache(key) if value is not None: return value async with RedLock(self.cache, key, self.lease): value = await self.get_from_cache(key) if value is not None: return value result = await f(*args, **kwargs) await self.set_in_cache(key, result) return result
async def test_multiple_locks_lock(self, mock_cache, lock): lock_1 = RedLock(mock_cache, pytest.KEY, 20) lock_2 = RedLock(mock_cache, pytest.KEY, 20) mock_cache._add.side_effect = [True, ValueError(), ValueError()] await lock._acquire() event = lock._EVENTS[pytest.KEY + '-lock'] assert pytest.KEY + '-lock' in lock._EVENTS assert pytest.KEY + '-lock' in lock_1._EVENTS assert pytest.KEY + '-lock' in lock_2._EVENTS assert not event.is_set() await asyncio.gather(lock_1._acquire(), lock._release(), lock_2._acquire()) assert pytest.KEY + '-lock' not in lock._EVENTS assert pytest.KEY + '-lock' not in lock_1._EVENTS assert pytest.KEY + '-lock' not in lock_2._EVENTS assert event.is_set()
async def test_release_wrong_client_fails(self, memory_cache, lock): wrong_lock = RedLock(memory_cache, pytest.KEY, 20) await lock.__aenter__() assert await wrong_lock.__aexit__("exc_type", "exc_value", "traceback") is None
def lock(self, memory_cache): return RedLock(memory_cache, pytest.KEY, 20)
def lock(cache): return RedLock(cache, pytest.KEY, 20)
async def dummy(): async with RedLock(cache, pytest.KEY, lease=1): raise ValueError()
async def test_float_lease(self, memcached_cache): lock = RedLock(memcached_cache, pytest.KEY, 0.1) with pytest.raises(TypeError): await lock.__aenter__()
async def test_float_lease(self, redis_cache): lock = RedLock(redis_cache, pytest.KEY, 0.1) await lock.__aenter__() await asyncio.sleep(0.2) assert await lock.__aexit__("exc_type", "exc_value", "traceback") is None
def lock(self, redis_cache): return RedLock(redis_cache, pytest.KEY, 20)
def lock(self, mock_cache): RedLock._EVENTS = {} yield RedLock(mock_cache, pytest.KEY, 20)
async def test_release_wrong_client_succeeds_meh(self, memcached_cache, lock): wrong_lock = RedLock(memcached_cache, pytest.KEY, 20) await lock.__aenter__() assert await wrong_lock.__aexit__("exc_type", "exc_value", "traceback") == 1