Exemplo n.º 1
0
    async def invalidate(self, *, data=None, sender=None):
        if isinstance(data, (bytes, str)):
            try:
                data = serialize.loads(data)
            except (TypeError, pickle.UnpicklingError):
                logger.warning("Invalid message")
                return

        assert isinstance(data, dict)
        assert "tid" in data
        assert "keys" in data
        if data["tid"] in self._ignored_tids:
            # on the same thread, ignore this sucker...
            self._ignored_tids.remove(data["tid"])
            return

        for key in data["keys"]:
            if key in self._memory_cache:
                del self._memory_cache[key]

        push = data.get("push", {})
        if isinstance(push, dict):
            for cache_key, ob in push.items():
                self._memory_cache.set(cache_key, ob, self.get_size(ob))

        # clean up possible memory leak
        while len(self._ignored_tids) > 100:
            self._ignored_tids.pop(0)
Exemplo n.º 2
0
    async def invalidate(self, *, data=None, sender=None):
        if isinstance(data, (bytes, str)):
            try:
                data = serialize.loads(data)
            except (TypeError, pickle.UnpicklingError):
                logger.warning("Invalid message")
                return

        assert isinstance(data, dict)
        assert 'tid' in data
        assert 'keys' in data
        if data['tid'] in self._ignored_tids:
            # on the same thread, ignore this sucker...
            self._ignored_tids.remove(data['tid'])
            return

        for key in data['keys']:
            if key in self._memory_cache:
                del self._memory_cache[key]

        for cache_key, ob in data.get('push', {}).items():
            print(f'PUSH {cache_key}')
            self._memory_cache[cache_key] = ob

        # clean up possible memory leak
        while len(self._ignored_tids) > 100:
            self._ignored_tids.pop(0)
Exemplo n.º 3
0
 async def get(self, key):
     try:
         if key in self._memory_cache:
             logger.info('Retrieved {} from memory cache'.format(key))
             return self._memory_cache[key]
         if self._obj_driver is not None:
             val = await self._obj_driver.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
     except Exception:
         logger.warning('Error getting cache value', exc_info=True)
Exemplo n.º 4
0
 async def get(self, key):
     try:
         if key in self._memory_cache:
             logger.debug("Retrieved {} from memory cache".format(key))
             return self._memory_cache[key]
         if self._obj_driver is not None:
             val = await self._obj_driver.get(CACHE_PREFIX + key)
             if val is not None:
                 logger.debug("Retrieved {} from redis cache".format(key))
                 val = serialize.loads(val)
                 size = self.get_size(val)
                 self._memory_cache.set(key, val, size)
                 return val
     except Exception:
         logger.warning("Error getting cache value", exc_info=True)
Exemplo n.º 5
0
async def test_subscriber_ignores_trsn_on_invalidate(redis_container,
                                                     guillotina_main):

    util = get_utility(ICacheUtility)
    await util.initialize()
    assert util.initialized
    assert util._obj_driver is not None
    assert util._subscriber is not None

    trns = mocks.MockTransaction(mocks.MockTransactionManager())
    trns.added = trns.deleted = {}
    content = create_content()
    trns.modified = {content.__uuid__: content}
    rcache = BasicCache(trns)
    await rcache.clear()
    driver = await resolve_dotted_name("guillotina.contrib.redis").get_driver()

    await rcache.set("foobar", oid=content.__uuid__)
    assert serialize.loads(await driver.get(CACHE_PREFIX + "root-" +
                                            content.__uuid__)) == "foobar"
    assert util._memory_cache.get("root-" + content.__uuid__) == "foobar"
    assert await rcache.get(oid=content.__uuid__) == "foobar"

    assert "root-" + content.__uuid__ in util._memory_cache

    util.ignore_tid(5555)

    await driver.publish(
        app_settings["cache"]["updates_channel"],
        pickle.dumps({
            "data":
            serialize.dumps({
                "tid": 5555,
                "keys": ["root-" + content.__uuid__]
            }),
            "ruid":
            "nonce"
        }),
    )
    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.__uuid__ in util._memory_cache
    # tid should also now be removed from ignored list
    assert 5555 not in util._ignored_tids
