Herokuで [CRITICAL] WORKER TIMEOUTと出た時に対処したこと[python]


ローカル環境では動いていたのに、Herokuにデプロイするとなぜか動かない…

$ heroku logs -t --app アプリ名
でログを見てみるとこんな表記を発見。
2021-08-11T02:53:56.976537+00:00 app[web.1]: [2021-08-11 02:53:56 +0000] [4] [CRITICAL] WORKER TIMEOUT (pid:9)

タイムアウトしてるじゃないか。

https://devcenter.heroku.com/ja/articles/request-timeout
ここを見ると、どうやら30秒でタイム・アウトするらしい。
これを乗り越えるために必要なのはバックグラウンドジョブによる処理だ。

RQ を使用した Python でのバックグラウンドタスク
https://devcenter.heroku.com/ja/articles/python-rq

ということで、ここに書いてあるとおり、RQを使ってバックグラウンドジョブに投げる必要がある。

ハマったこと

ジョブが投げられているかどうかが分からない

先程のリンクを見てみると分かるが、web dynoではなくworkerというdynoを使うことになる。
こいつのログを見るには

$ heroku logs -t -p worker --app アプリ名

でログを見る。
呼び出し側から正常に呼ぶことができていれば、workerのログに処理内容が流れる。
ちなみに、web dynoにも流れるが、これだけ見てるとしっかりworkerにジョブが渡っているかが分からないので注意。
web dynoだけ見て、処理されてるっぽいのになぜ…って結構な時間悩みました。

処理の書き方

q.enqueue(関数名,引数,job_timeout=3600)
job_timeout部分は必要に応じて

これはもうこの書き方じゃないと駄目です。
色々ハマってた時に、こんな形で書いてエラーが出なかったので安心していたのですが
q.enqueue(関数名(引数),引数名=引数,job_timeout=3600)

これだとworker側に渡りません。

ということで、ハマりました。
pythonを使ってリアクティブなWebアプリを作りたい【開発編5】Herokuの開発環境と本番環境
これの開発中にハマったのですが、処理走ってるのにサーバーエラーが表示されるとか、フロントエンド側にどうやって返せばいいのか、みたいないろんなものが複合的に絡まって、混乱したんですよね。
無事に解決できてよかった。
以上です!