From f1989ce6361193f1e213cb0b17e7dab4f2a8451c Mon Sep 17 00:00:00 2001 From: Gareth Bowen Date: Fri, 13 May 2016 20:56:20 +1200 Subject: [PATCH] (#5145) - Update checkpoint even when no changes * (#5145) - Update checkpoint even when no changes * (#5145) - Fix eslint * (#5146) - Test requested parameter, couchdb 2 compatibility * (#5145) - Tidy up test to be more promisey --- src/replicate/replicate.js | 34 +++++++++++++------ tests/integration/test.replication.js | 49 +++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/src/replicate/replicate.js b/src/replicate/replicate.js index a1a84d9854..62426736c1 100644 --- a/src/replicate/replicate.js +++ b/src/replicate/replicate.js @@ -121,11 +121,7 @@ function replicate(src, target, opts, returnValue, result) { } currentBatch = undefined; getChanges(); - }).catch(function (err) { - writingCheckpoint = false; - abortReplication('writeCheckpoint completed with error', err); - throw err; - }); + }).catch(onCheckpointError); } function getDiffs() { @@ -294,15 +290,33 @@ function replicate(src, target, opts, returnValue, result) { if (changes.results.length > 0) { changesOpts.since = changes.last_seq; getChanges(); + processPendingBatch(true); } else { - if (continuous) { - changesOpts.live = true; - getChanges(); + + var complete = function () { + if (continuous) { + changesOpts.live = true; + getChanges(); + } else { + changesCompleted = true; + } + processPendingBatch(true); + }; + + // update the checkpoint so we start from the right seq next time + if (!currentBatch && changes.last_seq > last_seq) { + writingCheckpoint = true; + checkpointer.writeCheckpoint(changes.last_seq, + session).then(function () { + writingCheckpoint = false; + result.last_seq = last_seq = changes.last_seq; + complete(); + }) + .catch(onCheckpointError); } else { - changesCompleted = true; + complete(); } } - processPendingBatch(true); } diff --git a/tests/integration/test.replication.js b/tests/integration/test.replication.js index 37d5cf4fc5..358453dcd8 100644 --- a/tests/integration/test.replication.js +++ b/tests/integration/test.replication.js @@ -1548,6 +1548,55 @@ adapters.forEach(function (adapters) { }); }); + it('Empty replication updates checkpoint (#5145)', function () { + var db = new PouchDB(dbs.name); + var remote = new PouchDB(dbs.remote); + var changes = remote.changes; + remote.changes = function (params) { + changesSince.push(params.since); + return changes.apply(this, arguments); + }; + var changesSince = []; + var replicationOpts = { + filter: function () { + return false; + } + }; + return remote.bulkDocs({ docs: docs }).then(function () { + return db.replicate.from(remote, replicationOpts); + }).then(function (result) { + result.ok.should.equal(true); + result.docs_written.should.equal(0); + result.docs_read.should.equal(0); + changesSince.length.should.equal(2); + // the returned last_seq should match the 'since' + // requested from remote + result.last_seq.should.equal(changesSince[1]); + // the 'since' parameter should be different on the + // next request + changesSince[0].should.not.equal(changesSince[1]); + // kick off a second replication + return db.replicate.from(remote, replicationOpts); + }).then(function (result) { + result.ok.should.equal(true); + result.docs_written.should.equal(0); + result.docs_read.should.equal(0); + changesSince.length.should.equal(3); + // the returned last_seq should match the 'since' + // requested from remote + result.last_seq.should.equal(changesSince[2]); + // nothing has changed on the remote so 'since' + // should be the same + changesSince[1].should.equal(changesSince[2]); + }).then(function () { + // Restore remote.changes to original + remote.changes = changes; + }).catch(function (err) { + remote.changes = changes; + throw err; + }); + }); + it('Replication with deleted doc', function (done) { var db = new PouchDB(dbs.name); var remote = new PouchDB(dbs.remote);