Within a complicated Ruby project, I need to monitor the connection to a PostgreSQL database, as answered here. I use a thread for this purpose. Every few milliseconds, I invoke "consume_input" which will raise an exception of the database connection no longer exists. If might have been closed for a number of reasons, but there is no indication from the socket/connection why it is closed. If the server is restarted and is alive again within a certain time-frame, I reconnect and assume everything is fine. Otherwise, I notify another object via a callback that all is not well, and the thread exits normally.
I'm looking for tips and suggestions on following best practices and correctness. I need some general Ruby advice on making my code cleaner and more robust.
PG_MAX_FAILURES=10
PG_SLEEP_QUANTA=0.25
def monitor_start
log.info("db: #{__method__}")
_dbconn=nil
if @monitor.alive?
@monitor.kill
sleep PG_SLEEP_QUANTA
end
@monitor = Thread.new {
_failures=0
while true do
begin
if ! _dbconn.is_a?PG::Connection or _dbconn.status() != PG::CONNECTION_OK
log.info("Reconnecting...")
_dbconn = PG.connect( @dbconnstr )
log.info("Reconnected.")
else
_dbconn.consume_input()
_failures=0
end
sleep PG_SLEEP_QUANTA
rescue PG::ConnectionBad => ex
_failures += 1
if _failures >= PG_MAX_FAILURES
@monitor_post_callback.call()
break # Thread.current.stop ??
end
log.warn("Postgresql connection lost. Retry# #{_failures}...")
sleep PG_SLEEP_QUANTA
retry
rescue => ex
log.warn("Other exception #{ex.class} #{ex.message}")
end
end
}
end