Skip to content

Useful options and performance improvements for Pool #1779

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,35 @@ constructor. In addition to those options pools accept a few extras:
* `queueLimit`: The maximum number of connection requests the pool will queue
before returning an error from `getConnection`. If set to `0`, there is no
limit to the number of queued connection requests. (Default: `0`)
* `queueTimeout`: The maximum number of milliseconds that the queued request will
wait for a connection when there are no available connections. If set to `0`,
wait indefinitely. (Default: `0`)
* `testOnBorrow`: Indicates whether the connection is validated before borrowed
from the pool. If the connection fails to validate, it is dropped from the pool.
(Default: `true`)
* `testOnBorrowInterval`: The number of milliseconds that indicates how often
to validate if the connection is working since it was last used. If set too low,
performance may decrease on heavy loaded systems. If set to `0`, It is checked
every time. (Default: `20000`)
* `initialSize`: The initial number of connections that are created when the
pool is started. If set to `0`, this feature is disabled. (Default: `0`)
* `maxIdle`: The maximum number of connections that can remain idle in the pool.
If set to `0`, there is no limit. (Default: `10`)
* `minIdle`: The minimum number of connections that can remain idle in the pool.
(Default: `0`)
* `maxReuseCount`: The maximum connection reuse count allows connections to be
gracefully closed and removed from the connection pool after a connection has
been borrowed a specific number of times. If set to `0`, this feature is disabled.
(Default: `0`)
* `timeBetweenEvictionRunsMillis` : The number of milliseconds to sleep between
runs of examining idle connections. The eviction timer will remove existent
idle conntions by `minEvictableIdleTimeMillis` or create new idle connections
by `minIdle`. If set to `0`, this feature is disabled. (Default: `0`)
* `minEvictableIdleTimeMillis`: The minimum amount of time the connection
may sit idle in the pool before it is eligible for eviction due to idle time.
If set to `0`, no connection will be dropped. (Default: `1800000`)
* `numTestsPerEvictionRun` : The number of connections to examine during each run
of the eviction timer (if any). (Default: `3`)

## Pool events

