Here is one of my web log entries, perhaps from my Yakkity Yak page, What's New page, or one of my Astounding Adventures from my Geocaching section:

Asynchronous (Non-Blocking) Communication in Ruby
Wednesday, 29 April 2009 2:49 PM MDT
Yakkity Yak
In doing work in Ruby for back-end infrastructure that needs to contact multiple RouterOS devices quickly and efficiently (using the RouterOS API), I've been exploring some non-blocking Ruby libraries. Looking at eventmachine and Rev, I'm leaning towards Rev due to Ruby 1.9 having integrated a lot of nonblocking stuff now.

So for asynchronous DNS resolution, I whipped up a little test script:
require 'rev'

def resolve_name(query, success_callback=nil, fail_callback=nil, loop=nil)
  unless query.is_a?(String) && query.length > 0
    raise ArgumentError.new(
      "unexpected argument query (expected String of non-zero length)"
    )
  end
  unless loop.nil? || loop.is_a?(Rev::Loop)
    raise ArgumentError.new(
      "unexpected argument class '#{loop.class}' for loop (expected Nil" +
      " or Rev::Looop)"
    )
  end
  unless success_callback.nil? || success_callback.is_a?(Proc)
    raise ArgumentError.new(
      "unexpected argument class '#{success_callback.class}' for " +
      "success_callback (expected Nil or Proc)"
    )
  end
  unless fail_callback.nil? || fail_callback.is_a?(Proc)
    raise ArgumentError.new(
      "unexpected argument class '#{fail_callback.class}' for " +
      "fail_callback (expected Nil or Proc)"
    )
  end
  aloop = loop.nil? ? Rev::Loop.new() : loop
  answer = nil
  onsuccess = success_callback.nil?     ?
    lambda { |result| answer = result } :
    success_callback
  onfail    = fail_callback.nil? ?
    lambda { onsuccess.(nil)   } :
    fail_callback
  Class.new(Rev::DNSResolver) do
    def initialize(query, on_success, on_fail)
      @on_success = on_success
      @on_fail    = on_fail
      super(query)
    end
    def on_fail
      return @on_fail.nil? ? nil : @on_fail.()
    end
    def on_success(result)
      if @on_success.nil?
        return result
      else
        return @on_success.(result)
      end
    end
  end.new(query, onsuccess, onfail).attach(aloop)
  aloop.run if loop.nil?
  return answer
end

loop = Rev::Loop.new()
def rq(query, loop)
  resolve_name(
    query,
    lambda {|result|
      if result.nil?
        print "'#{query} failed to resolve.\n"
      else
        print "'#{query} resolves to '#{result}'\n"
      end
    },
    nil,
    loop
  )
end
ARGV.each do |query|
  rq(query, loop)
  if query =~ /^\d+\.\d+\.\d+\.\d+$/
    rq(query.split(/\./).reverse.join('.') + '.in-addr.arpa', loop)
  end
end

loop.run
This lets me test it from the command line:
$ ./x.rb www.google.com www.infowest.com \
 www.eq.net hatrack.com eq.net fooaasdvwedf.df \
 127.0.0.1 204.17.177.10
'www.google.com resolves to '74.125.155.103'
'127.0.0.1 resolves to '127.0.0.1'
'www.infowest.com resolves to '204.17.177.250'
'www.eq.net resolves to '69.46.228.43'
'hatrack.com resolves to '66.223.20.195'
'eq.net resolves to '69.46.226.134'
'1.0.0.127.in-addr.arpa failed to resolve.
'204.17.177.10 resolves to '204.17.177.10'
'10.177.17.204.in-addr.arpa failed to resolve.
'fooaasdvwedf.df failed to resolve.
Ah, looks like Rev::DNSResolver.new() doesn't like to look up PTR records... I need to find better documentation to learn how to tell it to do PTR resolution instead of just IP resolution. Currently actual useful documentation is scarce, which seems quite common for most things in Ruby. *sigh*

Still, I quite like the single-threaded non-blocking event-style this (and similar libraries) allow. Now if only the Ruby MySQL module were fully asynchronous/non-blocking and event-ified (and I am ignoring NeverBlock's work in this area, as I've not tried it out yet, and also I'm hoping for something to become "mainstream").

With all this non-blocking stuff, monitoring tons of RouterOS devices using a single process (except for the MySQL database updates) should go smoothly. I like it!