69

I am very confused by looking at different ways of creating a celery task. On the surface they all work the same So, Can someone explain what is the difference between these.

1.

from myproject.tasks import app

@app.task
def foo():
    pass

2.

from celery import task

@task
def foo():
    pass

3.

from celery import shared_task

@shared_task
def foo():
    pass

I know by a little bit of googling that the difference between the 1nd and 3rd one is shared_task is used when you don't have a concrete app instance. Can someone elaborate more on that and when is the second one is used?

counter2015
  • 869
  • 7
  • 18
MOntu
  • 837
  • 1
  • 6
  • 8
  • 1
    I'm confused by #1, where in the project are you writing this? could this also be `from proj.celery import app` if following https://docs.celeryproject.org/en/stable/django/first-steps-with-django.html – dangel May 15 '20 at 01:33

1 Answers1

58

Don't use #2 unless you are using celery v3. If you are using celery v4, use #1.

Use #3 in instances where you are writing a reusable library or django app. For example, if you are writing an open source set of tasks that allow you to manage aws ec2 instances using celery, you would use shared_task so that the tasks could be run on celery, but you would leave it to the person using your library to configure celery for themselves.

Use #1 if you are writing for your own project and there is no concern for re-use.

2ps
  • 15,099
  • 2
  • 27
  • 47
  • 1
    is the second method specific to only celery v3? what if we use in v4? Also is there any difference between 1st and 2nd one? Are they exactly the same except they are celery version specific? – MOntu Feb 04 '19 at 06:02
  • As far as I understand, yes, the second version is only specific to v3 and should not be used with v4. There is difference between #1 and #2, but that is because v4 is fundamentally different than v3. In v4, using the decorator essentially registers the task as runnable for any worker that is started with that app instance. I don't think there's a similar concept in v3. – 2ps Feb 04 '19 at 22:58
  • 2
    We are using the #2 method to declare all tasks in a Django 1.11 app using Celery 4.3.0, and everything seems to work as expected. Even the latest Celery docs seem to use it interchangeably https://docs.celeryproject.org/en/v5.0.5/userguide/tasks.html. Do you have any concrete sources about the deprecation or changes in functionality? – tmarice Jan 11 '21 at 14:42
  • 3
    @tmarice #2 doesn't seem to be in the docs any longer. Also `task` is unimportable from celery 5.1.1 – bravmi Aug 03 '21 at 06:29