|
@@ -12,11 +12,14 @@
|
|
from __future__ import absolute_import
|
|
from __future__ import absolute_import
|
|
from __future__ import with_statement
|
|
from __future__ import with_statement
|
|
|
|
|
|
|
|
+from itertools import chain
|
|
|
|
+
|
|
from .. import current_app
|
|
from .. import current_app
|
|
from ..app import app_or_default, current_task
|
|
from ..app import app_or_default, current_task
|
|
from ..datastructures import AttributeDict
|
|
from ..datastructures import AttributeDict
|
|
from ..utils import cached_property, reprcall, uuid
|
|
from ..utils import cached_property, reprcall, uuid
|
|
-from ..utils.compat import UserList
|
|
|
|
|
|
+from ..utils.functional import maybe_list
|
|
|
|
+from ..utils.compat import UserList, chain_from_iterable
|
|
|
|
|
|
|
|
|
|
class subtask(AttributeDict):
|
|
class subtask(AttributeDict):
|
|
@@ -83,6 +86,25 @@ class subtask(AttributeDict):
|
|
options = dict(self.options, **options)
|
|
options = dict(self.options, **options)
|
|
return self.type.apply_async(args, kwargs, **options)
|
|
return self.type.apply_async(args, kwargs, **options)
|
|
|
|
|
|
|
|
+ def link(self, callback):
|
|
|
|
+ """Add a callback task to be applied if this task
|
|
|
|
+ executes successfully."""
|
|
|
|
+ self.options.setdefault("link", []).append(callback)
|
|
|
|
+ return callback
|
|
|
|
+
|
|
|
|
+ def link_error(self, errback):
|
|
|
|
+ """Add a callback task to be applied if an error occurs
|
|
|
|
+ while executing this task."""
|
|
|
|
+ self.options.setdefault("link_error", []).append(errback)
|
|
|
|
+ return errback
|
|
|
|
+
|
|
|
|
+ def flatten_links(self):
|
|
|
|
+ """Gives a recursive list of dependencies (unchain if you will,
|
|
|
|
+ but with links intact)."""
|
|
|
|
+ return list(chain_from_iterable(chain([[self]],
|
|
|
|
+ (link.flatten_links()
|
|
|
|
+ for link in maybe_list(self.options.get("link")) or []))))
|
|
|
|
+
|
|
def __reduce__(self):
|
|
def __reduce__(self):
|
|
# for serialization, the task type is lazily loaded,
|
|
# for serialization, the task type is lazily loaded,
|
|
# and not stored in the dict itself.
|
|
# and not stored in the dict itself.
|