Update notifications sent by a database allow me to react to changes submitted to it in almost real-time without having to continuously (or periodically) poll said database. Note, that update notifications are not the same thing as database triggers as known in the relational database world: update notifications are submitted after a database modification has occurred – there is no way to avoid the update. These notifications are typically consumed by an external process which then somehow reacts to the update. CouchDB has support for two types of update notifications (of which I’m aware):
- Update notifications powered by an external process, and
- Change notifications using the changes API.
This process receives a JSON string as a notification which includes the name of the database that was just modified.
For example, whenever my twitter database changes, the
couchjp program receives the following line on stdin:
Your program could then retrieve the database name and go and look for what has changed. Or for example, the program could automatically launch replication, if you don’t want to use
continuous_replication as exists in CouchDB 0.11.
CouchDB has the so-called _changes database-API which your application can use to get Comet-style notification of changes, be it by your application polling the database to query if anything has changed since a particular time or by CouchDB providing your application with a continuous stream of changes. I’m not going to delve into this API much, because it is very well documented in the book CouchDB: The Definitive Guide. In essence, you use an HTTP GET request to pull in a list of changed documents.
You’ll have to install node.js, but doing so is easy. Once you have that running, come back and continue here.
Mikeal Rogers created what he calls a generic change consumer that you can point at a running CouchDB instance. This change consumer, written in node.js periodically checks all CouchDB databases for existence of a
changes field in the design documents of databases. If such a
changes field is found, it must contain valid node.js code, which is pulled in by the consumer and executed on the machine running
What this means, is that once you have a consumer running, you can use Futon or CouchApp to create and modify code which is stored in your database design document, and that code is automatically read by the consumer and is triggerred by any PUT, POST or DELETE to documents in your database.
To follow what I’m doing here, you’ll need a few things:
- A running instance of CouchDB of course.
- A copy of node.couch.js. Actually, we need only the two files in
- A CouchDB database you can play with, and a design document, named whatever you like.
So, what happens when I launch that program? node is executed and loads the required modules. The principal module is service, which then
- Reads a list of all databases at the specified URI.
changesfield contains an error,
nodewill bail out and stop.
service.jssets up an event to rescan CouchDB databases and design documents every 60 seconds.
Let me create a first design document called
I’ll now start
node on another window, and keep an eye on that, while we continue working here.
I’m now going to add a document to my database.
The first line with the JSON string is printed by the
Hey: Jane) is printed by the second
Shall I delete that document? Ok, here goes:
node program displays
Take particular note of the
_deleted field, which allows me to differenciate whether I’m handling a real update or whether I should perhaps ignore this update notification as it is a deletion.
Taking this a step further, let’s see if we can actually do something with the updates.
Suppose I have a database into which messages (i.e. documents) are posted that may have a particular priority. I want to ensure that documents tagged with an “urgent” priority are notified to my Twitter account as soon as they are added to CouchDB.
I don’t have to restart couchlisten.js, as it will pick up the modified design document momentarily.
Let me show you what the result looks like in the following screen cast, which consists of three windows:
- The top window is where I'll be submitting requests to CouchDB, using resty.
- The window in the center shows the output of our local node.js program, which I've called
- In the bottom window, I have a small
node.jsprogram based on twitter-node. This program "follows" the Twitter user who is submitting the "urgent" Tweets.
And the result is quite pleasing:
- I can use these update notifications to tally how many updates to a database have occurred, and then, initiate a backup to a remote site. (One that doesn't have CouchDB -- I'd otherwise use replication for that, wouldn't I? :-) )
- If I use CouchDB as a writing platform, I can post via XML-RPC to my WordPress, Blogger, MT, etc. blog as soon as a document changes.
- If I think "DNS" database, with a solution like my <a href=/2010/05/05/powerdns-and-a-couchdb-backend/">CouchDB pipe back-end to PowerDNS</a>, I can use an update notification to send an alert e-mail to the domain's hostmaster, so that (s)he can verify the zone.