Skip to content

Commit

Permalink
Allow dotted dict as the restriction key
Browse files Browse the repository at this point in the history
  • Loading branch information
fernandowaitman committed Nov 5, 2020
1 parent 8800f45 commit fe806c4
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 3 deletions.
19 changes: 18 additions & 1 deletion README.rst
Expand Up @@ -147,6 +147,23 @@ If you want to specify locking based on a subset, or no arguments you can adjust
..
AlreadyQueued()
And in case you want a key inside a dict parameter as your lock key, you could use a string with its `dotted notation path <https://github.com/carlosescri/DottedDict/blob/master/README.rst#example-2-dotteddict>`_:

.. code:: python
@celery.task(base=QueueOnce, once={'keys': ['payload.a']})
def slow_payload_add(payload, b):
sleep(30)
return payload['a'] + b
example.delay({'a': 1, 'another_key': 'any'}, 1)
# Checks if any tasks are running with the `a=1`
example.delay({'a': 1, 'another_key_again': 'any other'}, 2)
Traceback (most recent call last):
..
AlreadyQueued()
example.delay({'a': 2}, 2)
``timeout``
-----------
Expand Down Expand Up @@ -215,7 +232,7 @@ The URL parser supports three patterns of urls:
The ``options`` query args are mapped to the `StrictRedis <https://redis-py.readthedocs.org/en/latest/index.html#redis.StrictRedis>`_ keyword args.
Examples:
* ``redis://localhost:6379/1``

* ``redis://localhost:6379/1?ssl=true``

* ``rediss://localhost:6379/1``
Expand Down
5 changes: 4 additions & 1 deletion celery_once/helpers.py
Expand Up @@ -7,6 +7,8 @@
import importlib
from collections import OrderedDict

from dotted.collection import DottedDict


def import_backend(config):
"""
Expand Down Expand Up @@ -67,7 +69,8 @@ def queue_once_key(name, kwargs, restrict_to=None):
keys = ['qo', force_string(name)]
# Restrict to only the keys allowed in keys.
if restrict_to is not None:
restrict_kwargs = {key: kwargs[key] for key in restrict_to}
dotted_kwargs = DottedDict(kwargs)
restrict_kwargs = {key: dotted_kwargs[key] for key in restrict_to}
keys += kwargs_to_list(restrict_kwargs)
else:
keys += kwargs_to_list(kwargs)
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Expand Up @@ -8,7 +8,8 @@

requirements = [
"celery",
"redis>=2.10.2"
"redis>=2.10.2",
"dotted>=0.1.8",
]

__version__ = ''
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/test_helpers.py
Expand Up @@ -93,6 +93,11 @@ def test_queue_once_key_kwargs_restrict_keys():
assert key == "qo_example_pk-10"


def test_queue_once_key_kwargs_restrict_dotted_keys():
key = queue_once_key("example", {'dict': {'pk': 10}, 'id': 10}, restrict_to=['dict.pk'])
assert key == "qo_example_dict.pk-10"


@pytest.mark.skipif(six.PY3, reason='requires python 2')
def test_queue_once_key_unicode_py2():
key = queue_once_key(u"éxample", {'a': u'é', u'b': 'é'})
Expand Down
10 changes: 10 additions & 0 deletions tests/unit/test_tasks.py
Expand Up @@ -23,6 +23,11 @@ def select_args_example(a, b):
return a + b


@task(name='select_args_dict_example', base=QueueOnce, once={'keys': ['payload.a']})
def select_args_dict_example(payload, b):
return payload['a'] + b


@task(name='autoretry_for_example', base=QueueOnce, autoretry_for=(Exception,))
def autoretry_for_example(a, b):
return a + b
Expand All @@ -46,6 +51,11 @@ def test_get_key_select_args_1():
kwargs={'a': 1, 'b': 2})


def test_get_dotted_key_select_args_1():
assert "qo_select_args_dict_example_payload.a-1" ==\
select_args_dict_example.get_key(kwargs={'payload': {'a': 1}, 'b': 2})


def test_get_key_bound_task():
assert "qo_bound_task_a-1_b-2" == bound_task.get_key(
kwargs={'a': 1, 'b': 2})
Expand Down

0 comments on commit fe806c4

Please sign in to comment.