fix: prevent max listeners warning

If establishing a database connection is slow
and database migration runs and there are many
models, sql operations are queued up and this
leads to the node.js max emitters exceeded
warning.

A default value for max emitters has now
been introduced, and it can also be configured
in datasources.json.

Co-authored-by: Dominique Emond <dremond@ca.ibm.com>
This commit is contained in:
Nora 2019-08-12 18:34:04 -04:00
parent 6fb745cdd4
commit f6117c2c47
2 changed files with 52 additions and 0 deletions

View File

@ -187,6 +187,11 @@ util.inherits(DataSource, EventEmitter);
// allow child classes to supply a data access object // allow child classes to supply a data access object
DataSource.DataAccessObject = DataAccessObject; DataSource.DataAccessObject = DataAccessObject;
/**
* Global maximum number of event listeners
*/
DataSource.DEFAULT_MAX_OFFLINE_REQUESTS = 16;
/** /**
* Set up the connector instance for backward compatibility with JugglingDB schema/adapter * Set up the connector instance for backward compatibility with JugglingDB schema/adapter
* @private * @private
@ -200,6 +205,10 @@ DataSource.prototype._setupConnector = function() {
this.connector.dataSource = this; this.connector.dataSource = this;
} }
const dataSource = this; const dataSource = this;
// Set max listeners to a default/configured value
dataSource.setMaxListeners(dataSource.getMaxOfflineRequests());
this.connector.log = function(query, start) { this.connector.log = function(query, start) {
dataSource.log(query, start); dataSource.log(query, start);
}; };
@ -2594,6 +2603,27 @@ DataSource.prototype.ping = function(cb) {
return cb.promise; return cb.promise;
}; };
/**
* Get the maximum number of event listeners
*/
DataSource.prototype.getMaxOfflineRequests = function() {
// Set max listeners to a default value
// Override this default value with a datasource setting
// 'maxOfflineRequests' from an application's datasources.json
let maxOfflineRequests = DataSource.DEFAULT_MAX_OFFLINE_REQUESTS;
if (
this.settings &&
this.settings.maxOfflineRequests
) {
if (typeof this.settings.maxOfflineRequests !== 'number')
throw new Error('maxOfflineRequests must be a number');
maxOfflineRequests = this.settings.maxOfflineRequests;
}
return maxOfflineRequests;
};
/*! The hidden property call is too expensive so it is not used that much /*! The hidden property call is too expensive so it is not used that much
*/ */
/** /**

View File

@ -352,4 +352,26 @@ describe('DataSource', function() {
.should.not.containEql('TestModel'); .should.not.containEql('TestModel');
}); });
}); });
describe('getMaxOfflineRequests', () => {
let ds;
beforeEach(() => ds = new DataSource('ds', {connector: 'memory'}));
it('sets the default maximum number of event listeners to 16', () => {
ds.getMaxOfflineRequests().should.be.eql(16);
});
it('uses provided number of listeners', () => {
ds.settings.maxOfflineRequests = 17;
ds.getMaxOfflineRequests().should.be.eql(17);
});
it('throws an error if a non-number is provided for the max number of listeners', () => {
ds.settings.maxOfflineRequests = '17';
(function() {
return ds.getMaxOfflineRequests();
}).should.throw('maxOfflineRequests must be a number');
});
});
}); });