Skip to content
This repository has been archived by the owner on Feb 4, 2022. It is now read-only.

Commit

Permalink
fix(replset): only remove primary if primary is there
Browse files Browse the repository at this point in the history
Fixes NODE-1393
  • Loading branch information
daprahamian committed Mar 29, 2018
1 parent 2d5dde3 commit 1acd288
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 13 deletions.
4 changes: 3 additions & 1 deletion lib/topologies/replset.js
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,9 @@ function executeWriteOperation(args, options, callback) {
}

// Per SDAM, remove primary from replicaset
self.s.replicaSetState.remove(self.s.replicaSetState.primary, { force: true });
if (self.s.replicaSetState.primary) {
self.s.replicaSetState.remove(self.s.replicaSetState.primary, { force: true });
}

return callback(err);
};
Expand Down
73 changes: 61 additions & 12 deletions test/tests/unit/replset/step_down_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const ReplSet = require('../../../../lib/topologies/replset');
const mock = require('mongodb-mock-server');
const ReplSetFixture = require('../common').ReplSetFixture;

describe('Step Down (ReplSet)', function() {
describe.only('Step Down (ReplSet)', function() {
class MyFixture extends ReplSetFixture {
constructor() {
super();
Expand Down Expand Up @@ -81,27 +81,28 @@ describe('Step Down (ReplSet)', function() {
}

let test;
before(() => (test = new MyFixture()));
beforeEach(() => (test = new MyFixture()));
afterEach(() => mock.cleanup());
beforeEach(() => test.setup());

function makeReplicaSet() {
return new ReplSet([test.primaryServer.address(), test.firstSecondaryServer.address()], {
setName: 'rs',
connectionTimeout: 3000,
socketTimeout: 0,
haInterval: 100,
size: 1
});
}

it('Should only issue a "not master" error once', {
metadata: {
requires: {
topology: 'single'
}
},
test: function(done) {
const replSet = new ReplSet(
[test.primaryServer.address(), test.firstSecondaryServer.address()],
{
setName: 'rs',
connectionTimeout: 3000,
socketTimeout: 0,
haInterval: 100,
size: 1
}
);
const replSet = makeReplicaSet();

replSet.on('error', done);
replSet.on('connect', () => {
Expand Down Expand Up @@ -164,4 +165,52 @@ describe('Step Down (ReplSet)', function() {
replSet.connect();
}
});

it('Should only attempt to remove primary once', {
metadata: {
requires: {
topology: 'single'
}
},
test: function(done) {
const replSet = makeReplicaSet();

replSet.on('error', done);
replSet.on('connect', () => {
const cleanupAndDone = e => {
replSet.destroy();
done(e);
};

test.nextState();

let counter = 2;

function handler(err, result) {
counter -= 1;
try {
expect(err).to.exist;
expect(err.message).to.match(/not master/);
expect(result).to.not.exist;
} catch (e) {
return cleanupAndDone(e);
}

if (counter <= 0) {
cleanupAndDone();
}
}

// Should issue a "not master", since primary has stepped down
// This one will attempt to remove the primary
replSet.insert('foo.bar', [{ b: 2 }], handler);

// Should issue a "not master", since primary has stepped down
// This one will not attempt to remove the primary, as it has
// already been removed
replSet.insert('foo.bar', [{ c: 3 }], handler);
});
replSet.connect();
}
});
});

0 comments on commit 1acd288

Please sign in to comment.