Herokuを使っているので、rack-timeoutを使っているのだけれど、あんまりよくわからずに使っていたので、よくないなと思って調べてみました。
私は英語が苦手なもんで、すごく適当に訳していってるので抜けもたくさんあるだろうし、終わるのはいつになるかわからんので、編集リクエスト待っています。
基本的な使い方
Rails
gem 'rack-timeout'
デフォルトは15秒なので、カスタマイズしたかったらinitializer fileを作る。
Rack::Timeout.timeout = 20 # seconds
詳細
Service Timeout(Rack::Timeout::timeout)
これが重要な設定で、アプリケーションの処理がtimeoutより長い時間かかる場合、ステータスをtimed_out
として、Rack::Timeout::RequestTimeoutError
が発生する。
0またはfalseに設定しておくと無効になる。
Wait Timeout(Rack::Timeout::wait_timeout)
Herokuではルーティングレイヤーで30秒以上かかる場合はリクエストを破棄する。
通常だとこの場合はログに何も残らないが、Rack::Timeout.wait_timeout
の設定がしてあると、Rack::Timeout::RequestExpiryError
が発生して、リスエストの結果がログにexpired
として残る。
デフォルトは30秒。0またはfalseに設定しておくと無効になる。
基本的にはこのままでwait timeoutを超えることはないだろう。しかしHerokuのルーターの振る舞いが理由で、リクエストをwait timeoutとして破棄するかもしれない。
例えば、
- timeout=15
- wait_timeout=30
のときに、リクエストを受け付けてから20秒経過すると、timeoutの15秒の前の、10秒の時点でwait_timeoutの30秒に到達してしまう。
この振る舞いを無効にしたかったら、Rack::Timeout.service_past_wait
をtrue
にすることだ。
Wait Overtime(Rack::Timeout::wait_overtime)
リクエストが大きい(POSTリクエストのような)場合や、クライアントが低速回線でアップロードしているような場合、問題である。
全部を受信するのに30秒以上かかるような場合、たとえアップロード中であったとしても、Rack::Timeoutはただちに破棄する。
Rack::Timeout.wait_overtime
を設定することで、延長時間を設定できる。
デフォルトは60秒。0またはfalseで無効になる。無効にしてあると、延長時間はない。
ものすごく大きなリクエストを破棄したくなければ、wait_overtimeの値をものすごく大きい数値に設定すること。
ただ、Herokuは大きなファイルはAmazon S3にダイレクトにアップロードすることを推奨していることを覚えておいて。
疲れたので続きはまた今度。