aiocache icon indicating copy to clipboard operation
aiocache copied to clipboard

Clear() method with 'namespace' parameter fails: TypeError: delete() missing 1 required positional argument: 'key'

Open AbuSM opened this issue 6 years ago • 8 comments

I want to use certain namespace while cleaning redis cache, like below: coros.append(asyncio.ensure_future(cache.clear(namespace='main'))) Error occured when redis cache doesn't have key with namespace 'main' : coros.append(asyncio.ensure_future(cache.clear(namespace='dialog_api')))

I've found the problem in file aiocache/backends/redis.py in 187 line:

async def _clear(self, namespace=None, _conn=None):
        if namespace:
            keys = await _conn.keys("{}:*".format(namespace))
            await _conn.delete(*keys)
        else:
            await _conn.flushdb()
        return True

So, I want to fix it by adding if statement, like:

async def _clear(self, namespace=None, _conn=None):
        if namespace:
            keys = await _conn.keys("{}:*".format(namespace))
            if keys:
                await _conn.delete(*keys)

I could be wrong or miss something, if anybody faced with it please comment

AbuSM avatar Dec 24 '19 08:12 AbuSM

thanks for reporting @AbuSM, could you please post the error traceback you get when this happens?

argaen avatar Dec 24 '19 08:12 argaen

Anyway, checking code for aioredis in https://github.com/aio-libs/aioredis/blob/master/aioredis/commands/generic.py#L10 I would say you are right. If you could open a PR and also add corresponding tests I would be happy to merge :)

argaen avatar Dec 24 '19 08:12 argaen

Hi, @argaen! Here is traceback:

Traceback (most recent call last):
  File "../app.py", line 6, in <module>
    main()
  File "../lib/main.py", line 112, in main
    loop.run_until_complete(asyncio.gather(*coros))
  File "uvloop/loop.pyx", line 1451, in uvloop.loop.Loop.run_until_complete
  File "../venv/lib/python3.7/site-packages/aiocache/base.py", line 61, in _enabled
    return await func(*args, **kwargs)
  File "../venv/lib/python3.7/site-packages/aiocache/base.py", line 45, in _timeout
    return await asyncio.wait_for(func(self, *args, **kwargs), timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/tasks.py", line 416, in wait_for
    return fut.result()
  File "../venv/lib/python3.7/site-packages/aiocache/base.py", line 75, in _plugins
    ret = await func(self, *args, **kwargs)
  File "../venv/lib/python3.7/site-packages/aiocache/base.py", line 429, in clear
    ret = await self._clear(namespace, _conn=_conn)
  File "../venv/lib/python3.7/site-packages/aiocache/backends/redis.py", line 24, in wrapper
    return await func(self, *args, _conn=_conn, **kwargs)
  File "../venv/lib/python3.7/site-packages/aiocache/backends/redis.py", line 187, in _clear
    await _conn.delete(*keys)
TypeError: delete() missing 1 required positional argument: 'key'

I'll open PR with tests as soon as possible :)

AbuSM avatar Dec 24 '19 10:12 AbuSM

Hi,the reason is maybe in cached decorator, if use alias param,the **kwargs,which include namespace,is not pass on cache backend,like RedisCache,look it:

    # in decorators.py,line 80-89
    def __call__(self, f):
        if self.alias:
            self.cache = caches.get(self.alias)
        else:
            self.cache = _get_cache(
                cache=self._cache,
                serializer=self._serializer,
                plugins=self._plugins,
                **self._kwargs
            )

so the namespace param will not take part in key_builder,when you call clear(namespace),you only get empty list keys,which cause TypeError: delete() missing 1 required positional argument: 'key' error.

method to fix it may to add **kwargs in caches.get(self.alias),looks like:

    # in decorators.py,line 80-89
    def __call__(self, f):
        if self.alias:
            self.cache = caches.get(self.alias,**self._kwargs)
        else:
            self.cache = _get_cache(
                cache=self._cache,
                serializer=self._serializer,
                plugins=self._plugins,
                **self._kwargs
            )

long2ice avatar Feb 07 '20 06:02 long2ice

@long2ice Great achievement! I didn't look at the root of the problem. Have you tested it? Sure you might write some tests and make a PR. Think this will help to whole project, not only to clear method

AbuSM avatar Feb 29 '20 13:02 AbuSM

@AbuSM Yes,I make some changes in my fork,but I am not sure if it's right and appropriate or not,that's appreciative if you can review https://github.com/long2ice/aiocache/commits/master and give some suggestions,then I will complete it and make tests,and give a pull request.

long2ice avatar Feb 29 '20 13:02 long2ice

@long2ice I didn't find anything awful in your code and suppose everything is fine. Maybe @argaen may give some comments to it?!

AbuSM avatar Mar 01 '20 12:03 AbuSM

If you create a PR, even as a draft, we'll take a look and provide feedback.

Dreamsorcerer avatar Jan 01 '23 23:01 Dreamsorcerer