From 34c403ec8d0794b62cc7ac72eb54522c9f68db90 Mon Sep 17 00:00:00 2001 From: John Lucas Date: Wed, 6 Dec 2017 09:34:26 -0500 Subject: [PATCH] Add meta to decorator, move depends_on + at_front to decorator (#892) --- rq/decorators.py | 16 +++++++++-- tests/test_decorator.py | 62 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/rq/decorators.py b/rq/decorators.py index 857a7d2..b5bb610 100644 --- a/rq/decorators.py +++ b/rq/decorators.py @@ -16,7 +16,7 @@ class job(object): # noqa def __init__(self, queue, connection=None, timeout=None, result_ttl=DEFAULT_RESULT_TTL, ttl=None, - queue_class=None): + queue_class=None, depends_on=None, at_front=None, meta=None): """A decorator that adds a ``delay`` method to the decorated function, which in turn creates a RQ job when called. Accepts a required ``queue`` argument that can be either a ``Queue`` instance or a string @@ -34,6 +34,9 @@ class job(object): # noqa self.timeout = timeout self.result_ttl = result_ttl self.ttl = ttl + self.meta = meta + self.depends_on = depends_on + self.at_front = at_front def __call__(self, f): @wraps(f) @@ -43,10 +46,19 @@ class job(object): # noqa connection=self.connection) else: queue = self.queue + depends_on = kwargs.pop('depends_on', None) at_front = kwargs.pop('at_front', False) + + if not depends_on: + depends_on = self.depends_on + + if not at_front: + at_front = self.at_front + return queue.enqueue_call(f, args=args, kwargs=kwargs, timeout=self.timeout, result_ttl=self.result_ttl, - ttl=self.ttl, depends_on=depends_on, at_front=at_front) + ttl=self.ttl, depends_on=depends_on, at_front=at_front, + meta=self.meta) f.delay = delay return f diff --git a/tests/test_decorator.py b/tests/test_decorator.py index 4fb1c1b..1b9e974 100644 --- a/tests/test_decorator.py +++ b/tests/test_decorator.py @@ -70,21 +70,44 @@ class TestDecorator(RQTestCase): result = hello.delay() self.assertEqual(result.ttl, 30) + def test_decorator_accepts_meta_as_argument(self): + """Ensure that passing in meta to the decorator sets the meta on the job + """ + # Ensure default + result = decorated_job.delay(1, 2) + self.assertEqual(result.meta, {}) + + test_meta = { + 'metaKey1': 1, + 'metaKey2': 2, + } + + @job('default', meta=test_meta) + def hello(): + return 'Hello' + result = hello.delay() + self.assertEqual(result.meta, test_meta) + def test_decorator_accepts_result_depends_on_as_argument(self): """Ensure that passing in depends_on to the decorator sets the correct dependency on the job """ + # Ensure default + result = decorated_job.delay(1, 2) + self.assertEqual(result.dependency, None) + self.assertEqual(result._dependency_id, None) @job(queue='queue_name') def foo(): return 'Firstly' - @job(queue='queue_name') + foo_job = foo.delay() + + @job(queue='queue_name', depends_on=foo_job) def bar(): return 'Secondly' - foo_job = foo.delay() - bar_job = bar.delay(depends_on=foo_job) + bar_job = bar.delay() self.assertIsNone(foo_job._dependency_id) @@ -92,6 +115,39 @@ class TestDecorator(RQTestCase): self.assertEqual(bar_job._dependency_id, foo_job.id) + def test_decorator_delay_accepts_depends_on_as_argument(self): + """Ensure that passing in depends_on to the delay method of + a decorated function overrides the depends_on set in the + constructor. + """ + # Ensure default + result = decorated_job.delay(1, 2) + self.assertEqual(result.dependency, None) + self.assertEqual(result._dependency_id, None) + + @job(queue='queue_name') + def foo(): + return 'Firstly' + + @job(queue='queue_name') + def bar(): + return 'Firstly' + + foo_job = foo.delay() + bar_job = bar.delay() + + @job(queue='queue_name', depends_on=foo_job) + def baz(): + return 'Secondly' + + baz_job = bar.delay(depends_on=bar_job) + + self.assertIsNone(foo_job._dependency_id) + self.assertIsNone(bar_job._dependency_id) + + self.assertEqual(baz_job.dependency, bar_job) + self.assertEqual(baz_job._dependency_id, bar_job.id) + @mock.patch('rq.queue.resolve_connection') def test_decorator_connection_laziness(self, resolve_connection): """Ensure that job decorator resolve connection in `lazy` way """