tasksets.rst 4.0 KB

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