Exemplo n.º 6
0
async def test_cache_set(redis_container, guillotina_main):
    util = get_utility(ICacheUtility)
    await util.initialize()
    assert util.initialized
    assert util._obj_driver is not None
    trns = mocks.MockTransaction(mocks.MockTransactionManager())
    trns.added = trns.deleted = {}
    rcache = BasicCache(trns)
    await rcache.clear()

    await rcache.set("bar", oid="foo")
    # make sure it is in redis
    driver = await resolve_dotted_name("guillotina.contrib.redis").get_driver()

    val = await driver.get(CACHE_PREFIX + "root-foo")
    assert serialize.loads(val) == "bar"
    # but also in memory
    assert util._memory_cache.get("root-foo") == "bar"
    # and api matches..
    assert await rcache.get(oid="foo") == "bar"
    await util.finalize(None)
Exemplo n.º 7
0
async def test_subscriber_invalidates(redis_container, guillotina_main, loop):
    util = get_utility(ICacheUtility)
    await util.initialize()
    assert util.initialized
    assert util._obj_driver is not None
    assert util._subscriber is not None

    trns = mocks.MockTransaction(mocks.MockTransactionManager())
    trns.added = trns.deleted = {}
    content = create_content()
    trns.modified = {content.__uuid__: content}
    rcache = BasicCache(trns)
    await rcache.clear()

    await rcache.set('foobar', oid=content.__uuid__)
    driver = await resolve_dotted_name('guillotina.contrib.redis').get_driver()

    assert serialize.loads(await driver.get(CACHE_PREFIX + 'root-' +
                                            content.__uuid__)) == "foobar"
    assert util._memory_cache.get('root-' + content.__uuid__) == 'foobar'
    assert await rcache.get(oid=content.__uuid__) == 'foobar'

    assert 'root-' + content.__uuid__ in util._memory_cache

    await driver.publish(
        app_settings['cache']['updates_channel'],
        pickle.dumps({
            'data':
            serialize.dumps({
                'tid': 32423,
                'keys': ['root-' + content.__uuid__]
            }),
            'ruid':
            'nonce'
        }))
    await asyncio.sleep(1)  # should be enough for pub/sub to finish
    assert 'root-' + content.__uuid__ not in util._memory_cache
Exemplo n.º 8
0
async def test_invalidate_object(redis_container, guillotina_main, loop):
    util = get_utility(ICacheUtility)
    await util.initialize()
    assert util.initialized
    assert util._obj_driver is not None
    assert util._subscriber is not None

    trns = mocks.MockTransaction(mocks.MockTransactionManager())
    trns.added = trns.deleted = {}
    content = create_content()
    trns.modified = {content.__uuid__: content}
    rcache = BasicCache(trns)
    await rcache.clear()

    await rcache.set('foobar', oid=content.__uuid__)

    driver = await resolve_dotted_name('guillotina.contrib.redis').get_driver()
    assert serialize.loads(await driver.get(CACHE_PREFIX + 'root-' +
                                            content.__uuid__)) == "foobar"
    assert util._memory_cache.get('root-' + content.__uuid__) == 'foobar'
    assert await rcache.get(oid=content.__uuid__) == 'foobar'

    await rcache.close(invalidate=True)
    assert await rcache.get(oid=content.__uuid__) is None
Exemplo n.º 9
0
async def test_cache_clear(redis_container, guillotina_main, loop):
    util = get_utility(ICacheUtility)
    await util.initialize()

    assert util.initialized
    assert util._obj_driver is not None

    trns = mocks.MockTransaction(mocks.MockTransactionManager())
    trns.added = trns.deleted = {}
    rcache = BasicCache(trns)
    await rcache.clear()

    await rcache.set('bar', oid='foo')
    # make sure it is in redis
    driver = await resolve_dotted_name('guillotina.contrib.redis').get_driver()

    assert serialize.loads(await
                           driver.get(CACHE_PREFIX + 'root-foo')) == "bar"
    assert util._memory_cache.get('root-foo') == 'bar'
    assert await rcache.get(oid='foo') == 'bar'

    await rcache.clear()
    assert await rcache.get(oid='foo') is None
    await util.finalize(None)