Skip to content

Commit b83e16b

Browse files
authored
Merge pull request #1 from redgeoff/initial
feat(initial)
2 parents fbaf062 + 1e7f401 commit b83e16b

File tree

9 files changed

+323
-56
lines changed

9 files changed

+323
-56
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# replicate-couchdb-cluster
22

3+
[![Circle CI](https://circleci.com/gh/redgeoff/replicate-couchdb-cluster.svg?style=svg&circle-token=29186a9bacd110b627323d86119076539d8b144e)](https://circleci.com/gh/redgeoff/replicate-couchdb-cluster)
4+
35
A fault-tolerant way to replicate an entire CouchDB cluster
46

57

circle.yml

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,40 @@
11
# Doesn't actually work!
22
# node:
3-
# version: 7.10.0
3+
# version: 8.1.4
4+
5+
# Uncomment to test with CouchDB 2
6+
machine:
7+
services:
8+
- docker
49

510
dependencies:
611
pre:
7-
- nvm install 7.10.0
8-
- nvm use 7.10.0 && npm install -g npm
12+
- nvm install 8.1.4
13+
- nvm use 8.1.4 && npm install -g npm
14+
15+
# Install CouchDB 2
16+
- docker run -d --name couchdb --restart always -p 5984:5984 -e COUCHDB_USER='admin' -e COUCHDB_PASSWORD='admin' redgeoff/couchdb
17+
# Wait for DB to be ready
18+
- sleep 15
19+
# Create system DBs
20+
- curl -X PUT http://admin:[email protected]:5984/_users
21+
- curl -X PUT http://admin:[email protected]:5984/_replicator
22+
- curl -X PUT http://admin:[email protected]:5984/_global_changes
23+
24+
# Enable CORS
25+
- nvm use 8.1.4 && npm install -g add-cors-to-couchdb
26+
- nvm use 8.1.4 && add-cors-to-couchdb http://localhost:5984 -u admin -p admin
927

1028
override:
11-
- nvm use 7.10.0 && npm install
29+
- nvm use 8.1.4 && npm install
1230

1331
test:
1432
pre:
15-
- nvm use 7.10.0 && npm run assert-beautified
16-
- nvm use 7.10.0 && npm run jshint
33+
- nvm use 8.1.4 && npm run assert-beautified
34+
- nvm use 8.1.4 && npm run jshint
1735

1836
override:
19-
- nvm use 7.10.0 && npm run node-full-test
20-
- nvm use 7.10.0 && npm run browser-test-phantomjs
21-
- nvm use 7.10.0 && npm run browser-coverage-full-test
37+
# Test on CouchDB 2
38+
- nvm use 8.1.4 && npm run node-full-test
39+
- nvm use 8.1.4 && npm run browser-test-phantomjs
40+
- nvm use 8.1.4 && npm run browser-coverage-full-test

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
]
5656
},
5757
"dependencies": {
58-
"sporks": "0.0.1"
58+
"couch-slouch": "0.0.3",
59+
"sporks": "0.0.1",
60+
"squadron": "0.0.3"
5961
}
6062
}

scripts/cluster.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
'use strict';
2+
3+
var Slouch = require('couch-slouch'),
4+
squadron = require('squadron');
5+
6+
// params
7+
// source
8+
// target
9+
// concurrency
10+
// skip
11+
var Cluster = function (params) {
12+
this._params = params;
13+
14+
this._sourceSlouch = new Slouch(params.source);
15+
this._targetSlouch = new Slouch(params.target);
16+
17+
if (this._params.concurrency === 1) {
18+
// Don't use a throttler
19+
this._throttler = undefined;
20+
} else {
21+
// Create a throttler with the specified or default concurrency
22+
var concurrency = this._params.concurrency ? this._params.concurrency : null;
23+
this._throttler = new squadron.Throttler(concurrency);
24+
}
25+
};
26+
27+
Cluster.prototype.replicate = function () {
28+
var self = this;
29+
return self._sourceSlouch.db.all().each(function (db) {
30+
if (!self._params.skip || self._params.skip.indexOf(db) === -1) {
31+
return self._replicateDB(db, db);
32+
}
33+
}, self._throttler);
34+
};
35+
36+
Cluster.prototype._createDBIfMissing = function (db) {
37+
var self = this;
38+
return self._targetSlouch.db.exists(db).then(function (exists) {
39+
if (!exists) {
40+
return self._targetSlouch.db.create(db);
41+
}
42+
});
43+
};
44+
45+
Cluster.prototype._replicateSecurity = function (sourceDB, targetDB) {
46+
var self = this;
47+
return self._sourceSlouch.security.get(sourceDB).then(function (security) {
48+
return self._targetSlouch.security.set(targetDB, security);
49+
});
50+
};
51+
52+
Cluster.prototype._replicateRawDB = function (sourceDB, targetDB) {
53+
return this._sourceSlouch.db.replicate({
54+
source: this._params.source + '/' + sourceDB,
55+
target: this._params.target + '/' + targetDB
56+
});
57+
};
58+
59+
Cluster.prototype._replicateDB = function (sourceDB, targetDB) {
60+
var self = this;
61+
return self._createDBIfMissing(targetDB).then(function () {
62+
// Replicate security first so that security is put in place before data is copied over
63+
return self._replicateSecurity(sourceDB, targetDB);
64+
}).then(function () {
65+
return self._replicateRawDB(sourceDB, targetDB);
66+
});
67+
};
68+
69+
module.exports = Cluster;

scripts/foo.js

Lines changed: 0 additions & 13 deletions
This file was deleted.

scripts/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
3+
module.exports = require('./cluster');

test/browser.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,4 @@ var chai = require('chai');
44
chai.use(require('chai-as-promised'));
55
chai.should();
66

7-
var Foo = require('../scripts/foo');
8-
97
require('./node-and-browser');
10-
11-
describe('browser', function () {
12-
13-
it('should test in only the browser', function () {
14-
// TODO: insert tests that can only be tested in the browser
15-
var foo = new Foo();
16-
return foo.bar().then(function (thing) {
17-
thing.should.eql('yar');
18-
});
19-
});
20-
21-
});

0 commit comments

Comments
 (0)