debugrubyMinor
Monitoring and re-establishing a PostgreSQL connection
Viewed 0 times
postgresqlestablishingmonitoringandconnection
Problem
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.
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
}
endSolution
What follows is just my subjective opinion; you can disagree.
-
Robust code is maintainable. You need to be able to change this code if you find a bug in it, or if the requirements change. It might even be that someone else may need to maintain this code. So you should probably use a regular indenting pattern (2 spaces is normal for Ruby). That would make it a lot easier to see what was going on.
-
Likewise, your code would be cleaner if it was split into separate functions. Making the contents of the
-
It seems to me that the
-
Robust code is maintainable. You need to be able to change this code if you find a bug in it, or if the requirements change. It might even be that someone else may need to maintain this code. So you should probably use a regular indenting pattern (2 spaces is normal for Ruby). That would make it a lot easier to see what was going on.
-
Likewise, your code would be cleaner if it was split into separate functions. Making the contents of the
thread.new block a separate function would be a good place to start, but you could (and maybe should) go further than that. -
It seems to me that the
sleep ... retry at the end of the first rescue block are redundant, since you are going to loop around again anyway. YMMV.Context
StackExchange Code Review Q#92444, answer score: 2
Revisions (0)
No revisions yet.