Syndication IconNew article alerts are available via Atom. Hide this message

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.

State of Ruby / Xen API's

Recently I've been doing a lot of work on creating a management interface for Xen VMs in one of my Rails applications. The current state of Xen API's is not well documented which makes it rather hard to implement. In fact, just about the only comparison that I can find of the API's appears to be on the Xen mailing list in an email from Ewan Mellor.

  • xend-http-server: Very old and totally broken HTML interface and legacy, generally working SXP-based interface, on port 8000.
  • xend-unix-server: Ditto, using a unix domain socket.
  • xend-unix-xmlrpc-server: Legacy XML-RPC server, over HTTP/unix, the recommended way to access Xend in 3.0.4.
  • xend-tcp-xmlrpc-server: Ditto, over TCP, on port 8006.
  • xen-api-server: All new, all shiny Xen-API interface, available in preview form now, and landing for 3.0.5.
-- Ewan Mellor, 2007-01-24 in http://lists.xensource.com/archives/html/xen-api/2007-01/msg00006.html

As far as I can tell, if you use Xen <= 3.0.4 the best option is to use the Ruby-Xen gem to work with the legacy Xen XML-RPC API. If you're using Xen >= 3.0.5 the preferred method of integration appears to be the almost-undocumented Xen API*, which as far as I can tell has no existing Ruby client.

A paper which talks about the Xen API is available at http://research.iu.hio.no/theses/pdf/master2007/ingard.pdf which seems to suggest that the new Xen API also uses XML-RPC, with a sample script available at http://folk.uio.no/ingardm/thesis/xensource.xeninfo.pl.

In the following weeks I hope to setup some modern Xen dom0's and begin to document exactly what is required to get the Xen API setup and accessible from a host within the same network as the dom0.

* Update, 2008-03-15

I found a draft definition of the new XML-RPC API on the XenSource Wiki. A huge cake is the prize for anyone that writes a BSD or MIT licenced Ruby interface against the specification given there.

The end of the world is nigh

According to Ruby, the world ends (or, at least, is reconfigured) on Tuesday the 19th of January 2038 at 7 seconds past 3.14am.

>> Time.utc(2038, 1, 19, 3, 14, 7, 999999)
=> Tue Jan 19 03:14:07 UTC 2038
>> Time.utc(2038, 1, 19, 3, 14, 7, 999999).succ
=> Fri Dec 13 20:45:52 UTC 1901

This is an artefact of representing time as an integer counting from the epoch, but given that a Fixnum will automatically roll over into a Bignum when it reaches 2**30, it's somewhat surprising that a similar transformation isn't performed internally in Time to allow us to represent dates and times beyond 2038-01-19.

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

Showing multiple message types with the flash

Traditionally the Rails flash is used to store only one message, usually in flash[:message] but I like to be able to differentiate between warnings and information in my view rather than displaying them both in the same place in the same style.

The flash is a HashWithIndifferentAccess so we can use any key we want to store messages and pull them back out later, in the view.

In your controller you simply use whichever key is most appropriate.

if @widget.save
  flash[:info] = "Your widget has been saved."
  flash[:notice] = "There are now #{Widget.count} widgets."
  redirect_to @widget and return
else
  flash.now[:warning] = "I couldn't save your widget."
  render :action => "edit"
end

In the view you can now iterate over the flash and pick out the key and the message.

<%= flash.sort.collect do |level, message|
  content_tag(:p, message, :class => "flash #{level}", :id => "flash_#{level}")
end.join %>

Say the @widget got saved earlier, you'd end up with some easily understood and styled markup.

<p class="flash info" id="flash_info">Your widget has been saved.</p>
<p class="flash notice" id="flash_notice">There are now 29 widgets.</p>

Of course, in the interest of readability the flash loop in the view should be extracted to a helper, but that's left as an exercise for the reader.

Related articles

About the author

A picture of Craig in black and white

Hi, I'm Craig. I'm obsessed with the web, accessibility, usability and good design in general. I live, work and play in London and love it.

Occasionally I have to work. When I do I generally use Ruby — frequently Rails. I'm available for freelance work if you have an interesting project.

You can contact me by email, MSN or GTalk / Jabber. My address on all of these is craig@xeriom.net.

I Work With Rails

Recommend Me

Blog Roll

Now Playing