5

I have been attempting to get streaming working in Rails 3.2 on Heroku (see my SO post here: Rails 3.2 streaming).

I am coming to the conclusion that rack-cache is causing the problem. Disabling it using config.middleware.delete(Rack::Cache) in production.rb seems to fix it. This, obviously, disables it for my entire app.

I only want it disabled for the one streaming request (which is on the admin side and will be used infrequently). Is this possible? It'd be a major bummer to lose caching for the sake of one small (but required) admin feature.

Thanks very much!!!

Edit: I have attempted setting the headers to not cache the action in question, but Rack::Cache is still causing the streaming to fail. Totally disabling it is the only solution I have found so far.

Community
  • 1
  • 1
Matt Fordham
  • 3,147
  • 10
  • 34
  • 51
  • What really helped me in this question was actually just knowing that you could disable Rack::Cache using `config.middleware.delete("Rack::Cache")`. (P.S.: It needs quotes around Rack::Cache.) – thekingoftruth Sep 25 '13 at 17:17

2 Answers2

2

I ended up not needing to disable Rack-cache. Just needed to add this self.response.headers['Last-Modified'] = Time.now.ctime.to_s to my response.

Matt Fordham
  • 3,147
  • 10
  • 34
  • 51
1

While you can't disable it, you might not need to; you may just need to bypass the caching mechanism.

Per the source here and here, if the Cache-Control: no-cache header or the Pragma: no-cache headers are set, Rack::Cache won't attempt to pull a request from the cache. That doesn't disable it, but it does let you ensure that you don't have a request that shouldn't be cached end up returning a caching response.

Additionally, you can ensure that Rack::Cache never caches a response for a given action with something like:

response.headers['Cache-Control'] = 'private,max-age=0,must-revalidate,no-store'

in your controller action. This will ensure that Rack::Cache (and any other upstream proxies) don't cache the response, resulting in an always-fresh hit to your backend.

If this fails, then you're likely having issues due to the forward method in context.rb. There doesn't seem to be a way to bypass it, so you'd probably want to patch Rack::Cache to just invoke #call if a certain header is set.

Chris Heald
  • 61,439
  • 10
  • 123
  • 137
  • Unfortunately, it seems that setting the headers doesn't fix it. Seems like I need to get Rack::Cache totally out of the way. I'll investigate your patch idea... any pointers on how I might do that? Thanks! – Matt Fordham Mar 29 '12 at 22:14
  • You should drop the max-age. From RFC2616: If a request includes the no-cache directive, it SHOULD NOT include min-fresh, max-stale, or max-age. – zaius Feb 05 '13 at 09:21
  • That portion of the RFC applies to the request header, not the response headers. – Chris Heald Feb 05 '13 at 13:00