Skip to content

Commit 786c97c

Browse files
committed
Added poolPingTimeout parameter to connection pool and global configuration (Issue #1626)
1 parent 90f8ad5 commit 786c97c

File tree

17 files changed

+278
-1
lines changed

17 files changed

+278
-1
lines changed

doc/src/api_manual/oracledb.rst

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,6 +1627,49 @@ Each of the configuration properties is described below.
16271627
const oracledb = require('oracledb');
16281628
oracledb.poolPingInterval = 60; // seconds
16291629
1630+
.. attribute:: oracledb.poolPingTimeout
1631+
1632+
.. versionadded:: 6.4
1633+
1634+
This property is the number of milliseconds that a connection should wait
1635+
for a response from :meth:`connection.ping()`. If
1636+
:meth:`~connection.ping()` does not respond by the time specified in this
1637+
property, then the connection is forcefully closed.
1638+
1639+
The default value is *5000* milliseconds. The behavior of a pool
1640+
``getConnection()`` call differs based on the value specified in the
1641+
``poolPingTimeout`` property as detailed below.
1642+
1643+
.. list-table-with-summary:: ``poolPingTimeout`` Values
1644+
:header-rows: 1
1645+
:class: wy-table-responsive
1646+
:align: center
1647+
:widths: 15 35
1648+
:summary: The first column displays the ``poolPingTimeout`` value. The second column displays the behavior of a pool ``getConnection()`` call.
1649+
1650+
* - ``poolPingTimeout`` Value
1651+
- Behavior of a Pool ``getConnection()`` Call
1652+
* - ``n`` < ``0``
1653+
- Returns the error ``NJS-007: invalid value for "poolPingTimeout" in parameter 1`` if the :ref:`poolPingTimeout <createpoolpoolattrspoolpingtimeout>` property in :meth:`oracledb.createPool()` is set to a negative value.
1654+
1655+
Returns the error ``NJS-004: invalid value for property "poolPingTimeout"`` if :attr:`oracledb.poolPingTimeout` is set to a negative value.
1656+
* - ``n`` = ``0``
1657+
- Waits until :meth:`connection.ping()` succeeds with a response or fails with an error.
1658+
* - ``n`` > ``0``
1659+
- Waits for :meth:`connection.ping()` to respond by ``n`` milliseconds.
1660+
1661+
If :meth:`~connection.ping()` does not respond by ``n`` milliseconds, then the connection is forcefully closed.
1662+
1663+
This property may be overridden when
1664+
:meth:`creating a connection pool <oracledb.createPool()>`.
1665+
1666+
**Example**
1667+
1668+
.. code-block:: javascript
1669+
1670+
const oracledb = require('oracledb');
1671+
oracledb.poolPingTimeout = 5000; // milliseconds
1672+
16301673
.. attribute:: oracledb.poolTimeout
16311674

16321675
This property is a number that allows the number of open connections in a
@@ -2354,6 +2397,20 @@ Oracledb Methods
23542397
This optional property overrides the :attr:`oracledb.poolPingInterval` property.
23552398

23562399
See :ref:`Connection Pool Pinging <connpoolpinging>` for more information.
2400+
* - ``poolPingTimeout``
2401+
- Number
2402+
- Both
2403+
- .. _createpoolpoolattrspoolpingtimeout:
2404+
2405+
The number of milliseconds that a connection should wait for a response from :meth:`connection.ping()`. Refer to :attr:`oracledb.poolPingTimeout` for details.
2406+
2407+
The default value is *5000* milliseconds.
2408+
2409+
This optional property overrides the :attr:`oracledb.poolPingTimeout` property.
2410+
2411+
See :ref:`Connection Pool Pinging <connpoolpinging>` for more information.
2412+
2413+
.. versionadded:: 6.4
23572414
* - ``poolTimeout``
23582415
- Number
23592416
- Both

doc/src/api_manual/pool.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,18 @@ values.
169169
parameter of :meth:`oracledb.createPool()` and
170170
:attr:`oracledb.poolPingInterval`.
171171

172+
.. attribute:: pool.poolPingTimeout
173+
174+
.. versionadded:: 6.4
175+
176+
This read-only property is a number which specifies the maximum number
177+
of milliseconds that a connection should wait for a response from
178+
:meth:`connection.ping()`.
179+
180+
See :ref:`poolPingTimeout <createpoolpoolattrspoolpingtimeout>`
181+
parameter of :meth:`oracledb.createPool()` and
182+
:attr:`oracledb.poolPingTimeout`.
183+
172184
.. attribute:: pool.poolTimeout
173185

174186
This read-only property is a number which specifies the time (in seconds)

doc/src/release_notes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ node-oracledb `v6.4.0 <https://github.com/oracle/node-oracledb/compare/v6.3.0...
1313
Common Changes
1414
++++++++++++++
1515

16+
#) Added :attr:`oracledb.poolPingTimeout` and :attr:`pool.poolPingTimeout`
17+
to limit the :meth:`connection.ping()` call time.
18+
`Issue #1626 <https://github.com/oracle/node-oracledb/issues/1626>`__.
19+
1620
#) Added the :ref:`warning <execmanywarning>` property to the
1721
:ref:`result <resultobjproperties>` object of
1822
:meth:`connection.executeMany()`.

doc/src/user_guide/connection_handling.rst

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,9 @@ function record the following:
12441244
* - ``poolPingInterval``
12451245
- :attr:`poolPingInterval (seconds) <pool.poolPingInterval>`
12461246
- The maximum number of seconds that a connection can remain idle in a connection pool before node-oracledb pings the database prior to returning that connection to the application.
1247+
* - ``poolPingTimeout``
1248+
- :attr:`poolPingTimeout (milliseconds) <pool.poolPingTimeout>`
1249+
- The number of milliseconds that a connection should wait for a response from :meth:`connection.ping()`.
12471250
* - ``poolTimeout``
12481251
- :attr:`poolTimeout (seconds) <pool.poolTimeout>`
12491252
- The time (in seconds) after which the pool terminates idle connections (unused in the pool).
@@ -1372,6 +1375,35 @@ subsequent ``getConnection()`` call.
13721375
13731376
Explicit pings can be performed at any time with :meth:`connection.ping()`.
13741377
1378+
The time to wait for a response from :meth:`connection.ping()` can be
1379+
controlled with the :attr:`oracledb.poolPingTimeout` property or with the
1380+
:ref:`poolPingTimeout <createpoolpoolattrspoolpingtimeout>` property during
1381+
:ref:`pool creation <createpoolpoolattrspoolpingtimeout>`.
1382+
1383+
The default :attr:`~oracledb.poolPingTimeout` value is *5000* milliseconds.
1384+
The behavior of a pool ``getConnection()`` call differs based on the value
1385+
specified in the ``poolPingTimeout`` property as detailed below.
1386+
1387+
.. list-table-with-summary:: ``poolPingTimeout`` Value
1388+
:header-rows: 1
1389+
:class: wy-table-responsive
1390+
:align: center
1391+
:widths: 15 40
1392+
:summary: The first column displays the poolPingTimeout value. The second column displays the behavior of a pool getConnection() call.
1393+
1394+
* - ``poolPingTimeout`` Value
1395+
- Behavior of a Pool ``getConnection()`` Call
1396+
* - ``n`` < ``0``
1397+
- Returns the error ``NJS-007: invalid value for "poolPingTimeout" in parameter 1`` if the :ref:`poolPingTimeout <createpoolpoolattrspoolpingtimeout>` property in :meth:`oracledb.createPool()` is set to a negative value.
1398+
1399+
Returns the error ``NJS-004: invalid value for property "poolPingTimeout"`` if :attr:`oracledb.poolPingTimeout` is set to a negative value.
1400+
* - ``n`` = ``0``
1401+
- Waits until :meth:`connection.ping()` succeeds with a response or fails with an error.
1402+
* - ``n`` > ``0``
1403+
- Waits for :meth:`connection.ping()` to respond by ``n`` milliseconds.
1404+
1405+
If :meth:`~connection.ping()` does not respond by ``n`` milliseconds, then the connection is forcefully closed.
1406+
13751407
.. _connpooltagging:
13761408
13771409
Connection Tagging and Session State

lib/impl/pool.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,15 @@ class PoolImpl {
147147
errors.throwNotImplemented("getting the pool ping interval");
148148
}
149149

150+
//---------------------------------------------------------------------------
151+
// getPoolPingTimeout()
152+
//
153+
// Returns the pool ping Timeout (milliseconds).
154+
//---------------------------------------------------------------------------
155+
getPoolPingTimeout() {
156+
errors.throwNotImplemented("getting the pool ping Timeout");
157+
}
158+
150159
//---------------------------------------------------------------------------
151160
// getPoolTimeout()
152161
//

lib/oracledb.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,13 @@ async function _verifyOptions(options, inCreatePool) {
368368
outOptions.poolPingInterval = options.poolPingInterval;
369369
}
370370

371+
// poolPingTimeout must be an integer (>= 0)
372+
if (options.poolPingTimeout !== undefined) {
373+
errors.assertParamPropValue(Number.isInteger(options.poolPingTimeout) &&
374+
options.poolPingTimeout >= 0, 1, "poolPingTimeout");
375+
outOptions.poolPingTimeout = options.poolPingTimeout;
376+
}
377+
371378
// homogeneous must be a boolean (and defaults to True)
372379
outOptions.homogeneous = true;
373380
if (options.homogeneous !== undefined) {
@@ -558,6 +565,7 @@ async function createPool(options) {
558565
"poolIncrement",
559566
"poolTimeout",
560567
"poolPingInterval",
568+
"poolPingTimeout",
561569
"queueMax",
562570
"queueTimeout");
563571

@@ -1113,6 +1121,10 @@ module.exports = {
11131121
return settings.poolPingInterval;
11141122
},
11151123

1124+
get poolPingTimeout() {
1125+
return settings.poolPingTimeout;
1126+
},
1127+
11161128
get poolTimeout() {
11171129
return settings.poolTimeout;
11181130
},
@@ -1251,6 +1263,12 @@ module.exports = {
12511263
settings.poolPingInterval = value;
12521264
},
12531265

1266+
set poolPingTimeout(value) {
1267+
errors.assertPropValue(Number.isInteger(value) && value >= 0,
1268+
"poolPingTimeout");
1269+
settings.poolPingTimeout = value;
1270+
},
1271+
12541272
set poolTimeout(value) {
12551273
errors.assertPropValue(Number.isInteger(value) && value >= 0,
12561274
"poolTimeout");

lib/pool.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,15 @@ class Pool extends EventEmitter {
628628
return this._impl.getPoolPingInterval();
629629
}
630630

631+
//---------------------------------------------------------------------------
632+
// poolPingTimeout
633+
//
634+
// Property for the ping timeout associated with the pool.
635+
//---------------------------------------------------------------------------
636+
get poolPingTimeout() {
637+
return this._impl.getPoolPingTimeout();
638+
}
639+
631640
//---------------------------------------------------------------------------
632641
// poolTimeout
633642
//

lib/poolStatistics.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class PoolStatistics {
7272
this.poolMaxPerShard = pool.poolMaxPerShard;
7373
this.poolMin = pool.poolMin;
7474
this.poolPingInterval = pool.poolPingInterval;
75+
this.poolPingTimeout = pool.poolPingTimeout;
7576
this.poolTimeout = pool.poolTimeout;
7677
this.queueMax = pool.queueMax;
7778
this.queueTimeout = pool.queueTimeout;
@@ -124,6 +125,7 @@ class PoolStatistics {
124125
console.log('...poolMaxPerShard:', this.poolMaxPerShard);
125126
console.log('...poolMin:', this.poolMin);
126127
console.log('...poolPingInterval (seconds):', this.poolPingInterval);
128+
console.log('...poolPingTimeout (milliseconds):', this.poolPingTimeout);
127129
console.log('...poolTimeout (seconds):', this.poolTimeout);
128130
console.log('...queueMax:', this.queueMax);
129131
console.log('...queueTimeout (milliseconds):', this.queueTimeout);

lib/settings.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class Settings {
5151
this.poolMaxPerShard = 0;
5252
this.poolMin = 0;
5353
this.poolPingInterval = 60;
54+
this.poolPingTimeout = 5000;
5455
this.poolTimeout = 60;
5556
this.prefetchRows = 2;
5657
this.queueTimeout = 60000;

lib/thin/pool.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class ThinPoolImpl extends PoolImpl {
5353
this._poolIncrement = params.poolIncrement;
5454
this._poolTimeout = params.poolTimeout;
5555
this._poolPingInterval = params.poolPingInterval;
56+
this._poolPingTimeout = params.poolPingTimeout;
5657
this._stmtCacheSize = params.stmtCacheSize;
5758

5859
// The user Config filterd from common layer is cached except
@@ -318,6 +319,13 @@ class ThinPoolImpl extends PoolImpl {
318319
return this._poolPingInterval;
319320
}
320321

322+
//---------------------------------------------------------------------------
323+
// returns the pool ping Timeout (milliseconds)
324+
//---------------------------------------------------------------------------
325+
getPoolPingTimeout() {
326+
return this._poolPingTimeout;
327+
}
328+
321329
//---------------------------------------------------------------------------
322330
// returns the pool timeout
323331
//---------------------------------------------------------------------------
@@ -495,11 +503,21 @@ class ThinPoolImpl extends PoolImpl {
495503
requiresPing = true;
496504
}
497505
if (requiresPing) {
506+
let pingTimer;
498507
try {
508+
if (this._poolPingTimeout) {
509+
pingTimer = setTimeout(() => {
510+
// force disconnect causes ping task to unblock
511+
// and return.
512+
conn.nscon.forceDisconnect();
513+
}, this._poolPingTimeout);
514+
}
499515
await conn.ping();
500516
} catch {
501-
this.eventEmitter.emit('_removePoolConnection', conn);
517+
conn.nscon.forceDisconnect();
502518
continue;
519+
} finally {
520+
clearTimeout(pingTimer);
503521
}
504522
}
505523

0 commit comments

Comments
 (0)