37dev
37dev

Reputation: 189

Is Celery really async?

I am codig a realtime game using celery and django-channels.

I have a task that works like a timer and if this timer reaches to zero, once the task was activated, a group_send() is called. From what I see, celery tasks are async but we can't await functions inside tasks.. this makes me a little bit confused.. here is the code:

@app.task(ignore_result=True)
def count_down(channel_name):
    set_random_game_result(channel_name)
    room = process_game_result(channel_name, revoke=False)
    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        channel_name,
        {
            "type": "game_room_info",
            "room": room
        }
    )

from the docs:

By default the send(), group_send(), group_add() and other functions are async functions, meaning you have to await them. If you need to call them from synchronous code, you’ll need to use the handy asgiref.sync.async_to_sync wrapper

So if celery is async, why can't I use the group_send without using the async_to_sync util?

Another thing is about querying.. From the docs:

If you are writing asynchronous code, however, you will need to call database methods in a safe, synchronous context, using database_sync_to_async.

database_sync_to_async actually doesn't work inside the task function. Am I missing something?

Upvotes: 3

Views: 3068

Answers (1)

DejanLekic
DejanLekic

Reputation: 19797

The problem you are talking about is something that is done by design, for a good reason. It is also well-documented, and can be solved easily with appropriate Canvas.

Also... Do not get confused with terminology... Celery is asynchronous, but it is not "Python async" as it predates the Python's asyncio... Maybe Celery 5 will get its async parts replaced/refactored to use Python 3+ asyncio and related.

Upvotes: 2

Related Questions