Skip to content

Commit 95b7614

Browse files
author
Alexey Tsitkin
committed
support nesting tasks using a single-invocation patched method
1 parent 6c1b6ab commit 95b7614

File tree

4 files changed

+48
-31
lines changed

4 files changed

+48
-31
lines changed

eb_sqs/auto_tasks/base_service.py

Lines changed: 0 additions & 24 deletions
This file was deleted.

eb_sqs/auto_tasks/service.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import importlib
22
import logging
33

4-
from eb_sqs.auto_tasks.base_service import BaseAutoTaskService, NoopTaskService
54
from eb_sqs.auto_tasks.exceptions import RetryableTaskException
65
from eb_sqs.decorators import task
76
from eb_sqs.worker.worker_exceptions import MaxRetriesReachedException
@@ -24,11 +23,12 @@ def _auto_task_wrapper(module_name, class_name, func_name, *args, **kwargs):
2423
module = importlib.import_module(module_name) # import module
2524
class_ = getattr(module, class_name) # find class
2625

27-
noop_task_service = NoopTaskService()
28-
instance = class_(auto_task_service=noop_task_service) # instantiate class using NoopTaskService
26+
auto_task_executor_service = _AutoTaskExecutorService(func_name)
27+
instance = class_(auto_task_service=auto_task_executor_service) # instantiate class using _AutoTaskExecutorService
2928

30-
if noop_task_service.is_func_name_registered(func_name):
31-
getattr(instance, func_name)(*args, **kwargs) # invoke method on instance
29+
executor_func_name = auto_task_executor_service.get_executor_func_name()
30+
if executor_func_name:
31+
getattr(instance, executor_func_name)(*args, **kwargs) # invoke method on instance
3232
else:
3333
logger.error(
3434
'Trying to invoke _auto_task_wrapper for unregistered task with module: %s class: %s func: %s args: %s and kwargs: %s',
@@ -57,7 +57,7 @@ def _auto_task_wrapper(module_name, class_name, func_name, *args, **kwargs):
5757
logger.error('Reached max retries in auto task {}.{}.{} with error: {}'.format(module_name, class_name, func_name, repr(exc)))
5858

5959

60-
class AutoTaskService(BaseAutoTaskService):
60+
class AutoTaskService(object):
6161
def register_task(self, method, queue_name=None, max_retries=None):
6262
# type: (Any, str, int) -> None
6363
instance = method.__self__
@@ -79,3 +79,26 @@ def _auto_task_wrapper_invoker(*args, **kwargs):
7979
)
8080

8181
setattr(instance, func_name, _auto_task_wrapper_invoker)
82+
83+
84+
class _AutoTaskExecutorService(AutoTaskService):
85+
def __init__(self, func_name):
86+
# type: (str) -> None
87+
self._func_name = func_name
88+
89+
self._executor_func_name = None
90+
91+
def register_task(self, method, queue_name=None, max_retries=None):
92+
# type: (Any, str, int) -> None
93+
if self._func_name == method.__name__:
94+
# circuit breaker to allow actually executing the method once
95+
instance = method.__self__
96+
97+
self._executor_func_name = self._func_name + '__auto_task_executor__'
98+
setattr(instance, self._executor_func_name, getattr(instance, self._func_name))
99+
100+
super(_AutoTaskExecutorService, self).register_task(method, queue_name, max_retries)
101+
102+
def get_executor_func_name(self):
103+
# type: () -> str
104+
return self._executor_func_name

eb_sqs/tests/auto_tasks/tests_auto_tasks.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ class TestService:
1313

1414
def __init__(self, auto_task_service=None):
1515
self._auto_task_service = auto_task_service or AutoTaskService()
16+
1617
self._auto_task_service.register_task(self.task_method)
1718
self._auto_task_service.register_task(self.task_retry_method, max_retries=self._MAX_RETRY_NUM)
1819

20+
self._auto_task_service.register_task(self.task_recursive_method)
21+
self._auto_task_service.register_task(self.task_other_method)
22+
1923
def task_method(self, *args, **kwargs):
2024
self._TEST_MOCK.task_method(*args, **kwargs)
2125

@@ -30,6 +34,15 @@ def max_retry_fun():
3034
def non_task_method(self):
3135
self._TEST_MOCK.non_task_method()
3236

37+
def task_recursive_method(self, tries=2):
38+
if tries > 0:
39+
self.task_recursive_method(tries=tries - 1)
40+
else:
41+
self.task_other_method()
42+
43+
def task_other_method(self):
44+
self._TEST_MOCK.task_other_method()
45+
3346

3447
class AutoTasksTest(TestCase):
3548
def setUp(self):
@@ -61,3 +74,8 @@ def test_non_task_method(self):
6174
)
6275

6376
TestService._TEST_MOCK.non_task_method.assert_not_called()
77+
78+
def test_task_recursive_method(self):
79+
self._test_service.task_recursive_method()
80+
81+
TestService._TEST_MOCK.task_other_method.assert_called_once_with()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
setup(
88
name='django-eb-sqs',
9-
version='1.31',
9+
version='1.32',
1010
package_dir={'eb_sqs': 'eb_sqs'},
1111
include_package_data=True,
1212
packages=find_packages(),

0 commit comments

Comments
 (0)