Skip to content

Commit

Permalink
Allow milestone snapshot saving logic to be overridden in the middleware
Browse files Browse the repository at this point in the history
This change adds a flag to `SubmitRequest`: `saveMilestoneSnapshot`.
This flag defaults to `null`. If this value is left as `null`, then
milestone snapshots will be written according to the interval set in the
options passed into the provided `MilestoneDB` instance.

The value can be overridden in middleware, like in the test case in this
commit. If the value of `request.saveMilestoneSnapshot` is changed to
a `boolean`, then all interval logic is ignored, and the value of that
flag is used directly to determine if a milestone should be saved.

This allows more complex milestone logic, such as:

  - saving a milestone once per day
  - different intervals depending on collection
  - non-uniform milestone intervals
  • Loading branch information
Alec Gibson committed Aug 16, 2018
1 parent f828ed9 commit 55ed07a
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 2 deletions.
13 changes: 11 additions & 2 deletions lib/submit-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ function SubmitRequest(backend, agent, index, id, op, options) {
// For custom use in middleware
this.custom = {};

// Whether or not to store a milestone snapshot. If left as null, the milestone
// snapshots are saved according to the interval provided to the milestone db
// options. If overridden to a boolean value, then that value is used instead of
// the interval logic.
this.saveMilestoneSnapshot = null;
this.suppressPublish = backend.suppressPublish;
this.maxRetries = backend.maxSubmitRetries;
this.retries = 0;
Expand Down Expand Up @@ -220,8 +225,12 @@ SubmitRequest.prototype._addSnapshotMeta = function() {
};

SubmitRequest.prototype._shouldSaveMilestoneSnapshot = function (snapshot) {
return snapshot
&& snapshot.v % this.backend.milestoneDb.interval === 0;
// If the flag is null, it's not been overridden by the consumer, so apply the interval
if (this.saveMilestoneSnapshot === null) {
return snapshot && snapshot.v % this.backend.milestoneDb.interval === 0;
}

return this.saveMilestoneSnapshot;
};

// Non-fatal client errors:
Expand Down
60 changes: 60 additions & 0 deletions test/milestone-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,66 @@ module.exports = function (options) {
}
]);
});

it('can have the saving logic overridden in middleware', function (done) {
backend.use('commit', function (request, callback) {
request.saveMilestoneSnapshot = request.snapshot.v >= 3;
callback();
});

db.on('save', function (saved, collection, snapshot) {
if (snapshot.v !== 4) return;

util.callInSeries([
function (next) {
db.getMilestoneSnapshot('books', 'catcher-in-the-rye', 1, next);
},
function (snapshot, next) {
expect(snapshot).to.be(undefined);
next();
},
function (next) {
db.getMilestoneSnapshot('books', 'catcher-in-the-rye', 2, next);
},
function (snapshot, next) {
expect(snapshot).to.be(undefined);
next();
},
function (next) {
db.getMilestoneSnapshot('books', 'catcher-in-the-rye', 3, next);
},
function (snapshot, next) {
expect(snapshot.v).to.be(3);
next();
},
function (next) {
db.getMilestoneSnapshot('books', 'catcher-in-the-rye', 4, next);
},
function (snapshot, next) {
expect(snapshot.v).to.be(4);
next();
},
done
]);
});

var doc = backend.connect().get('books', 'catcher-in-the-rye');

util.callInSeries([
function (next) {
doc.create({ title: 'Catcher in the Rye' }, next);
},
function (next) {
doc.submitOp({ p: ['author'], oi: 'J.F.Salinger' }, next);
},
function (next) {
doc.submitOp({ p: ['author'], od: 'J.F.Salinger', oi: 'J.D.Salinger' }, next);
},
function (next) {
doc.submitOp({ p: ['author'], od: 'J.D.Salinger', oi: 'J.D. Salinger' }, next);
}
]);
});
});
});
};

0 comments on commit 55ed07a

Please sign in to comment.