The Celery documentation suggests that it's a bad idea to have tasks wait on the results of other tasks… But the suggested solution (see “good” heading) leaves a something to be desired. Specifically, there's no clear way of getting the subtask's result back to the caller (also, it's kind of ugly).
So, is there any way of “chaining” jobs, so the caller gets the result of the final job? Eg, to use the add
example:
>>> add3 = add.subtask(args=(3, )) >>> add.delay(1, 2, callback=add3).get() 6
Alternately, is it OK to return instances of Result? For example:
@task def add(x, y, callback=None): result = x + y if callback: return subtask(callback).delay(result) return result
This would let the result of the “final” job in the chain could be retrived with a simple:
result = add(1, 2, callback=add3).delay() while isinstance(result, Result): result = result.get() print "result:", result
It allows you to offload work from your Python app. Once you integrate Celery into your app, you can send time-intensive tasks to Celery's task queue. That way, your web app can continue to respond quickly to users while Celery completes expensive operations asynchronously in the background.
Celery chains allow you to modularise your application and reuse common Celery tasks.
The "shared_task" decorator allows creation of Celery tasks for reusable apps as it doesn't need the instance of the Celery app. It is also easier way to define a task as you don't need to import the Celery app instance.
You can do it with a celery chain. See https://celery.readthedocs.org/en/latest/userguide/canvas.html#chains
@task() def add(a, b): time.sleep(5) # simulate long time processing return a + b
Chaining job:
# import chain from celery import chain # the result of the first add job will be # the first argument of the second add job ret = chain(add.s(1, 2), add.s(3)).apply_async() # another way to express a chain using pipes ret2 = (add.s(1, 2) | add.s(3)).apply_async() ... # check ret status to get result if ret.status == u'SUCCESS': print "result:", ret.get()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With