LoginSignup
2
2

More than 3 years have passed since last update.

rack-2.2.x で ActionController::Live が動かなくなっている件について

Last updated at Posted at 2020-08-19

経緯

  • レスポンスをすべて組み立てるのに時間がかかる処理があるので、処理全体が完了する前にレスポンスを返したい。
    • HTTP 1.1 では HTTPヘッダで Transfer-Encoding: chunked を設定することで、body を任意の長さの chunk (かたまり) に分割してクライアントに返すことができることになっている
    • Rails には ActionController::Live というモジュールが用意されている
      • そのモジュールを include して、 response.stream に文字列を出力することで、レスポンスを任意の単位で送出することができる
      • 公式のドキュメント等には、その使用例として Server-Sent Events (SSE) が挙げられているが、別に SSE を利用しなくてもよい

問題

ネタ元:

Rack::ETag ミドルウェアでバッファリングされているらしく、本来、逐次レスポンスが返ってくるところ、response.stream.close するまでレスポンスが返ってこない挙動になってしまっています。

回避方法

rack を 2.1.x 系にデグレードするか、あるいは、以下のようにコントローラで HTTPヘッダを明示的に指定することで Rack::ETag によるバッファリングを回避できるようです。

      headers['Last-Modified'] = '0'
      headers['ETag'] = '0'

Last-ModifiedETagは、 HTTP条件付きリクエスト で使用され、コンテンツの中身が前回取得のものと同じであればリクエストを飛ばさずにキャッシュを利用するようなケースでよく利用されます。
しかし、(個人的な印象ですが)APIのようなコンテンツが動的に生成されるような場合においては、キャッシュが利用できるケースは限られていて、キャッシュを利用したくないケースが多いと思います。

今回のケースでも、APIで動的コンテンツを返すような箇所だったので上記のような回避策でも問題無いと判断しました。

こんなので一日が潰れてしまった...

参考リンク

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2