首页 > 解决方案 > 如何查找/检索已在 Rails 中配置的 Rack::Timeout 超时值?

问题描述

在我们的 Rails 应用程序中,我们使用 rack-timeout 0.4.2 并将其配置config/initializers/timeout.rb为 prod 和 staging,如下所示:

if Rails.env.production? || Rails.env.staging?
  Rack::Timeout.timeout = (ENV['RACKTIMEOUT'] || 25).to_i # seconds
end

当我们在不久的将来升级 gem 时,这些值可能会设置为service_timoutwait_timeout

我想检索在应用程序中设置的这个值作为任何MySidekiqWorker.perform_in(CURRENT_TIMEOUT_VALUE, ...)调用的默认值,而不是只(ENV['RACKTIMEOUT'] || 25).to_i在需要的地方写。我在这里尝试解决的问题是这个 sidekiq 问题,它找不到模型,因为它尚未提交。现在不能将这些调用重构为after_commit钩子。

这次尝试给出了以下结果:

0> Rack::Timeout.timeout
=> private method `timeout' called for Rack::Timeout:Class

并且Rails.app.configuration只有 Rails.app.configuration.middleware.includes? Rack::Timeoutastrue并且没有给出我可以看到的任何值。

标签: ruby-on-railsrubysidekiqrack

解决方案


我假设您在谈论https://github.com/sharpstone/rack-timeout

0.4.2 允许使用一些向后兼容的方法读取值:

Rack::Timeout.service_timeout
=> 25

这似乎是处理这个问题的错误方法。您正在根据环境变量在 Rails 中设置值,因此只需确保它在以下位置定义ENV

# config/initializers/timeout.rb
if Rails.env.production? || Rails.env.staging?
  ENV['RACKTIMEOUT'] ||= '25'
  Rack::Timeout.timeout = ENV['RACKTIMEOUT'].to_i
end

然后你可以从任何地方阅读它:

MySidekiqWorker.perform_in(ENV['RACKTIMEOUT'].to_i, ...)

最好使用figaroENV之类的东西将逻辑分解为单独的配置,以使其更易于管理。

如果您决定升级到较新版本的 gem,这将使您的生活更轻松。我建议调查一下,因为 0.4.2 现在大约 4 岁了。0.6.0 是最新版本,gem使用一些默认环境变量进行自我配置,因此您所要做的就是设置ENV['RACK_TIMEOUT_SERVICE_TIMEOUT'],然后您可以完全跳过初始化程序。


推荐阅读