Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

timeout doesn't seem to work properly

#129
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

Reported by Matt Aimonetti (mattetti) · March 13th, 2010 @ 12:27 PM

State: resolved
Milestone: none
Assigned to: macournoyer macournoyer

Activity

  1. macournoyer
    macournoyer
    • 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.

    March 16th, 2010 @ 02:23 PM

  2. Matt Aimonetti (mattetti)
    Matt Aimonetti (mattetti)

    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

    March 16th, 2010 @ 03:20 PM

  3. macournoyer
    macournoyer

    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
    

    March 16th, 2010 @ 03:34 PM

  4. John
    John

    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/

    December 13th, 2023 @ 11:58 AM

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.