@app.task vs. @shared_task

24,409 views
Skip to first unread message

Dan Langer

unread,
Nov 10, 2013, 3:58:48 PM11/10/13
to celery...@googlegroups.com
In a (Django in my case) project where I'll only ever have one Celery app going, what are some of the tradeoffs with always using @shared_task, as opposed to @app.task? From my read of the docs, they should be equivalent.

Thanks,

Dan

Ask Solem

unread,
Nov 11, 2013, 9:53:58 AM11/11/13
to celery...@googlegroups.com
There is a difference between @task(shared=True) and @shared_task


The task decorator will share tasks between apps by default so that if you do:


app1 = Celery()
@app1.task
def test():
pass

app2 = Celery()

the test task will be registered in both apps:

assert app1.tasks[test.name]
assert app2.tasks[test.name]


However, the name ‘test’ will always refer to the instance bound to the ‘app1’
app, so it will be configured using app1’s configuration:

assert test.app is app1



The @shared_task decorator returns a proxy that always uses the task instance
in the current_app:


app1 = Celery()

@shared_task
def test():
pass
assert test.app is app1


app2 = Celery()
assert test.app is app2


This makes the @shared_task decorator useful for libraries and reusable apps,
since they will not have access to the app of the user.


In addition the default Django example project defines the app instance
as part of the Django project:

from proj.celery import app

and it makes no sense for a Django reusable app to depend on the project module,
as then it would not be reusable anymore.

--
Ask Solem
twitter.com/asksol

Reply all
Reply to author
Forward
0 new messages