Skip to content

Commit e90d75a

Browse files
committed
Make sharded pool connections respect queueTimeout when poolMaxPerShard has been reached
1 parent 1643fe2 commit e90d75a

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
- Fixed various execution failures with Node.js 13.2 due to Node.js NULL pointer behavior change ([ODPI-C
2323
change](https://github.com/oracle/odpi/commit/7693865bb6a98568546aa319cc0fdb9e208cf9d4)).
2424

25+
- Fixed connection pooling so sharded `pool.getConnection()` requests respect
26+
`queueTimeout` when `poolMaxPerShard` has been reached.
27+
2528
- Added a directory the binary module search to help Webpack use, though a copy
2629
plugin is still required, see
2730
[here](https://github.com/oracle/node-oracledb/issues/1156#issuecomment-571554125).

lib/oracledb.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,22 @@ function createPool(poolAttrs, createPoolCb) {
174174
// be called by the database when a connection acquired from the pool doesn't
175175
// have the requested tag
176176
sessionCallback = poolAttrs.sessionCallback;
177+
178+
// create an adjusted set of pool attributes to pass to the C layer; the
179+
// session callback must be removed if it is a JavaScript function and the
180+
// queue timeout is used to specify the maximum amount of time that the C
181+
// layer will wait for a connection to be returned; ordinarily since the
182+
// JavaScript layer never calls the C layer to get a connection unless one is
183+
// known to be available, this should not be needed, but in some cases (such
184+
// as when the maximum for a particular shard is specified) this may not be
185+
// known, so this prevents an unnecessarily long wait from taking place
186+
const adjustedPoolAttrs = Object.defineProperties({},
187+
Object.getOwnPropertyDescriptors(poolAttrs));
177188
if (typeof poolAttrs.sessionCallback === 'function') {
178-
poolAttrs = Object.assign({}, poolAttrs);
179-
delete poolAttrs.sessionCallback;
189+
delete adjustedPoolAttrs.sessionCallback;
190+
}
191+
if (adjustedPoolAttrs.queueTimeout === undefined) {
192+
adjustedPoolAttrs.queueTimeout = self.queueTimeout;
180193
}
181194

182195
// Need to prevent another call in the same stack from succeeding, otherwise
@@ -186,7 +199,7 @@ function createPool(poolAttrs, createPoolCb) {
186199
tempUsedPoolAliases[poolAlias] = true;
187200
}
188201

189-
self._createPool(poolAttrs, function(err, poolInst) {
202+
self._createPool(adjustedPoolAttrs, function(err, poolInst) {
190203
if (err) {
191204
// We need to free this up since the creation of the pool failed.
192205
if (poolAlias) {
@@ -208,7 +221,6 @@ function createPool(poolAttrs, createPoolCb) {
208221
delete tempUsedPoolAliases[poolAlias];
209222
}
210223

211-
poolAttrs.sessionCallback = sessionCallback;
212224
poolInst._setup(poolAttrs, poolAlias, self);
213225

214226
poolInst.on('_after_close', function() {

src/njsModule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
1+
// Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
22

33
//-----------------------------------------------------------------------------
44
//
@@ -426,6 +426,7 @@ struct njsBaton {
426426
uint32_t poolMaxPerShard;
427427
uint32_t poolIncrement;
428428
uint32_t poolTimeout;
429+
uint32_t poolWaitTimeout;
429430
int32_t poolPingInterval;
430431
uint32_t stmtCacheSize;
431432
uint32_t maxRows;

src/njsOracleDb.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
1+
// Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
22

33
//-----------------------------------------------------------------------------
44
//
@@ -367,7 +367,9 @@ static bool njsOracleDb_createPoolAsync(njsBaton *baton)
367367
params.maxSessions = baton->poolMax;
368368
params.maxSessionsPerShard = baton->poolMaxPerShard;
369369
params.sessionIncrement = baton->poolIncrement;
370-
params.getMode = DPI_MODE_POOL_GET_WAIT;
370+
params.getMode = (baton->poolMaxPerShard > 0) ?
371+
DPI_MODE_POOL_GET_TIMEDWAIT : DPI_MODE_POOL_GET_WAIT;
372+
params.waitTimeout = baton->poolWaitTimeout;
371373
params.externalAuth = baton->externalAuth;
372374
params.homogeneous = baton->homogeneous;
373375
params.plsqlFixupCallback = baton->plsqlFixupCallback;
@@ -495,6 +497,9 @@ static bool njsOracleDb_createPoolProcessArgs(njsBaton *baton, napi_env env,
495497
if (!njsBaton_getBoolFromArg(baton, env, args, 0, "events",
496498
&baton->events, NULL))
497499
return false;
500+
if (!njsBaton_getUnsignedIntFromArg(baton, env, args, 0, "queueTimeout",
501+
&baton->poolWaitTimeout, NULL))
502+
return false;
498503

499504
return true;
500505
}

0 commit comments

Comments
 (0)