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

Ruby on rails 如何在可配置的超时内响应Rails请求,ruby-on-rails,ruby,thread-safety,timeout,Ruby On Rails,Ruby,Thread Safety,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 re

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

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
class AdminController
我希望避免使用Timeout,因为它会在我的应用程序中导致许多错误,包括数据库连接泄漏。报告的其他一些问题如下:

不要为此使用ruby。问题是超时模块将在执行代码的某个地方中止代码,这将导致套接字、连接和文件打开或悬空,甚至更糟。(我想,如果您正在启动外部脚本或为每个作业进行测试,这并不是一个真正的问题,但在这些情况下,只需使用unix/linux本机io超时)

这就是ruby CI服务器从未起飞的原因(Jenkins是java)。 我将使用一个单独的服务来设计它,该服务处理运行中的作业,您可以使用API ping这些作业;然后,在您的视图中,每隔几秒钟ping一次,这样他们就可以看到持续的更新。在本例中,rails应用程序不需要任何超时代码

编辑:由于您在该块中执行HTTP请求,只需使用HTTP库中内置的超时设置(例如)

您可以使用
gem“rack timeout”
完全满足您的要求

# Gemfile

gem "rack-timeout"

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

希望这能对您有所帮助。

您在这个请求中实际做了什么?对于一个更大的问题,超时是一个糟糕的解决方案-您可能能够预处理或将其中一些代码转换为作业,甚至可以使用状态机将请求拆分为多个阶段。@Court3可能是一个运行作业的web服务,处理作业可能需要100毫秒到30秒。每个客户端都可以为请求的作业指定自己可接受的超时。@barbolo您当前的代码有一个缺陷。最好将超时包装在
begin
块中,然后是
rescue=>e
。你想达到什么目的?如果查询耗时过长,则停止请求?代码被包装在“try/catch”结构中,我只是没有使用begin。如果耗时过长,则希望停止请求。对但是“太长”应该是可配置的。谢谢你,@court3nay。我希望通过纯Ruby的解决方案来批准答案。让我们看看我得到了什么。它派遣了一个网络刮板。哦,看,那容易多了。(为什么不这么说呢!呵呵)大多数http库实际上都有一个超时设置。例如,具有每个请求的连接和请求超时设置。另请参见具有打开超时、读取超时、ssl超时和其他设置的net/http;它只有一个:timeout,但是这个类可以被重写。这不是我问题的解决方案。这项任务比那要复杂一点。您可以想象,对于收到的每个web服务请求,我可能会发出3或4个HTTP请求和数据库操作。因此,为每个I/O操作设置超时似乎并不适用。这实际上是一个很好的方法,但并不能解决我的问题。它不允许我指定每个请求的超时时间。它要求在应用程序初始化期间指定一个固定的超时值。