Verify database connections in long-running idle Rails processes
I've interfaced one of my xmpp4r bots with the Xeriom Networks control panel. I had intended to write a post about it to show how easy it is, but I've been beaten to it. I can, however, offer one piece of advice that will stop the bot dying after a few hours of idling: periodically verify your database connections.
RAILS_DEFAULT_LOGGER.debug "Launching database connection verifier"
Thread.new do
loop do
sleep 1800 # Half an hour
RAILS_DEFAULT_LOGGER.debug "Verifying database connections"
ActiveRecord::Base.verify_active_connections!
end
end
Adding the above code to a script will stop database connections getting dropped (or, at least, will reconnect them if it happens).
To see it in action, add support@xeriom.net to your XMPP roster and have a chat. It's not hugely intelligent, but it does support a few useful commands.
Offline tasks the easy way
There's been quite a lot of chat recently about various job scheduling systems and process managers for offlining expensive tasks on the LRUG list. BackgrounDRb, Beanstalk, Starling, BackgroundJob and other similar solutions have been discussed. These systems can be useful, but most of the time they're just adding unnecessary complexity.
One instance where I feel these solutions are unnecessary is where you need to strip data from an external service in a way that's totally disconnected from the HTTP request-response cycle.
Say you want to pull the most recent article from this blog every 15 minutes and create a file that could then be served statically to your visitors. A naive implementation of that functionality would look something like this:
require 'net/http'
require 'hpricot'
barking_iguana = URI.parse('http://barkingiguana.com/')
loop do
articles = Hpricot(Net::HTTP.get(barking_iguana))
title = (articles / "div.article a[@rel=bookmark] text()").first
link = (articles / "div.article a[@rel=bookmark]").first['href']
# Of course, this should have a real file path in it.
File.open("/.../.../.../barking_iguana.ssi", "w+") do |f|
f.write("#{title}: #{link}")
f.flush
end
sleep 900 # 15 minutes
end
Doesn't that look nice? No screwing around with complex tools to handle the scheduling - just run it and it'll go forever.
"Ah," I hear you say, "but what if it crashes?" Well, in the unlikely event that such a simple script does crash I'd have something like God monitoring the processes so it would be restarted. You've got something monitoring your processes anyway (right?) so it should be pretty simple to add another process to that list.
Love me!
If you've found this article useful I'd appreciate recommendations at Working With Rails.
Related articles
XMPP4R-Simple makes XMPP in Ruby uhh... simple...
I thought it might be cool to have a control interface that you could talk to using IM, something like the IM client for Twitter.
Initially I was looking at XMPP4R but a little reading pointed out that there's a gem called XMPP4R-Simple. Well, simple is always good so one gem install and 45 minutes later I had a Ruby script that could log in to an XMPP server, listen to (and log) what people said, and respond with a simple message.
#!/usr/bin/env ruby
require 'rubygems'
require 'xmpp4r-simple'
logfile = File.join('..', 'log', "#{File.basename(__FILE__)}.log")
logger = Hodel3000CompliantLogger.new(logfile)
jabber = Jabber::Simple.new "username@domain.com", "password"
sleep 1
jabber.status(:away, "No one here but us mice.")
sleep 1
jabber.deliver("craig@xeriom.net", "I woke up at #{Time.now}.")
loop do
begin
jabber.received_messages do |msg|
jid = msg.from.strip.to_s
logger.info "%s said: %s" % [ jid, msg.body ]
jabber.add(jid) if !jabber.subscribed_to?(jid)
jabber.deliver(jid, "Nom nom nom.")
end
jabber.presence_updates do |update|
jid, status, message = *update
logger.info "#{jid} is #{status} (#{message})"
end
jabber.new_subscriptions do |friend, presence|
logger.info "#{friend.jid} #{presence.type}"
jabber.add(friend.jid) if !jabber.subscribed_to?(friend.jid)
end
rescue Exception => e
logger.error e.to_s
end
sleep 1
end
Our own little pet XMPP client. How cute is that?
Quit yo jibba jabba, sucka!
If you've found this article useful I'd appreciate recommendations at Working With Rails.
Class, Instance and Singleton methods
There are three types of methods in Ruby and I always get them confused. Here, for my future reference, is what I currently think they mean.
Class methods
Methods which can be called directly on a class.
Time.now
Monkey.find(:all)
Instance methods
Methods which can be called on any instance of that class.
@widget.to_s
Time.now.to_f
Singleton methods
Methods which can be called only on a specific instance of that class.
chicken = Chicken.new
class << chicken
def hide
# ...
end
end
chicken.hide


