3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Djangoでsync_to_asyncを使ってみる

Last updated at Posted at 2021-09-08

Djangoで先にリスポンスを返してから重い処理を継続する簡単な方法を見つけたので紹介します。理解できていない部分も多いので、誤り等あればご指摘いただければ幸いです。

asyncioを使った非同期処理

Django 3.1より非同期処理的にリスポンスを返す非同期Viewが導入されました。例えば、標準ライブラリasyncioを使って次のような非同期Viewを書くと、スリープしている間に非同期的にリスポンスを返してくれます。

views.py
import asyncio
async def async_func():
    for i in range(5):
        await asyncio.sleep(1.0) # 1秒待機
        print(i+1)

async def async_response(request):
    task = asyncio.create_task(async_func())
    task
    return HttpResponse('Asyncronous Response')

上では、非同期関数async_funcを定義し、非同期Viewのasync_responseで呼び出しています。async_responseではasyncio.create_taskを使って同時並行でコルーチンを実行しています。これをuvicornで実行してブラウザからアクセスすると以下のようなログが出ます("Project"はプロジェクト名で置き換えてください)。

$ uvicorn Project.asgi:application
INFO:     Started server process [15308]
INFO:     Waiting for application startup.
INFO:     ASGI 'lifespan' protocol appears unsupported.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:49470 - "GET /myapp/async_response HTTP/1.1" 200 OK
1
2
3
4
5

スリープの完了を待たずにResponseが返されているのが分かります。

sync_to_asyncによる非同期化

一方で、次のsync_funcのような同期関数に適応したい場合、コルーチンを返す非同期関数に変換する必要があります。ここで、ASGIのsync_to_asyncを使うことができます。

views.py
import time, asyncio
from asgiref.sync import sync_to_async
def sync_func():
    for i in range(5):
        time.sleep(1.0) # 1秒待機
        print(i+1)

async def async_response(request):
    async_func2 = sync_to_async(sync_func, thread_sensitive=False)
    task = asyncio.create_task(async_func2())
    task
    return HttpResponse('Asyncronous Response')

実行すると、先ほどと同様のログが出力されます。これにより、自分で定義した任意の処理を開始しつつ先にリスポンスを返すことができました。
 以上を応用すると、バックエンド側で機械学習や数値計算などの重い処理を開始しつつ、リスポンスを先に返すといったことにも使えるかと思います。

参考

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?