【问题标题】:How to set timeout for a particular URL in rails如何在 Rails 中为特定 URL 设置超时
【发布时间】:2013-05-06 11:16:02
【问题描述】:

我使用 rack-timeout 并且它工作正常。 但我不知道如何为特定 URL 设置时间。

即使我喜欢:

map '/foo/bar' 做 机架::超时。超时 = 10 结尾

不仅是 /foo/bar 动作,而且每个动作都会在 10 秒后终止。

是否可以为特定 URL 设置超时? 还是应该使用机架超时以外的其他解决方案?

【问题讨论】:

  • 顺便说一句,我正在使用 Heroku。

标签: ruby-on-rails timeout rack


【解决方案1】:

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

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

【讨论】:

    【解决方案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
    

    【讨论】:

      【解决方案3】:

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

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-05
        相关资源
        最近更新 更多