tasks.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # Example::
  2. # >>> R = A.apply_async()
  3. # >>> list(joinall(R))
  4. # [['A 0', 'A 1', 'A 2', 'A 3', 'A 4', 'A 5', 'A 6', 'A 7', 'A 8', 'A 9'],
  5. # ['B 0', 'B 1', 'B 2', 'B 3', 'B 4', 'B 5', 'B 6', 'B 7', 'B 8', 'B 9'],
  6. # ['C 0', 'C 1', 'C 2', 'C 3', 'C 4', 'C 5', 'C 6', 'C 7', 'C 8', 'C 9'],
  7. # ['D 0', 'D 1', 'D 2', 'D 3', 'D 4', 'D 5', 'D 6', 'D 7', 'D 8', 'D 9'],
  8. # ['E 0', 'E 1', 'E 2', 'E 3', 'E 4', 'E 5', 'E 6', 'E 7', 'E 8', 'E 9'],
  9. # ['F 0', 'F 1', 'F 2', 'F 3', 'F 4', 'F 5', 'F 6', 'F 7', 'F 8', 'F 9'],
  10. # ['G 0', 'G 1', 'G 2', 'G 3', 'G 4', 'G 5', 'G 6', 'G 7', 'G 8', 'G 9'],
  11. # ['H 0', 'H 1', 'H 2', 'H 3', 'H 4', 'H 5', 'H 6', 'H 7', 'H 8', 'H 9']]
  12. #
  13. #
  14. # Joining the graph asynchronously with a callback
  15. # (Note: only two levels, the deps are considered final
  16. # when the second task is ready).
  17. #
  18. # >>> unlock_graph.apply_async((A.apply_async(),
  19. # ... A_callback.s()), countdown=1)
  20. from __future__ import absolute_import, print_function, unicode_literals
  21. from celery import chord, group, task, signature, uuid
  22. from celery.result import AsyncResult, ResultSet, allow_join_result
  23. from collections import deque
  24. @task()
  25. def add(x, y):
  26. return x + y
  27. @task()
  28. def make_request(id, url):
  29. print('-get: {0!r}'.format(url))
  30. return url
  31. @task()
  32. def B_callback(urls, id):
  33. print('-batch {0} done'.format(id))
  34. return urls
  35. @task()
  36. def B(id):
  37. return chord(
  38. make_request.s(id, '{0} {1!r}'.format(id, i))
  39. for i in range(10)
  40. )(B_callback.s(id))
  41. @task()
  42. def A():
  43. return group(B.s(c) for c in 'ABCDEFGH').apply_async()
  44. def joinall(R, timeout=None, propagate=True):
  45. stack = deque([R])
  46. try:
  47. use_native = joinall.backend.supports_native_join
  48. except AttributeError:
  49. use_native = False
  50. while stack:
  51. res = stack.popleft()
  52. if isinstance(res, ResultSet):
  53. j = res.join_native if use_native else res.join
  54. stack.extend(j(timeout=timeout, propagate=propagate))
  55. elif isinstance(res, AsyncResult):
  56. stack.append(res.get(timeout=timeout, propagate=propagate))
  57. else:
  58. yield res
  59. @task()
  60. def unlock_graph(result, callback,
  61. interval=1, propagate=False, max_retries=None):
  62. if result.ready():
  63. second_level_res = result.get()
  64. if second_level_res.ready():
  65. with allow_join_result():
  66. signature(callback).delay(list(joinall(
  67. second_level_res, propagate=propagate)))
  68. else:
  69. unlock_graph.retry(countdown=interval, max_retries=max_retries)
  70. @task()
  71. def A_callback(res):
  72. print('-everything done: {0!r}'.format(res))
  73. return res
  74. class chord2(object):
  75. def __init__(self, tasks, **options):
  76. self.tasks = tasks
  77. self.options = options
  78. def __call__(self, body, **options):
  79. body.options.setdefault('task_id', uuid())
  80. unlock_graph.apply_async()