如何在可配置的超时内响应Rails请求

时间:2015-10-18 01:06:00

标签: ruby-on-rails ruby thread-safety timeout

我希望在不使用Timeout模块的情况下在控制器的操作中实现以下行为:

class AdminController < ApplicationController
  def example
    Timeout.timeout(params[:timeout].to_i) do
      ... # try to process the request within params[:timeout] seconds
    end
  rescue Timeout::Error
    render nothing: true, status: :gateway_timeout
  end
end

我想避免使用Timeout,因为它导致我的应用程序中出现许多错误,包括数据库连接泄漏。报告的其他一些问题: http://www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/

2 个答案:

答案 0 :(得分:4)

不要使用红宝石。问题是超时模块将在执行代码中的任何地方中止代码,这将导致打开和悬空的套接字,连接和文件或更糟。 (如果您正在为每个作业启动一个外部脚本或炮轰,这不是一个真正的问题,我想,但在这些情况下只使用unix / linux native io timeout)

这就是为什么ruby CI服务器从未起飞的原因(Jenkins是java)。 我设计了一个单独的服务来处理你可以使用API​​ ping的运行作业;然后,在您的视图中,每隔几秒钟ping一次,以便他们可以看到持续更新。在这种情况下,rails app不需要任何污染超时代码。

编辑:由于您正在该块中执行HTTP请求,只需使用http库中内置的超时设置(例如https://github.com/lostisland/faraday

答案 1 :(得分:3)

您可以使用gem "rack-timeout" https://github.com/heroku/rack-timeout完全填写您的要求。

# Gemfile

gem "rack-timeout"

# config/initializers/rack_timeout.rb
Rack::Timeout.timeout = 5  # seconds

希望这会对你有所帮助。