tasksets.rst 3.9 KB

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