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.task 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() # have all subtasks completed?
  67. True
  68. >>> result.successful() # were all subtasks successful?
  69. True
  70. >>> result.join()
  71. [4, 8, 16, 32, 64]
  72. .. _sets-results:
  73. Results
  74. -------
  75. When a :class:`~celery.task.sets.TaskSet` is applied it returns a
  76. :class:`~celery.result.TaskSetResult` object.
  77. :class:`~celery.result.TaskSetResult` takes a list of
  78. :class:`~celery.result.AsyncResult` instances and operates on them as if it was a
  79. single task.
  80. It supports the following operations:
  81. * :meth:`~celery.result.TaskSetResult.successful`
  82. Returns :const:`True` if all of the subtasks finished
  83. successfully (e.g. did not raise an exception).
  84. * :meth:`~celery.result.TaskSetResult.failed`
  85. Returns :const:`True` if any of the subtasks failed.
  86. * :meth:`~celery.result.TaskSetResult.waiting`
  87. Returns :const:`True` if any of the subtasks
  88. is not ready yet.
  89. * :meth:`~celery.result.TaskSetResult.ready`
  90. Return :const:`True` if all of the subtasks
  91. are ready.
  92. * :meth:`~celery.result.TaskSetResult.completed_count`
  93. Returns the number of completed subtasks.
  94. * :meth:`~celery.result.TaskSetResult.revoke`
  95. Revokes all of the subtasks.
  96. * :meth:`~celery.result.TaskSetResult.iterate`
  97. Iterates over the return values of the subtasks
  98. as they finish, one by one.
  99. * :meth:`~celery.result.TaskSetResult.join`
  100. Gather the results for all of the subtasks
  101. and return a list with them ordered by the order of which they
  102. were called.