zombocom/rack-timeout

Manually Inserting Middleware + Setting Timeout With Rails WITHOUT Gemfile

sshaw opened this issue · 5 comments

sshaw commented

If the Rails app/engine is a gem and it includes rack-timeout in its gemspec one cannot manually insert the middleware with a custom timeout:

Rails.application.config.middleware.insert_before Rack::Runtime, Rack::Timeout, service_timeout: MY_TIMEOUT

This will not work because the middleware has already been inserted by the Railtie with a default timeout of 15 seconds.

Since Rails.application.config.middleware is just a proxy that records the operations, using middleware.delete Rack::Timeout then insert_before(....) does not work.

Without further digging, it appears that in the scenario one can only use the environment variable to set timeout..?

I have the same question; as far as I understand, since the gem loads rack/timeout/rails.rb if Rails is defined, it will already have run app.config.middleware.insert_after(ActionDispatch::RequestId, Rack::Timeout), so there's no way to manually include it without having it loaded twice, right?

In my use case, I'm trying to update a fork of this gem (https://github.com/skatedude007/rack-timeout) with master so I can have Rails 6 support, but the fork uses the deprecated (now removed) class method settings.

So since that's not supported anymore, I need to manually include the middleware to pass parameters to it (in this case, a proc where the logic for setting custom timeouts based on each route), but it seems to be no way of doing that.

Hello! You should be able to avoid the automatic insertion by doing the following in your Gemfile:

gem "rack-timeout", require: "rack/timeout/base"

You can then insert the middleware manually with your desired settings.

By doing so, you will avoid loading the main rack-timeout.rb file, which is what loads the Railtie.

Please let me know if this doesn't work for you! A PR to update the documentation for this issue would be welcome, and if you can think of a better user experience to address this issue, let me know!

Edit: this is actually already documented here, but as my next comment explains, this isn't possible in this case:
https://github.com/sharpstone/rack-timeout#rails-apps-manually

Apologies, I missed that you may not have direct control over your Gemfile, i.e.:

If the Rails app/engine is a gem and it includes rack-timeout in its gemspec

I'm not familiar with the ins-and-outs of engines but I'd probably suggest engine authors do not include rack-timeout. I realize that might not help you if you are not the author, but you might raise this issue with the author. Regardless, yes, you can adjust the settings using the environment variables (or disable it by using 0).

Since Rails.application.config.middleware is just a proxy that records the operations, using middleware.delete Rack::Timeout then insert_before(....) does not work.

I'd love to know more about this, I'm not aware of what's going on here.