tasksets.rst 4.0 KB

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