=================== 92:タスク非同期処理 =================== .. maigo:: ワーカープロセスからスレッド起動 * 後輩W:ちょっとわからない不具合があって、相談に乗ってください。タスクの非同期処理を実装したんですが、たまに処理が行われないことがあるんです。 * 先輩T:非同期処理、どうしてやりたいんだっけ。 * 後輩W:Webアプリケーションでボタンを押したときに、時間がかかる処理をやりつつ、ブラウザにはすぐレスポンスを返すためです。 * 先輩T:んー、なるほど。その非同期処理はどうやって実装したの? * 後輩W:スレッドで動かしてます。 * 先輩T:あー、それが原因だろうね。タスク処理用のスレッドをGunicornプロセスから起動したために、Gunicornのワーカープロセスが自動再起動したときにおかしくなってるんだと思うよ。 .. index:: Gunicorn .. index:: ワーカープロセス .. index:: プロセス .. index:: スレッド Gunicornのワーカープロセスなど、自動的に再起動されるプロセス上でスレッド起動や子プロセス起動をしてはいけません。 GunicornのようなWebアプリケーションのプロセスは、複数のレスポンスを扱うための機能を提供するためにマルチプロセス、マルチスレッドが使われています。 このため各プロセスからさらにスレッドや子プロセスを起動した場合、そういった制御機構と競合してしまい、何が起こるかわかりません。 .. omission:: ベストプラクティス ================== 非同期タスク処理が必要な場合は、専用プロセスで処理を行うように設計しましょう。 非同期タスク処理は自作しようとせず、定番フレームワークの利用を検討しましょう。 定番フレームワークには、以下のようなものがあります。 .. index:: Celery .. index:: Django Background Tasks .. index:: APScheduler .. csv-table:: 非同期タスク処理フレームワークの比較 ,`Celery`_,`Django Background Tasks`_, `APScheduler`_ バージョン(リリース日),4.4.0(2019/12/16),1.2.5(2019/12/23),3.6.3(2019/11/5) インフラミドルウェア追加,Redis,なし,なし ライブラリの使いやすさ, .. omission:: .. _Celery: http://www.celeryproject.org/ .. _Django Background Tasks: https://django-background-tasks.readthedocs.io/ .. _APScheduler: https://pypi.org/project/APScheduler/ 関連 ==== * :doc:`../プロセス設計/95-Celeryのタスクにはプリミティブなデータを渡そう`