Thursday, April 1, 2010

Node.Couch.Js

‹prev | My Chain | next›

Even after over a year of working with CouchDB regularly, I still find that I have fundamental misunderstandings. For the most part, I can accept those because that is why I do the chain—I learn to overcome those gaps. What I dislike is simply not knowing certain features, which is what I have done with the changes API.

To explore that (and a bit more node.js at the same time), I will have a look at node.couch.js. This is an interesting little server that defines node.js callbacks in CouchDB design documents.

It seems like I can create any design document with a changes attribute to collect changes. I'm not sure if there needs to be a map associated or not. I will try it without to start.

So I start a couch_docs watcher to define such a beasty:
cstrom@whitefall:~/tmp/seed$ couch-docs push http://localhost:5984/seed -w
Updating documents on CouchDB Server...
In that seed directory, I create a _design/test/changes.js file with the following content:
var sys = require('sys');
var listener = function (change) {
sys.puts(JSON.stringify(change));
}
exports.listener = listener;
This is taken directly from the README for node.couch.js and should create a node.js callback that will simply print out the change. If I did this right. And I understand it.

After saving the file, couch_docs picks up the change and loads it into my seed database:
cstrom@whitefall:~/tmp/seed$ couch-docs push http://localhost:5984/seed -w
Updating documents on CouchDB Server...
Updating documents on CouchDB Server...
This creates a document on the server:



Nice. So now I should be able to run the node.couch.js node.js script to watch for changes:
cstrom@whitefall:~/repos/node.couch.js/changes$ ~/local/bin/node lib/service.js http://localhost:5984
Error: The 'posix' module has been renamed to 'fs'
at Object.<anonymous> (posix:1:69)
at Module._compile (node.js:721:23)
at loadNative (node.js:84:13)
at loadModule (node.js:554:22)
at require (node.js:700:12)
at Object.<anonymous> (/home/cstrom/repos/node.couch.js/changes/lib/service.js:6:13)
at Module._compile (node.js:721:23)
at node.js:749:20
at fs:51:23
at node.js:810:9
Hrm. That seems an easy enough fix. I change the posix definition to use fs:
var listener = require('./listener'),
url = require('url'),
events = require('events'),
sys = require('sys'),
path = require('path'),
posix = require('fs'),
http = require('http');
I leave the namespace/module named posix in case anything is referencing it (though I am not even certain this is how node.js works). Now, when I run the script, I find:
cstrom@whitefall:~/repos/node.couch.js/changes$ ~/local/bin/node lib/service.js http://localhost:5984
Error: Promise has been removed. See http://groups.google.com/group/nodejs/msg/0c483b891c56fea2 for more information.
at new <anonymous> (node.js:11:11)
at /home/cstrom/repos/node.couch.js/changes/lib/service.js:29:11
at /home/cstrom/repos/node.couch.js/changes/lib/service.js:175:37
at Object.<anonymous> (/home/cstrom/repos/node.couch.js/changes/lib/service.js:186:3)
at Module._compile (node.js:721:23)
at node.js:749:20
at fs:51:23
at node.js:810:9
Ew. I check the link in the backtrace and it says that "promises" were removed in 0.1.30. Sure enough I am running 0.1.33:
cstrom@whitefall:~/repos/node.couch.js/changes$ ~/local/bin/node --version
0.1.33
I try commenting out code in the hope that this is not needed, but do not get much further so maybe I can futz this...

The alldbs method returns a "promise" whose addCallback method is called:
              alldbs(couchdbUrl.port, couchdbUrl.hostname, pathname).addCallback(function(dbs) {
// do db stuff
})
Will this work if I build a dumb Javascript object with an addCallback method? For now, I will not add anything to the callback, I just want to see if this will work:
var alldbs = function (port, hostname, pathname) {
//var p = new events.Promise();
var p = {};

var client = http.createClient(port, hostname);
var request = client.request('GET', pathname + '_all_dbs', {'accept':'application/json'});
request.finish(function(response){
var buffer = '';
response.addListener("body", function(data){buffer += data});
response.addListener("complete", function(){
dbs = JSON.parse(buffer);
p['addCallback'] = function (callback) {
// call the callback
}

//p.emitSuccess(dbs);
})
})
return p
}
Sadly, when I run the script now, I find:
cstrom@whitefall:~/repos/node.couch.js/changes$ ~/local/bin/node lib/service.js http://localhost:5984
Error: finish() has been renamed to close() and no longer takes a response handler as an argument. Manually add a 'response' listener to the request object.
at ClientRequest.finish (http:317:9)
at /home/cstrom/repos/node.couch.js/changes/lib/service.js:33:11
at /home/cstrom/repos/node.couch.js/changes/lib/service.js:179:37
at Object. (/home/cstrom/repos/node.couch.js/changes/lib/service.js:190:3)
at Module._compile (node.js:721:23)
at node.js:749:20
at fs:51:23
at node.js:810:9
Man! A lot sure seems to have changed recently in node.js.

I think it best to call it a night at this point. I have used up 3 pomodoros (actually blew through the end time of my last one trying to get this working). I will ruminate on what I have learned and start fresh tomorrow. I do think I will give fixing this a go—seems like a great way to learn this stuff a bit better.

Day #60

1 comment:

  1. yeah, node.couch.js is do for an update. It's been over a month and that's like a decade in the node.js world :)

    ReplyDelete