Specify the timeout for each path with Rack :: Timeout

Previously (up to rails 5.2.3, rack-timeout 0.5.1) to change the timeout specification for each path using rack-timeout Was specified as follows (slightly simplified).

Gemfile


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

config/initializers/rack_timeout.rb


module Rack
  class DynamicTimeout < Rack::Timeout
    def call(env)
      #URL is/30 seconds if starting with admin, 10 seconds otherwise
      @service_timeout = env['REQUEST_URI'].start_with?('/admin') ? 30 : 10

      super(env)
    end
  end
end

timeout_params = {
  service_timeout: 10,
  wait_timeout: 5.minutes.to_i,
  wait_overtime: 5.minutes.to_i,
  service_past_wait: false,
}

Rails.application.config.middleware.insert_before Rack::Runtime, Rack::DynamicTimeout, timeout_params

However, starting with Rails 6 or rack-timeout 0.6.0, the timeout was shorter than the dynamically specified value of service_timeout. It was actually shorter (10 seconds) than the value output to the log (30 seconds) as shown below.

severity:ERROR	message:source=rack-timeout id=0284947e-c24c-4024-a9ba-c542b3eb58f9 timeout=30000ms service=10000ms state=timed_out

After investigating the cause by preparing various logs, it seems that the call of Rack :: Timeout itself is called in addition to the call of Rack :: DynamicTimeout.

For convenience, the call method was executed twice, first with Rack :: DynamicTimeout, then with Rack :: Timeout, and finally the timeout value was specified with Rack :: Timeout. The value is used. It seemed like it would take some time to find out where it was called and if it could be changed, so this time I decided to use a patch that overwrites Rack :: Timeout.

Gemfile


gem 'rack-timeout'

config/initializers/rack_timeout.rb


module Rack
  module DynamicTimeout
    def call(env)
      #URL is/30 seconds if starting with admin, 10 seconds otherwise
      @service_timeout = env['REQUEST_URI'].start_with?('/admin') ? 30 : 10

      super(env)
    end
  end
end

Rack::Timeout.prepend Rack::DynamicTimeout

Enabled to handle even if call of Rack :: Timeout is called by inserting the module with Module # prepare. With this for the time being.

Recommended Posts

Specify the timeout for each path with Rack :: Timeout
Change the injection target for each environment with Spring Boot 2
Change the setting value for each environment with Digdag (RubyOnRails)
Common markup: Change url path for each action
I summarized the naming conventions for each Rails
Specify the default value with @Builder of Lombok
Rewrite the code for java.io.File with java.nio.Path and java.nio.Files
Oreore certificate https (2020/12/19) for the first time with nginx
[Java] Get the file path in the folder with List
Challenge the settings for developing with vue.js on Rails 6
How to specify the resource path in HTML import
Prepare the environment for java11 and javaFx with Ubuntu 18.4
Specify VS Code as the default editor for jshell