tasksets.rst 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. =======================================
  2. Sets of tasks, Subtasks and Callbacks
  3. =======================================
  4. Subtasks
  5. ========
  6. The :class:`~celery.task.sets.subtask` class is used to wrap the arguments and
  7. execution options for a task invocation. The signature is the following::
  8. subtask(task_name_or_cls, args, kwargs, options)
  9. For convenience every task also has a shortcut to create subtask instances::
  10. task.subtask(args, kwargs, options)
  11. :class:`~celery.task.sets.subtask` is actually a subclass of :class:`dict`,
  12. which means it can be serialized with JSON or other encodings that doesn't
  13. support complex Python objects.
  14. Also it can be regarded as a type, as the following usage works::
  15. >>> s = subtask("tasks.add", args=(2, 2), kwargs={})
  16. >>> subtask(dict(s)) # coerce dict into subtask
  17. This makes it excellent as a means to pass callbacks around to tasks.
  18. Let's improve our ``add`` task so it can accept a callback that
  19. takes the result as an argument::
  20. from celery.decorators import task
  21. from celery.task.sets import subtask
  22. @task
  23. def add(x, y, callback=None):
  24. result = x + y
  25. if callback is not None:
  26. subtask(callback).apply_async(result)
  27. return result
  28. See? :class:`~celery.task.sets.subtask` also knows how it should be applied,
  29. asynchronously by :meth:`~celery.task.sets.subtask.apply_async`, and
  30. eagerly by :meth:`~celery.task.sets.subtask.apply`.
  31. The best thing is that any arguments you add to ``subtask.apply_async``,
  32. will be prepended to the arguments specified by the subtask itself
  33. Bbut please note: additional keyword arguments will be added to the
  34. execution options, not the task keyword arguments.
  35. So if you have the subtask::
  36. >>> add.subtask(args=(10, ), options={"ignore_result": True})
  37. ``subtask.apply_async(result)`` becomes::
  38. >>> add.apply_async(args=(result, 10), ignore_result=True)
  39. and ``subtask.apply_async(result, ignore_result=False)`` becomes::
  40. >>> add.apply_async(args=(result, 10), ignore_result=False)
  41. Now let's execute our new ``add`` task with a callback::
  42. >>> add.delay(2, 2, callback=add.subtask((8, )))
  43. As expected this will first execute ``2 + 2``, then ``4 + 8``.
  44. TaskSets
  45. =========
  46. The :class:`~celery.task.sets.TaskSet` enables easy invocation of several
  47. tasks at once, and is then able to join the results in the same order as the
  48. tasks were invoked.
  49. The task set works on a list of :class:`~celery.task.sets.subtask`'s::
  50. >>> from celery.task.sets import TaskSet
  51. >>> from tasks import add
  52. >>> job = TaskSet(tasks=[
  53. ... add.subtask((4, 4)),
  54. ... add.subtask((8, 8)),
  55. ... add.subtask((16, 16)),
  56. ... add.subtask((32, 32)),
  57. ... ])
  58. >>> result = job.apply_async()
  59. >>> result.ready() # has all subtasks completed?
  60. True
  61. >>> result.successful() # was all subtasks successful?
  62. >>> result.join()
  63. [4, 8, 16, 32, 64]
  64. TaskSet Results
  65. ===============
  66. When a :class:`~celery.task.sets.TaskSet` is applied it returns a
  67. :class:`~celery.result.TaskSetResult` object.
  68. :class:`~celery.result.TaskSetResult` takes a list of
  69. :class:`~celery.result.AsyncResult` instances and operates on them as if was a
  70. single task.
  71. The following operations are available:
  72. * :meth:`~celery.result.TaskSetResult.successful`
  73. Returns :const:`True` if all of the subtasks finished
  74. successfully (e.g. did not raise an exception).
  75. * :meth:`~celery.result.TaskSetResult.failed`
  76. Returns :const:`True` if any of the subtasks failed.
  77. * :meth:`~celery.result.TaskSetResult.waiting`
  78. Returns :const:`True` if any of the subtasks
  79. is not ready.
  80. * meth:`~celery.result.TaskSetResult.ready`
  81. Return :const:`True` if all of the subtasks
  82. are ready.
  83. * meth:`~celery.result.TaskSetResult.completed_count`
  84. Returns the number of completed subtasks.
  85. * meth:`~celery.result.TaskSetResult.revoke`
  86. Revoke all of the subtasks.
  87. * meth:`~celery.result.TaskSetResult.iterate`
  88. Iterate over the return values of the subtasks
  89. as they finish, one by one.
  90. * meth:`~celery.result.TaskSetResult.join`
  91. Gather the results for all of the subtasks,
  92. and return a list with them ordered by the order of which they
  93. were called.