fix: prevent adding listeners past limit

Co-authored-by: Dominique Emond <dremond@ca.ibm.com>
This commit is contained in:
Dominique Emond 2019-08-01 16:32:39 -04:00 committed by Nora
parent 183d2a31de
commit 7ab10fb8fb
3 changed files with 53 additions and 4 deletions

View File

@ -623,9 +623,22 @@ SQLConnector.prototype.execute = function(sql, params, options, callback) {
const self = this; const self = this;
if (!this.dataSource.connected) { if (!this.dataSource.connected) {
// Prevent adding too many listeners to the 'connected' event on the datasource.
if (this.dataSource.listenerCount('connected') <
this.dataSource.getMaxOfflineRequests()) {
// allow this listener to be added to this event
return this.dataSource.once('connected', function() { return this.dataSource.once('connected', function() {
self.execute(sql, params, options, callback); self.execute(sql, params, options, callback);
}); });
} else {
const limitReachedError = new Error(
g.f(
'Event listener limit reached. ' +
'Increase maxOfflineRequests value in datasources.json.',
),
);
callback(limitReachedError);
}
} }
const context = { const context = {
req: { req: {

View File

@ -36,7 +36,7 @@
"chai-as-promised": "^7.1.1", "chai-as-promised": "^7.1.1",
"eslint": "^6.1.0", "eslint": "^6.1.0",
"eslint-config-loopback": "^13.1.0", "eslint-config-loopback": "^13.1.0",
"loopback-datasource-juggler": "^3.12.0", "loopback-datasource-juggler": "^3.32.0",
"mocha": "^6.2.0" "mocha": "^6.2.0"
} }
} }

View File

@ -459,4 +459,40 @@ describe('sql connector', function() {
done(err, results); done(err, results);
}); });
}); });
it('should throw if the event listener limit is reached', function() {
ds.connected = false;
function runExecute() {
return connector.execute('SELECT * FROM `CUSTOMER`', function(err) {
throw err;
});
}
for (let i = 0; i < 16; i++) {
runExecute();
}
expect(function() { runExecute(); }).to.throw(
'Event listener limit reached. ' +
'Increase maxOfflineRequests value in datasources.json.',
);
ds.connected = true;
ds.removeAllListeners(['connected']);
});
it('should not throw if the event listener limit is not reached', function() {
ds.connected = false;
function runExecute() {
return connector.execute('SELECT * FROM `CUSTOMER`', function(err) {
throw err;
});
}
for (let i = 0; i < 15; i++) {
runExecute();
}
expect(function() { runExecute(); }).to.not.throw();
ds.connected = true;
});
}); });