Skip to content
This repository has been archived by the owner on Dec 27, 2022. It is now read-only.

Working with Callbacks

lusis edited this page Mar 15, 2011 · 4 revisions

Working with Callbacks


There are currently two ways to work with callbacks:

  1. Using the agent "daemon"
  2. Tapping into the Redis "stream"

Using the agent daemon

A word of note. The agent daemon is not so much a daemon and isn't quite "production" ready. I'm still testing various techniques and there's simply lots of cruft in there. Everything appears to be working properly but I don't have any proper specs yet because it's all EventMachine based.

That being said, I think I've worked out most if not all of the crashes that occur in my test scenario. The biggest limitation of the current agent is that it doesn't handle anything other than HTTP callbacks.

Installation

The agent daemon comes with the Noah gem. However it requires some additional "packages" to get working that I didn't want to require as part of Noah itself:

gem install eventmachine --pre
gem install em-http-request --pre
gem install em-hiredis

Those are the three packages you'll need. They only currently work on MRI. So while the server will work on JRuby, the agent will not. Once you have them installed (and the noah gem obviously), you can start the agent like so:

noah-agent

It starts in the foreground goes through the following initial steps:

  • Creates an new instance of Noah::Agent
  • Creates a new EventMachine::Channel
  • Attaches to the Redis pub/sub queue
  • Watches for any Noah messages on the queue

As messages come in they are pushed on to the EM::Channel. If any of those messages are related to watchers (creates/updates/deletes), the existing Noah::Agent object is told to recompile its watcher list. Messages are then passed to the broker method of the instance of Noah::Agent.

The broker method is currently a dumb proxy method that passes the event pattern, message and a dup of the current list of registered agents.

Each agent does the following:

  • All registered watchers are matched against the message pattern and a final notification list is built.
  • The notification list is iterated via EM::Iterator (hence the need for pre-release EventMachine) and does work against the pattern.

Tapping into the Redis stream

If you're using Ruby, this is a fairly painless process. You'll still need the em-hiredis gem installed but you're given some leeway in how you process those messages.

In the examples directory of the Noah source you'll find a few sample implementations. There's a small DSL for creating new custom watches. For instance if you simply wanted to log everything that came across the stream:

#!/usr/bin/env ruby
require 'noah/custom_watcher'
require 'logger'

class LoggingWatcher < Noah::CustomWatcher
  redis_host "redis://127.0.0.1:6379/0"
  pattern "//noah/application"
  destination Proc.new {|x| log = Logger.new(STDOUT); log.debug(x)}
  run!
end

The above would attach to redis on localhost and watch for messages against the defined pattern. When a match occurs, the Proc in destination would fire. The run! statement puts your local script in listening mode.

The biggest requirement here is that what you pass into destination is self-contained.

You can look in the examples directory to see other examples of the DSL, including one that will fire HTTP callbacks.

Note that the DSL is limited to one pattern+callback combination and this combination is temporal for the life of the running script