What is the difference between mytask.apply()
, mytask.run()
and mytask()
? Which way is preferable?
If the task isn't registered in the current process you can use send_task() to call the task by name instead. So delay is clearly convenient, but if you want to set additional execution options you have to use apply_async .
To answer your opening questions: As of version 2.0, Celery provides an easy way to start tasks from other tasks. What you are calling "secondary tasks" are what it calls "subtasks".
delay() has comes preconfigured and only requires arguments to be passed to the task — that's sufficient for most basic needs. Apply_async is more complex, but also more powerful then preconfigured delay. It is always better to use apply_async with specifically set options for maximum flexibility.
Also if you are sending task from a totally different app, working with the same Celery instance – you can't use import and thus can't do .delay or .apply_async For this case you can call the task by name. Let's see the example for the calling task from within the models.py
For development docs, go here . Tasks are the building blocks of Celery applications. A task is a class that can be created out of any callable. It performs dual roles in that it defines both what happens when a task is called (sends a message), and what happens when a worker receives that message.
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. Shared task has a lot of parameters and you have to decide which one to use depending on type of task.
It might be easier to use signals, but in a larger context - web application pov, if you used email, chances are if the app grows big, you might need to do some additional background tasks, in which case , having one system (celery) would be easier. And celery handles these perfectly well..
You can find all of this in the celery package in celery/app/task.py
, or in the documentation http://docs.celeryproject.org/en/latest/reference/celery.app.task.html
To elaborate in my own investigation:
delay
with the same limitations (arguments get passed, however no access to other execution options), and is similar to calling. it will immediately return e.g. in case of an exception, so the call is fully blocking, and just like calling a function.tasks.my_task.run(foo='bar')
my_task() is the documented one, and acts like run
. (in fact, Task.__call__
executes self.run(*args, **kwargs)
); It should be probably preferred over run(), as it does other things as well.
tasks.my_task(foo='bar')
so between mytask.run() and mytask() i would choose mytask(), except if i know i want run instead. If it would be rewritten, as true celery worker function, both would be rewritten as delay()
tasks.my_task.apply(kwargs={'foo': 'bar'})
it is also the function called by apply_async if it is set to always_eager. A side effect is, that exceptions would continue execution, just as apply_async would, if it is not set to always_eager or gets the throw keyword set.
when i want to have a syntax which later gets changed into apply_async, i would prefer apply - generally i would prefer apply personally.
In my understanding:
apply
: is to call task and execute locally run
: never seen beforemytask()
: just like call funcIf you want to send message and execute remote,you should use apply_async
or delay
, referring call_task.
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