mirror of
https://github.com/donl/slouch.git
synced 2026-05-25 22:07:24 -06:00
feat(persist-through-conflicts): use exponential backoff
This commit is contained in:
parent
87587338cf
commit
25b4bc1fdb
2 changed files with 26 additions and 18 deletions
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
var promisedRequest = require('./request'),
|
||||
CouchPersistentStreamIterator = require('./couch-persistent-stream-iterator'),
|
||||
sporks = require('sporks');
|
||||
sporks = require('sporks'),
|
||||
Backoff = require('backoff-promise');
|
||||
|
||||
var Doc = function (slouch) {
|
||||
this._slouch = slouch;
|
||||
|
|
@ -159,27 +160,33 @@ Doc.prototype.createOrUpdateIgnoreConflict = function (dbName, doc) {
|
|||
});
|
||||
};
|
||||
|
||||
// Provide a construct for mocking
|
||||
Doc.prototype._newBackoff = function () {
|
||||
return new Backoff();
|
||||
};
|
||||
|
||||
Doc.prototype._persistThroughConflicts = function (promiseFactory) {
|
||||
|
||||
var self = this,
|
||||
i = 0;
|
||||
|
||||
// Use an exponential backoff to prevent multiple ticks from competing with each other and
|
||||
// resulting in none of the ticks persisting through the conflict within the allotted number of
|
||||
// retries.
|
||||
var backoff = self._newBackoff();
|
||||
|
||||
var run = function () {
|
||||
|
||||
return promiseFactory().catch(function (err) {
|
||||
|
||||
if (err.error === 'conflict' && i++ < self.maxRetries) { // conflict?
|
||||
|
||||
// Retry
|
||||
return backoff.attempt(function () {
|
||||
return promiseFactory();
|
||||
}).catch(function (err) {
|
||||
// Conflict and haven't reached max retries?
|
||||
if (err.error === 'conflict' && i++ < self.maxRetries) {
|
||||
// Attempt again
|
||||
return run();
|
||||
|
||||
} else {
|
||||
|
||||
// Unexpected error
|
||||
throw err;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ var Slouch = require('../../scripts'),
|
|||
utils = require('../utils'),
|
||||
sporks = require('sporks'),
|
||||
Promise = require('sporks/scripts/promise'),
|
||||
config = require('../config.json');
|
||||
config = require('../config.json'),
|
||||
Backoff = require('backoff-promise');
|
||||
|
||||
describe('doc', function () {
|
||||
|
||||
|
|
@ -19,6 +20,12 @@ describe('doc', function () {
|
|||
slouch = new Slouch(utils.couchDBURL());
|
||||
db = slouch.db;
|
||||
updates = [];
|
||||
|
||||
// Shorten backoff
|
||||
slouch.doc._newBackoff = function () {
|
||||
return new Backoff(1);
|
||||
};
|
||||
|
||||
return utils.createDB();
|
||||
});
|
||||
|
||||
|
|
@ -265,8 +272,6 @@ describe('doc', function () {
|
|||
});
|
||||
|
||||
it('upsert should fail after max retries', function () {
|
||||
slouch.maxRetries = 3;
|
||||
|
||||
// Disable for conflict faking
|
||||
slouch.doc.ignoreDuplicateUpdates = false;
|
||||
|
||||
|
|
@ -347,8 +352,6 @@ describe('doc', function () {
|
|||
});
|
||||
|
||||
it('get, merge and upsert should fail after max retries', function () {
|
||||
slouch.maxRetries = 3;
|
||||
|
||||
// Disable for conflict faking
|
||||
slouch.doc.ignoreDuplicateUpdates = false;
|
||||
|
||||
|
|
@ -382,8 +385,6 @@ describe('doc', function () {
|
|||
});
|
||||
|
||||
it('get, modify and upsert should fail after max retries', function () {
|
||||
slouch.maxRetries = 3;
|
||||
|
||||
return fakeConflict().then(function () {
|
||||
return sporks.shouldThrow(function () {
|
||||
return slouch.doc.getModifyUpsert(utils.createdDB, '1', function (doc) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue