Picking up from last night's failure to get node.js playing nicely with CouchDB replication, I start by trying it from the command line. The failure stemmed from the use of the
create_target
attribute, which should create a new database if it does not already exist. With curl
, I find:cstrom@whitefall:~$ curl -X POST http://localhost:5984/_replicate \Ah good to know. It is not a problem with node.js. Something in my understanding of the
> -d '{"source":"seed", "target":"http://couch-011a.local:5984/seed", "create_target":true}'
{"error":"db_not_found","reason":"could not open http://couch-011a.local:5984/seed/"}
create_target
attribute is amiss.Switching the source and target does, however, work:
cstrom@whitefall:~$ curl -X POST http://couch-011a.local:5984/_replicate \ > -d '{"source":"http://whitefall.local:5984/seed", "target":"seed", "create_target":true}'Interesting. I learn a couple of things from this result. The first is that I need create another seed DB. It is silly to replicate 678 documents for a test.
{"ok":true,"session_id":"cb968554905b1527e6fab6eaa0c6f754","source_last_seq":743,"history":[{"session_id":"cb968554905b1527e6fab6eaa0c6f754","start_time":"Fri, 26 Mar 2010 21:40:59 GMT","end_time":"Fri, 26 Mar 2010 21:47:15 GMT","start_last_seq":0,"end_last_seq":743,"recorded_seq":743,"missing_checked":0,"missing_found":675,"docs_read":678,"docs_written":678,"doc_write_failures":0}]}
More importantly, I figured out how the
create_target
option works. Specifically, it only works when the target database resides on the server being POSTed to, though the wiki seems to imply otherwise. Speaking of the wiki, while reading it, I found that a local target is preferred. I have been doing local source / remote target. That means that I need to update couch-replicate, but first, I want to see last night's node.js replication script through.I delete the incredibly large seed databases:
cstrom@whitefall:~$ curl -X DELETE http://couch-011a.local:5984/seedUsing the couch_docs gem, I create a smaller seed DB:
{"ok":true}
cstrom@whitefall:~$ curl -X DELETE http://localhost:5984/seed
{"ok":true}
cstrom@whitefall:~/tmp/seed$ lsMy simple goal is to replicate a database from my localhost (whitefall.local) machine onto CouchDB VM A, and the from A to B, and B to C. At the end, the seed database, which did not exist on VM C at the start should contain the newly created and replicated DB. The node.js script, now using local targets, becomes:
2002-08-26-grilled_chicken.json 2002-08-26.json 2002-08-26-pasta.json 2002-08-26-pesto.json _design
cstrom@whitefall:~/tmp/seed$ couch-docs push http://localhost:5984/seed -R
Updating documents on CouchDB Server...
varNow when I run the script I find... that the database still is not replicated to C:
sys = require('sys'),
couchdb = require('node-couchdb/lib/couchdb'),
client = couchdb.createClient(5984, 'whitefall.local'),
clienta = couchdb.createClient(5984, 'couch-011a.local'),
clientb = couchdb.createClient(5984, 'couch-011b.local'),
clientc = couchdb.createClient(5984, 'couch-011c.local');
client.allDbs(function (er, data) {
sys.puts("DBs on localhost: " + data);
});
clientc.allDbs(function (er, data) {
sys.puts("DBs on C before replication: " + data);
});
clienta.replicate("http://whitefall.local:5984/seed", "seed", {create_target:true});
clientb.replicate("http://couch-011a.local:5984/seed", "seed", {create_target:true});
clientc.replicate("http://couch-011b.local:5984/seed", "seed", {create_target:true});
clientc.allDbs(function (er, data) {
sys.puts("DBs on C after replication: " + data);
});
cstrom@whitefall:~$ ./local/bin/node ./tmp/node-couch.jsGah!
DBs on localhost: eee,test,seed
DBs on C before replication: test
DBs on C after replication: test
The explanation for this failure turns out to be simple enough. Checking the log in server B, I find:
[Fri, 26 Mar 2010 22:53:18 GMT] [error] [<0.222.0>] {error_report,<0.31.0>,But checking server A, I see that the
{<0.222.0>,crash_report,
[[{initial_call,{couch_rep,init,['Argument__1']}},
{pid,<0.222.0>},
{registered_name,[]},
{error_info,
{exit,
{db_not_found,<<"http://couch-011a.local:5984/seed/">>},
[{gen_server,init_it,6},{proc_lib,init_p_do_apply,3}]}},
seed
database is there:My guess is that server A has not had time to finished creating / replicating the seed database before server B tries to replicate it. To verify, I add some timeouts to my node.js script:
clienta.replicate("http://whitefall.local:5984/seed", "seed", {create_target:true});Indeed, server C now contains the
setTimeout(function () {
clientb.replicate("http://couch-011a.local:5984/seed", "seed", {create_target:true});
}, 2000);
setTimeout(function () {
clientc.replicate("http://couch-011b.local:5984/seed", "seed", {create_target:true});
}, 4000);
setTimeout(function () {
clientc.allDbs(function (er, data) {
sys.puts("DBs on C after replication: " + data);
});
}, 6000);
seed
database:cstrom@whitefall:~$ ./local/bin/node ./tmp/node-couch.jsThis is clearly a contrived example. Were I to even try this for real in node.js, I would not be using timeouts, which would certainly fail for large databases. Still, I feel like I made progress—I figured out why last night's script failed and learned a thing or two about CouchDB replication.
DBs on localhost: eee,test,seed
DBs on C before replication: test
DBs on C after replication: seed,test
Day #54
No comments:
Post a Comment