91:時間のかかる処理は非同期化しよう

Webアプリケーションを開発していて、1つのHTTPリクエストの中で、大量のデータを扱い、処理が重くなったことはないですか? ここでは、リアルタイムでの必要のない処理を非同期化することのメリットについて紹介します。

具体的な失敗

たとえばSNSなどで複数人の友達に一斉に招待メールを送るような機能を、どう実装しますか? 下記はDjangoで愚直に書いたコードです。

def invite_users_view(request):

    form = InviteForm(request.POST)
    if not form.is_valid():
        return render('error.html')

    emails = form.cleaned_data['emails']
    for email in emails:
        api.send_invite_mail(email) # 1件1件その場で配信してすべて終わるまで処理がブロックされる

    # メールがすべて配信し終わるまでsend_end.html画面は表示されない
    return render('send_end.html')

このコードだと、1,000人同時に招待したら1,000人にメール配信が完了するまでユーザーの画面は固まったままです。 システム的にもリソースが占有されて他のリクエストを捌けなくなる可能性があります。

ベストプラクティス

リアルタイムでの処理が必要ない部分で時間がかかるような場合、 非同期化 を検討しましょう。 たとえば、メールの送信や、外部システムへの通信は、非同期で処理したほうが良い場合があります。

非同期化と一口に言っても、実現方法はさまざまです。たとえばPythonでは以下のような方法があります。

  • ThreadPoolExecutor等を用いて別スレッドで処理する

  • asyncioを利用する

  • Celeryなどのジョブキューシステムを利用する

cover

(中略)詳細は書籍 自走プログラマー をご参照ください