Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
streaming interrupted before complete with ActionController::Live in Rails 5 for production environment #25581
Sorry, at the time being I don't have much details or a sample application to reproduce the issue but I was finally able to understand that my streamed response was interrupted after the first writes after I upgraded the application to Rails 5. Unfortunately it only happens in my production (and staging) servers, not under the development environment. I have to sign off for today but I'd love to get any input that might help me digging on what could be causing this issue in production with Rails 5.
Any ideas on what has been changed in Rails 5 that could be causing this issue? This is not related to nginx since I tried using curl directly to localhost:port and I get the same error. as soon as the controller has to wait for some more data the connection is interrupted so I only see the output of the first stream.write calls. The action finishes without any errors so I don't know what could be happening.
If I can't think of anything that could fix this tomorrow morning I'm afraid I'll have to downgrade to Rails 4 until I'm able to figure out what's happening. Please let me know if you think you can help with this issue.
Ok, I was finally able to track down what is causing the problem. The response being created is the regular one rather than the live version because
class MyController < ApplicationController include StreamingSupport end
And StreamingSupport is defined as:
require_dependency 'action_controller' # Adds support for streaming using ActionController::Live. # # Also handle the unauthenticated cases where warden would throw a # :warden symbol, but it would cause an exception because the live # controller runs in a separate thread and only propagates exceptions. # There is currently no way to proparate throws through the Thread # boundary. # # To handle this situation, we detect an ArgumentError caused by # an uncaught throw by warden, then we rethrow the :warden symbol # without any parameters. This will cause the appropriate warden # handlers to run. Note that custom actions or any other parameters # to throw :warden are lost. # # https://github.com/hassox/warden/wiki/Failures # https://bugs.ruby-lang.org/issues/6372 # https://github.com/plataformatec/devise/issues/2332 # https://github.com/rails/rails/issues/13873 module StreamingSupport include ActionController::Live # for it to work on Rails 5 this must be moved directly # to each controller including StreamingSupport def process(name) super(name) rescue ArgumentError => e if e.message == 'uncaught throw :warden' throw :warden else raise e end end end
If I move that
That makes sense. I guess another alternative would be using an "included" hook in the module so that I can include it directly in the controller.
In any case we can simply close this issue if we think I'm the only one taking this approach or we could add some note to the changelog in case someone else would be interested in knowing about this. This was tricky for me because it only happened in the production servers and I was only able to reproduce locally and debug the issue after switching to something similar to the production mode. So, if they test the behavior before going live they would be inclined to think everything is fine until someone reports the error in production.
If you are interested in such a note I can add it to the actionpack changelog and create a PR but if you think this won't affect anyone else than that's fine too, simply close this issue.
However if you prefer me to add this note to the changelog, please let me know where it should go, as this behavior has probably changed in one of the first beta releases, so I'm not sure it should go there or on the more recent notes section...
@rosenfeld can you add it to the upgrade guide under the upgrading to Rails 5 guide? https://github.com/rails/rails/blob/master/guides/source/upgrading_ruby_on_rails.md#upgrading-from-rails-42-to-rails-50
and in the release notes under ActionPack? https://github.com/rails/rails/blob/master/guides/source/5_0_release_notes.md#notable-changes-1