92:タスク非同期処理

プログラミング迷子: ワーカープロセスからスレッド起動

  • 後輩W:ちょっとわからない不具合があって、相談に乗ってください。タスクの非同期処理を実装したんですが、たまに処理が行われないことがあるんです。

  • 先輩T:非同期処理、どうしてやりたいんだっけ。

  • 後輩W:Webアプリケーションでボタンを押したときに、時間がかかる処理をやりつつ、ブラウザにはすぐレスポンスを返すためです。

  • 先輩T:んー、なるほど。その非同期処理はどうやって実装したの?

  • 後輩W:スレッドで動かしてます。

  • 先輩T:あー、それが原因だろうね。タスク処理用のスレッドをGunicornプロセスから起動したために、Gunicornのワーカープロセスが自動再起動したときにおかしくなってるんだと思うよ。

Gunicornのワーカープロセスなど、自動的に再起動されるプロセス上でスレッド起動や子プロセス起動をしてはいけません。 GunicornのようなWebアプリケーションのプロセスは、複数のレスポンスを扱うための機能を提供するためにマルチプロセス、マルチスレッドが使われています。 このため各プロセスからさらにスレッドや子プロセスを起動した場合、そういった制御機構と競合してしまい、何が起こるかわかりません。

cover

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

ベストプラクティス

非同期タスク処理が必要な場合は、専用プロセスで処理を行うように設計しましょう。

非同期タスク処理は自作しようとせず、定番フレームワークの利用を検討しましょう。 定番フレームワークには、以下のようなものがあります。

表 4.1 非同期タスク処理フレームワークの比較

Celery

Django Background Tasks

APScheduler

バージョン(リリース日)

4.4.0(2019/12/16)

1.2.5(2019/12/23)

3.6.3(2019/11/5)

インフラミドルウェア追加

Redis

なし

なし

ライブラリの使いやすさ

cover

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