async def runit(): print(f'Test content serialization') start = time.time() for _ in range(ITERATIONS): blah = serialize.dumps({ 'dlsfkds': 'dslfkdsf', 'dslfks': 'sdlfkjds', 'state': b'X' * ITERATIONS }) serialize.loads(blah) end = time.time() print(f'Done with {ITERATIONS} in {end - start} seconds')
async def test_subscriber_invalidates(redis_container, dummy_guillotina, loop): await cache.close_redis_pool() trns = mocks.MockTransaction(mocks.MockTransactionManager()) trns.added = trns.deleted = {} content = create_content() trns.modified = {content._p_oid: content} rcache = RedisCache(trns, loop=loop) await rcache.clear() await rcache.set('foobar', oid=content._p_oid) assert serialize.loads( await rcache._redis.get( CACHE_PREFIX + 'root-' + content._p_oid)) == "foobar" assert rcache._memory_cache.get( 'root-' + content._p_oid) == 'foobar' assert await rcache.get(oid=content._p_oid) == 'foobar' assert 'root-' + content._p_oid in rcache._memory_cache await rcache._redis.publish( app_settings['redis']['updates_channel'], serialize.dumps({ 'tid': 32423, 'keys': ['root-' + content._p_oid] })) await asyncio.sleep(1) # should be enough for pub/sub to finish assert 'root-' + content._p_oid not in rcache._memory_cache await cache.close_redis_pool()
async def test_subscriber_ignores_trsn_on_invalidate( redis_container, dummy_guillotina, loop): await cache.close_redis_pool() trns = mocks.MockTransaction(mocks.MockTransactionManager()) trns.added = trns.deleted = {} content = create_content() trns.modified = {content._p_oid: content} rcache = RedisCache(trns, loop=loop) await rcache.clear() await rcache.set('foobar', oid=content._p_oid) assert serialize.loads( await rcache._redis.get( CACHE_PREFIX + 'root-' + content._p_oid)) == "foobar" assert rcache._memory_cache.get('root-' + content._p_oid) == 'foobar' assert await rcache.get(oid=content._p_oid) == 'foobar' assert 'root-' + content._p_oid in rcache._memory_cache utility = getUtility(IRedisChannelUtility) utility.ignore_tid(5555) await rcache._redis.publish( app_settings['redis']['updates_channel'], serialize.dumps({ 'tid': 5555, 'keys': ['root-' + content._p_oid] })) await asyncio.sleep(1) # should be enough for pub/sub to finish # should still be there because we set to ignore this tid assert 'root-' + content._p_oid in rcache._memory_cache # tid should also now be removed from ignored list assert 5555 not in utility._ignored_tids await cache.close_redis_pool()
async def get(self, **kwargs): key = self.get_key(**kwargs) try: if key in self._memory_cache: logger.info('Retrieved {} from memory cache'.format(key)) return self._memory_cache[key] conn = await self.get_redis() val = await conn.get(CACHE_PREFIX + key) if val is not None: logger.info('Retrieved {} from redis cache'.format(key)) val = serialize.loads(val) self._memory_cache[key] = val return val except Exception: logger.warning('Error getting cache value', exc_info=True)
async def test_cache_set(redis_container, dummy_guillotina, loop): await cache.close_redis_pool() trns = mocks.MockTransaction(mocks.MockTransactionManager()) trns.added = trns.deleted = {} rcache = RedisCache(trns, loop=loop) await rcache.clear() await rcache.set('bar', oid='foo') # make sure it is in redis val = await rcache._redis.get(CACHE_PREFIX + 'root-foo') assert serialize.loads(val) == "bar" # but also in memory assert rcache._memory_cache.get('root-foo') == 'bar' # and api matches.. assert await rcache.get(oid='foo') == 'bar' await cache.close_redis_pool()
async def test_cache_clear(redis_container, dummy_guillotina, loop): await cache.close_redis_pool() trns = mocks.MockTransaction(mocks.MockTransactionManager()) trns.added = trns.deleted = {} rcache = RedisCache(trns, loop=loop) await rcache.clear() await rcache.set('bar', oid='foo') # make sure it is in redis assert serialize.loads(await rcache._redis.get(CACHE_PREFIX + 'foo')) == "bar" assert rcache._memory_cache.get('foo') == 'bar' assert await rcache.get(oid='foo') == 'bar' await rcache.clear() assert await rcache.get(oid='foo') is None await cache.close_redis_pool()
async def test_invalidate_object(redis_container, dummy_guillotina, loop): await cache.close_redis_pool() trns = mocks.MockTransaction(mocks.MockTransactionManager()) trns.added = trns.deleted = {} content = create_content() trns.modified = {content._p_oid: content} rcache = RedisCache(trns, loop=loop) await rcache.clear() await rcache.set('foobar', oid=content._p_oid) assert serialize.loads(await rcache._redis.get(CACHE_PREFIX + content._p_oid)) == "foobar" assert rcache._memory_cache.get(content._p_oid) == 'foobar' assert await rcache.get(oid=content._p_oid) == 'foobar' await rcache.close(invalidate=True) assert await rcache.get(oid=content._p_oid) is None await cache.close_redis_pool()
async def initialize(self, app=None): settings = app_settings['redis'] while True: try: self._pool = await cache.get_redis_pool(self._loop) self._redis = aioredis.Redis(self._pool) res = await self._redis.subscribe(settings['updates_channel']) ch = res[0] while (await ch.wait_message()): try: msg = serialize.loads(await ch.get()) await self.invalidate(msg) except (TypeError, pickle.UnpicklingError): pass except (asyncio.CancelledError, RuntimeError): # task cancelled, let it die return except Exception: logger.warn( 'Error subscribing to redis changes. Waiting before trying again', exc_info=True) await asyncio.sleep(5)