如何在rails中为特定URL设置超时

时间:2013-05-06 11:16:03

标签: ruby-on-rails timeout rack

我使用机架超时,它工作正常。 但我无法弄清楚如何为特定网址设置时间。

即使我喜欢:

map '/foo/bar' do
  Rack::Timeout.timeout = 10
end

不仅是/ foo / bar动作,而且每次动作都会在10秒后死亡。

是否可以为特定网址设置超时? 或者我应该使用除机架超时以外的其他解决方案吗?

3 个答案:

答案 0 :(得分:4)

如果您担心特定操作运行时间过长,我会将关注的代码包装在Timeout块中,而不是尝试在URL级别上强制执行超时。您可以轻松地将下面的内容包装到辅助方法中,并在整个控制器中使用变量超时。

require "timeout'"
begin
  status = Timeout::timeout(10) {
  # Potentially long process here...
}
rescue Timeout::Error
  puts 'This is taking way too long.'
end

答案 1 :(得分:2)

Jiten Kothari的答案的更新版本:

module Rack
  class Timeout
    @excludes = [
      '/statistics',
    ]

    class << self
      attr_accessor :excludes
    end

    def call_with_excludes(env)
      #puts 'BEGIN CALL'
      #puts  env['REQUEST_URI']
      #puts 'END CALL'

      if self.class.excludes.any? {|exclude_uri| /\A#{exclude_uri}/ =~ env['REQUEST_URI']}
        @app.call(env)
      else
        call_without_excludes(env)
      end
    end

    alias_method_chain :call, :excludes

  end
end

答案 2 :(得分:1)

将此代码作为timeout.rb放在config / initializers文件夹下,并将您的特定网址放在排除数组

require RUBY_VERSION < '1.9' && RUBY_PLATFORM != "java" ? 'system_timer' : 'timeout'
SystemTimer ||= Timeout

module Rack
  class Timeout
    @timeout = 30
    @excludes = ['your url here',
                 'your url here'
    ]

    class << self
      attr_accessor :timeout, :excludes
    end

    def initialize(app)
      @app = app
    end

    def call(env)
      #puts 'BEGIN CALL'
      #puts  env['REQUEST_URI']
      #puts 'END CALL'

      if self.class.excludes.any? {|exclude_uri| /#{exclude_uri}/ =~ env['REQUEST_URI']}
        @app.call(env)
      else
        SystemTimer.timeout(self.class.timeout, ::Timeout::Error) { @app.call(env) }
      end
    end

  end
end