timeout doesn't seem to work properly
Reported by Matt Aimonetti (mattetti) | March 13th, 2010 @ 12:27 PM
require 'thin'
require 'sequel'
app = proc do |env|
body = ['should not display!']
db = Sequel.connect('mysql://root@localhost:3306/test')
db.execute("select sleep(15)")
[
200, # Status code
{ 'Content-Type' => 'text/html' }, # Reponse headers
body # Body of the response
]
end
Start as:
$ thin start -R timeout_test.ru -t 2
And try to load localhost:3000, in theory the request should timeout since the timeout limit is set to 2 seconds and the query will take 15s.
Tested against Thin 1.2.6 with Ruby 1.9 and 1.2.2 on Ruby 1.8.7
Comments and changes to this ticket
-
macournoyer March 16th, 2010 @ 02:23 PM
- State changed from new to resolved
- Tag set to timeout
Hey Matt,
This is because the timeout is handled at the connection level by EventMachine. Since Thin is single-threaded and the db.execute line is blocking the whole process, the control is never given back to EM during the whole time the proc executes.
Using a non-blocking MySQL driver could solve that issue (like I presented at Confoo) as it would give back the control to EM after sending the query, and before receiving the results.
Long story short... the solution is to use ruby Timeout module (or better, SystemTimer gem):
require 'thin' require 'sequel' require 'system_timer' DB = Sequel.connect('mysql://root@localhost:3306/talker_development') app = proc do |env| body = ['should not display!'] puts "Sending db query..." SystemTimer.timeout_after(2) do DB.execute("select sleep(15)") puts "Got db results!" end [ 200, # Status code { 'Content-Type' => 'text/html' }, # Reponse headers body # Body of the response ] end run app
Let me know if something is not clear.
-
Matt Aimonetti (mattetti) March 16th, 2010 @ 03:20 PM
Thanks Marc André, the problem is that when using Rails, you can't easily setup a timeout, I guess I could write a middleware that would automatically timeout my requests but it would be nice to have thin handle that for us. I believe passenger has this option too, I don't know about the other webservers.
Thanks again for looking into this
-
macournoyer March 16th, 2010 @ 03:34 PM
hmm right, I'll think about replacing Thin's timeout logic w/ SystemTimer...
in the meantime, this middleware will do the trick:
require 'system_timer' class Timeout def initialize(app, sec) @app = app @sec = sec end def call(env) SystemTimer.timeout_after(@sec) { @app.call(env) } end end
-
John December 13th, 2023 @ 11:58 AM
La gente trata de asegurar que los casinos en línea pueden ser tanto buenos como malos para su cartera. He estado jugando al proveedor de casino online VulkanVegas durante mucho tiempo y no puedo decir nada malo sobre él. Según las estadísticas, este casino online tiene el RTP más alto. https://vulkanvegas-pe.com/
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป