Reputation: 740
I use rack-timeout and it works fine. But I couldn't figure out how to set time for a particular URL.
Even if I do like:
map '/foo/bar' do Rack::Timeout.timeout = 10 end
not only /foo/bar action but every action dies after 10 second.
Is it possible to set timeout for a particular URL? Or should I use another solution other than rack-timeout?
Upvotes: 5
Views: 5105
Reputation: 1802
Updated version of Jiten Kothari's answer:
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
Upvotes: 2
Reputation: 4065
put this code as timeout.rb under config/initializers folder and put your particular url on excludes array
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
Upvotes: 1
Reputation: 636
If you're worried about particular actions running too long, I would wrap the code of concern in a Timeout block instead of trying to enforce timeouts on a URL level. You could easily wrap up the below into a helper method and use it with a variable timeout throughout your controllers.
require "timeout'"
begin
status = Timeout::timeout(10) {
# Potentially long process here...
}
rescue Timeout::Error
puts 'This is taking way too long.'
end
Upvotes: 7