Skip to content

Commit

Permalink
fix: prevent parallel monitor checks
Browse files Browse the repository at this point in the history
  • Loading branch information
baileympearson committed Oct 3, 2022
1 parent cdce4bf commit 0ace76c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 24 deletions.
4 changes: 4 additions & 0 deletions src/sdam/monitor.ts
Expand Up @@ -328,6 +328,10 @@ function checkServer(monitor: Monitor, callback: Callback<Document | null>) {

function monitorServer(monitor: Monitor) {
return (callback: Callback) => {
if (monitor.s.state === STATE_MONITORING) {
callback();
return;
}
stateTransition(monitor, STATE_MONITORING);
function done() {
if (!isInCloseState(monitor)) {
Expand Down
Expand Up @@ -25,8 +25,8 @@ describe('SDAM Unified Tests', function () {
// TODO(NODE-4573): fix socket leaks
const LEAKY_TESTS = [
'Command error on Monitor handshake',
'Network error on Monitor check',
'Network timeout on Monitor check',
// 'Network error on Monitor check',
// 'Network timeout on Monitor check',
'Network error on Monitor handshake',
'Network timeout on Monitor handshake'
];
Expand Down
74 changes: 52 additions & 22 deletions test/unit/sdam/monitor.test.ts
Expand Up @@ -400,41 +400,71 @@ describe('monitoring', function () {
});
});

context('when it has been < minHeartbeatFrequencyMS since fn() last completed', function () {
context(
'when it has been < minHeartbeatFrequencyMS and >= 0 since fn() last completed',
function () {
beforeEach(function () {
executor = new MonitorInterval(fnSpy, {
minHeartbeatFrequencyMS: 10,
heartbeatFrequencyMS: 30
});

// call fn() once
clock.tick(30);
expect(fnSpy.calledOnce).to.be.true;

fnSpy.callCount = 0;

// advance less than minHeartbeatFrequency
clock.tick(5);

executor.wake();
});

it('reschedules fn() to minHeartbeatFrequencyMS after the last call', function () {
expect(fnSpy.callCount).to.equal(0);
clock.tick(5);
expect(fnSpy.calledOnce).to.be.true;
});

context('when wake() is called more than once', function () {
it('schedules fn() minHeartbeatFrequencyMS after the last call to fn()', function () {
executor.wake();
executor.wake();
executor.wake();

expect(fnSpy.callCount).to.equal(0);
clock.tick(5);
expect(fnSpy.calledOnce).to.be.true;
});
});
}
);

context('when it has been <0 since fn() has last executed', function () {
beforeEach(function () {
executor = new MonitorInterval(fnSpy, {
minHeartbeatFrequencyMS: 10,
heartbeatFrequencyMS: 30
});

// call fn() once
clock.tick(30);
expect(fnSpy.calledOnce).to.be.true;

fnSpy.callCount = 0;

// advance less than minHeartbeatFrequency
clock.tick(5);

// negative ticks aren't supported, so manually set execution time
executor.lastExecutionEnded = Infinity;
executor.wake();
});

it('reschedules fn() to minHeartbeatFrequencyMS after the last call', function () {
expect(fnSpy.callCount).to.equal(0);
clock.tick(5);
it('executes fn() immediately', function () {
expect(fnSpy.calledOnce).to.be.true;
});

context('when wake() is called more than once', function () {
it('schedules fn() minHeartbeatFrequencyMS after the last call to fn()', function () {
executor.wake();
executor.wake();
executor.wake();
it('reschedules fn() to minHeartbeatFrequency away', function () {
fnSpy.callCount = 0;

expect(fnSpy.callCount).to.equal(0);
clock.tick(5);
expect(fnSpy.calledOnce).to.be.true;
});
clock.tick(29);
expect(fnSpy.callCount).to.equal(0);

clock.tick(1);
expect(fnSpy.calledOnce).to.be.true;
});
});
});
Expand Down

0 comments on commit 0ace76c

Please sign in to comment.