0

I am trying to render few static pages in my rails app when the mysql server is shut down. I tried to catch the Mysql::Error exception and render the corresponding static page for each controller.

When we just stop the mysql service in the machine where the mysql is installed. The Mysql::Error exception is thrown immediately and i am able to render the pages without any delay. but if i just shut down the server. The whole website becomes irresponsive.

I traced down the actual function in the rails framework , which is taking 3 mins to complete. It was this statement

Mysql.real_connect

in the active_record gem. which takes so long. Is there any way i can give a time out so that , when the mysql server is powered off. it returns with the Mysql::Error exception really quickly so that i can render the pages without any delay??

anusuya
  • 653
  • 1
  • 9
  • 24

2 Answers2

1

This is probably coming from the socket timeout within the mysql adapter. When the service is stopped, the server will respond quickly with a connection refused error. When the server itself is down, the socket will have to get a connection timeout before it returns. What you'll probably have to do is monkey patch the #real_connect method so that it first validates that the server is running by attempting a socket connection (with a timeout) before continuing on with the original implementation. This question may be of some help to you there:

How do I set the socket timeout in Ruby?

Community
  • 1
  • 1
Keith Gaddis
  • 4,113
  • 23
  • 20
  • is putting a timeout around the real_connect call a a good option?? like timeout(5) do Mysql.real_connect() end?? – anusuya Nov 29 '10 at 17:35
  • It looks like it depends on the Ruby version you're using. See http://ph7spot.com/musings/system-timer and http://www.mikeperham.com/2009/03/15/socket-timeouts-in-ruby/ – Keith Gaddis Nov 29 '10 at 17:40
  • i used system-timer gem to timeout the real_connect method. it worked perfectly. am thinking of how many sec to wait before timingout the system call? will 2 sec will be correct? or even 1 sec is enough? – anusuya Nov 30 '10 at 10:55
  • Depends on where the infrastructure is located. A number of factors can figure into response latency. If they're on the same network segment I'd probably set it to at least two seconds to be on the safe side. If they're on a different network segment, I'd give it more along the lines of a 5 or 10 second timeout, and have it raise an exception you can catch in your application and notify yourself of the exception so you can get the server back up ASAP. The problem is that if you set it too long, you're opening a window for a DOS attack, too short and you're looking at false positives. – Keith Gaddis Nov 30 '10 at 15:56
1
  dbh = Mysql.init
  dbh.options(Mysql::OPT_CONNECT_TIMEOUT, 6)