Expand Down Expand Up @@ -442,6 +471,29 @@ pool.on('release', function (connection) {
});
```

### prepared

The pool will emit a `prepared` event when the pool is ready to use.
If `initialSize` is set, this is called after all initial connections are created.

```js
pool.on('prepared', function (count) {
if (count > 0) {
console.log('Created %d initial connections', count);
}
});
```

### eviction

The pool will emit a `eviction` event when the eviction timer runs.

```js
pool.on('eviction', function (result) {
console.log('Removed : %d / Created : %d', connection.removed, connection.created);
});
```

## Closing all the connections in a pool

When you are done using the pool, you have to end all the connections or the
Expand All @@ -463,6 +515,19 @@ pending queries will still complete and the time to end the pool will vary.
**Once `pool.end()` has been called, `pool.getConnection` and other operations
can no longer be performed**

## Monitoring the status of a pool

If you want to know about the status of the pool, use the `getStatus` method.
It provides 4 values(all, use, idle, queue).

```js
var status = pool.getStatus();
console.log('All connected connections : %d', status.all);
console.log('Connections being used : %d', status.use);
console.log('Idle connections : %d', status.idle);
console.log('Queued requests : %d', status.queue);
```

## PoolCluster

PoolCluster provides multiple hosts connection. (group & retry & selector)
Expand Down
52 changes: 27 additions & 25 deletions lib/ConnectionConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ function ConnectionConfig(options) {
this.user = options.user || undefined;
this.password = options.password || undefined;
this.database = options.database;
this.connectTimeout = (options.connectTimeout === undefined)
? (10 * 1000)
: options.connectTimeout;
this.connectTimeout = (options.connectTimeout === undefined) ? (10 * 1000) : options.connectTimeout;
this.insecureAuth = options.insecureAuth || false;
this.supportBigNumbers = options.supportBigNumbers || false;
this.bigNumberStrings = options.bigNumberStrings || false;
Expand All @@ -30,13 +28,9 @@ function ConnectionConfig(options) {
this.flags = options.flags || '';
this.queryFormat = options.queryFormat;
this.pool = options.pool || undefined;
this.ssl = (typeof options.ssl === 'string')
? ConnectionConfig.getSSLProfile(options.ssl)
: (options.ssl || false);
this.ssl = (typeof options.ssl === 'string') ? ConnectionConfig.getSSLProfile(options.ssl) : (options.ssl || false);
this.multipleStatements = options.multipleStatements || false;
this.typeCast = (options.typeCast === undefined)
? true
: options.typeCast;
this.typeCast = (options.typeCast === undefined) ? true : options.typeCast;

if (this.timezone[0] === ' ') {
// "+" is a url encoded char for space so it
Expand All @@ -51,32 +45,42 @@ function ConnectionConfig(options) {
}

this.maxPacketSize = 0;
this.charsetNumber = (options.charset)
? ConnectionConfig.getCharsetNumber(options.charset)
: options.charsetNumber || Charsets.UTF8_GENERAL_CI;
this.charsetNumber = (options.charset) ? ConnectionConfig.getCharsetNumber(options.charset) : options.charsetNumber || Charsets.UTF8_GENERAL_CI;

// Set the client flags
var defaultFlags = ConnectionConfig.getDefaultFlags(options);
this.clientFlags = ConnectionConfig.mergeFlags(defaultFlags, options.flags);
this.clientFlags = ConnectionConfig._getClientFlags(this.multipleStatements, this.flags);
}

var _clientFlagsCache = {};

ConnectionConfig._getClientFlags = function(multipleStatements, flags) {
var key = flags + multipleStatements;

if (_clientFlagsCache[key] === undefined) {
var defaultFlags = ConnectionConfig.getDefaultFlags(multipleStatements);
_clientFlagsCache[key] = ConnectionConfig.mergeFlags(defaultFlags, flags);
}

return _clientFlagsCache[key];
};

ConnectionConfig.mergeFlags = function mergeFlags(defaultFlags, userFlags) {
var allFlags = ConnectionConfig.parseFlagList(defaultFlags);
var newFlags = ConnectionConfig.parseFlagList(userFlags);

// Merge the new flags
for (var flag in newFlags) {
if (allFlags[flag] !== false) {
allFlags[flag] = newFlags[flag];
for (var newFlagKey in newFlags) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why rename this variable? Seems unrelated to the pull request. Please undo or explain how it fits into changing the pool.

if (allFlags[newFlagKey] !== false) {
allFlags[newFlagKey] = newFlags[newFlagKey];
}
}

// Build flags
var flags = 0x0;
for (var flag in allFlags) {
if (allFlags[flag]) {
for (var key in allFlags) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why rename this variable? Seems unrelated to the pull request. Please undo or explain how it fits into changing the pool.

if (allFlags[key]) {
// TODO: Throw here on some future release
flags |= ClientConstants['CLIENT_' + flag] || 0x0;
flags |= ClientConstants['CLIENT_' + key] || 0x0;
}
}

Expand All @@ -93,7 +97,7 @@ ConnectionConfig.getCharsetNumber = function getCharsetNumber(charset) {
return num;
};

ConnectionConfig.getDefaultFlags = function getDefaultFlags(options) {
ConnectionConfig.getDefaultFlags = function getDefaultFlags(multipleStatements) {
var defaultFlags = [
'-COMPRESS', // Compression protocol *NOT* supported
'-CONNECT_ATTRS', // Does *NOT* send connection attributes in Protocol::HandshakeResponse41
Expand All @@ -114,7 +118,7 @@ ConnectionConfig.getDefaultFlags = function getDefaultFlags(options) {
'+TRANSACTIONS' // Expects status flags
];

if (options && options.multipleStatements) {
if (multipleStatements) {
// May send multiple statements per COM_QUERY and COM_STMT_PREPARE
defaultFlags.push('+MULTI_STATEMENTS');
}
Expand Down Expand Up @@ -143,9 +147,7 @@ ConnectionConfig.parseFlagList = function parseFlagList(flagList) {
return allFlags;
}

var flags = !Array.isArray(flagList)
? String(flagList || '').toUpperCase().split(/\s*,+\s*/)
: flagList;
var flags = !Array.isArray(flagList) ? String(flagList || '').toUpperCase().split(/\s*,+\s*/) : flagList;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please undo the format change to this line.


for (var i = 0; i < flags.length; i++) {
var flag = flags[i];
Expand Down
Loading