aiocache icon indicating copy to clipboard operation
aiocache copied to clipboard

Calling 'clear' on namespaced SimpleMemoryCache instance clears entire underlying cache

Open edaniszewski opened this issue 4 years ago • 0 comments

When calling clear on an instance of a SimpleMemoryCache with a namespace assigned, it will clear the entire underlying cache instead of using the instance namespace. An example:

import aiocache
import asyncio

# Define namespace constants
NS_ONE = 'ns.one'
NS_TWO = 'ns.two'

# Define cache references
cache_one = aiocache.SimpleMemoryCache(namespace=NS_ONE)
cache_two = aiocache.SimpleMemoryCache(namespace=NS_TWO)


async def do_something():
    # Add some data to CACHE_ONE, then get it and print it out
    # to verify it is there.
    await cache_one.set('foo', 'bar')
    val = await cache_one.get('foo')
    print(f'cache_one    k=foo v={val}')
    print(f'underlying cache: {cache_one._cache}')
    print('')

    # Call `clear` on cache_two. Since the cache reference is differentiated
    # by namespace, one would expect the clear to apply to the namespace of
    # the referenced cache.
    await cache_two.clear()

    # Get the value from cache_one again. It is not there because the
    # entire cache was cleared, not just the data under the cache_two namespace.
    val = await cache_one.get('foo')
    print(f'cache_one    k=foo v={val}')
    print(f'underlying cache: {cache_one._cache}')


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(do_something())

Where the output is:

cache_one    k=foo v=bar
underlying cache: {'ns.onefoo': 'bar'}

cache_one    k=foo v=None
underlying cache: {}

Specifying the namespace explicitly for the call to clear behaves as expected though

- await cache_two.clear()
+ await cache_two.clear(NS_TWO)

leading to the output

cache_one    k=foo v=bar
underlying cache: {'ns.onefoo': 'bar'}

cache_one    k=foo v=bar
underlying cache: {'ns.onefoo': 'bar'}

I believe this is related to this bit of code: https://github.com/argaen/aiocache/blob/f811995e0632b46a4597cc07007c26f755d2ffa3/aiocache/base.py#L417-L431

Where the namespace is only ever passed in via parameter, never checking to see if the instance's namespace member is set.

edaniszewski avatar Feb 21 '20 16:02 edaniszewski