Added support for timed waits when acquiring a session from a session pool and

added support for specifying the timeout and maximum lifetime session of
sessions in the pool when the pool is being created.
This commit is contained in:
Anthony Tuininga 2018-05-16 14:09:59 -06:00
parent 62f11ac570
commit b9381892a5
3 changed files with 59 additions and 4 deletions

View File

@ -180,7 +180,7 @@ Module Interface
increment=1, connectiontype=cx_Oracle.Connection, threaded=False, \ increment=1, connectiontype=cx_Oracle.Connection, threaded=False, \
getmode=cx_Oracle.SPOOL_ATTRVAL_NOWAIT, events=False, \ getmode=cx_Oracle.SPOOL_ATTRVAL_NOWAIT, events=False, \
homogeneous=True, externalauth=False, encoding=None, nencoding=None, \ homogeneous=True, externalauth=False, encoding=None, nencoding=None, \
edition=None) edition=None, timeout=0, waitTimeout=0, maxLifetimeSession=0)
Create and return a :ref:`session pool object <sesspool>`. This Create and return a :ref:`session pool object <sesspool>`. This
allows for very fast connections to the database and is of primary use in a allows for very fast connections to the database and is of primary use in a
@ -216,6 +216,26 @@ Module Interface
the edition to use for the sessions in the pool. It is only relevant if the edition to use for the sessions in the pool. It is only relevant if
both the client and the server are at least Oracle Database 11.2. both the client and the server are at least Oracle Database 11.2.
The timeout parameter is expected to be an integer, if specified, and sets
the length of time (in seconds) after which idle sessions in the pool are
terminated. Note that termination only occurs when another session is
released back to the pool. The default value of 0 means that no idle
are terminated.
The waitTimeout parameter is expected to be an integer, if specified, and
sets the length of time (in milliseconds) that the caller should wait for
a session to become available in the pool before returning with an error.
This value is only used if the getmode parameter is set to the value
:data:`cx_Oracle.SPOOL_ATTRVAL_TIMEDWAIT`.
The maxLifetimeSession parameter is expected to be an integer, if
specified, and sets the length of time (in seconds) a session may remain
in the pool. Sessions in the pool are terminated after they have been in
the pool for the specified period of time. Note that termination only
occurs when another session is released back to the pool. The default value
is 0 which means that there is no maximum length of time that a session may
exist in the pool.
.. note:: .. note::
This method is an extension to the DB API definition. This method is an extension to the DB API definition.
@ -753,6 +773,12 @@ values for the getmode parameter of the :meth:`SessionPool()` method.
session is available if there are no free sessions available in the pool. session is available if there are no free sessions available in the pool.
.. data:: SPOOL_ATTRVAL_TIMEDWAIT
This constant is used to specify that the caller should wait for a period
of time (defined by the waitTimeout parameter) for a session to become
available before returning with an error.
Session Pool Purity Session Pool Purity
------------------- -------------------

View File

@ -407,6 +407,8 @@ static PyObject *cxoModule_initialize(void)
CXO_ADD_INT_CONSTANT("SPOOL_ATTRVAL_WAIT", DPI_MODE_POOL_GET_WAIT) CXO_ADD_INT_CONSTANT("SPOOL_ATTRVAL_WAIT", DPI_MODE_POOL_GET_WAIT)
CXO_ADD_INT_CONSTANT("SPOOL_ATTRVAL_NOWAIT", DPI_MODE_POOL_GET_NOWAIT) CXO_ADD_INT_CONSTANT("SPOOL_ATTRVAL_NOWAIT", DPI_MODE_POOL_GET_NOWAIT)
CXO_ADD_INT_CONSTANT("SPOOL_ATTRVAL_FORCEGET", DPI_MODE_POOL_GET_FORCEGET) CXO_ADD_INT_CONSTANT("SPOOL_ATTRVAL_FORCEGET", DPI_MODE_POOL_GET_FORCEGET)
CXO_ADD_INT_CONSTANT("SPOOL_ATTRVAL_TIMEDWAIT",
DPI_MODE_POOL_GET_TIMEDWAIT)
// add constants for database shutdown modes // add constants for database shutdown modes
CXO_ADD_INT_CONSTANT("DBSHUTDOWN_ABORT", DPI_MODE_SHUTDOWN_ABORT) CXO_ADD_INT_CONSTANT("DBSHUTDOWN_ABORT", DPI_MODE_SHUTDOWN_ABORT)

View File

@ -29,11 +29,13 @@ static PyObject *cxoSessionPool_getMaxLifetimeSession(cxoSessionPool*, void*);
static PyObject *cxoSessionPool_getOpenCount(cxoSessionPool*, void*); static PyObject *cxoSessionPool_getOpenCount(cxoSessionPool*, void*);
static PyObject *cxoSessionPool_getStmtCacheSize(cxoSessionPool*, void*); static PyObject *cxoSessionPool_getStmtCacheSize(cxoSessionPool*, void*);
static PyObject *cxoSessionPool_getTimeout(cxoSessionPool*, void*); static PyObject *cxoSessionPool_getTimeout(cxoSessionPool*, void*);
static PyObject *cxoSessionPool_getWaitTimeout(cxoSessionPool*, void*);
static int cxoSessionPool_setGetMode(cxoSessionPool*, PyObject*, void*); static int cxoSessionPool_setGetMode(cxoSessionPool*, PyObject*, void*);
static int cxoSessionPool_setMaxLifetimeSession(cxoSessionPool*, PyObject*, static int cxoSessionPool_setMaxLifetimeSession(cxoSessionPool*, PyObject*,
void*); void*);
static int cxoSessionPool_setStmtCacheSize(cxoSessionPool*, PyObject*, void*); static int cxoSessionPool_setStmtCacheSize(cxoSessionPool*, PyObject*, void*);
static int cxoSessionPool_setTimeout(cxoSessionPool*, PyObject*, void*); static int cxoSessionPool_setTimeout(cxoSessionPool*, PyObject*, void*);
static int cxoSessionPool_setWaitTimeout(cxoSessionPool*, PyObject*, void*);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -80,6 +82,8 @@ static PyGetSetDef cxoSessionPoolCalcMembers[] = {
(setter) cxoSessionPool_setMaxLifetimeSession, 0, 0 }, (setter) cxoSessionPool_setMaxLifetimeSession, 0, 0 },
{ "stmtcachesize", (getter) cxoSessionPool_getStmtCacheSize, { "stmtcachesize", (getter) cxoSessionPool_getStmtCacheSize,
(setter) cxoSessionPool_setStmtCacheSize, 0, 0 }, (setter) cxoSessionPool_setStmtCacheSize, 0, 0 },
{ "wait_timeout", (getter) cxoSessionPool_getWaitTimeout,
(setter) cxoSessionPool_setWaitTimeout, 0, 0 },
{ NULL } { NULL }
}; };
@ -166,7 +170,7 @@ static int cxoSessionPool_init(cxoSessionPool *pool, PyObject *args,
static char *keywordList[] = { "user", "password", "dsn", "min", "max", static char *keywordList[] = { "user", "password", "dsn", "min", "max",
"increment", "connectiontype", "threaded", "getmode", "events", "increment", "connectiontype", "threaded", "getmode", "events",
"homogeneous", "externalauth", "encoding", "nencoding", "edition", "homogeneous", "externalauth", "encoding", "nencoding", "edition",
NULL }; "timeout", "waitTimeout", "maxLifetimeSession", NULL };
// parse arguments and keywords // parse arguments and keywords
usernameObj = passwordObj = dsnObj = editionObj = Py_None; usernameObj = passwordObj = dsnObj = editionObj = Py_None;
@ -185,12 +189,13 @@ static int cxoSessionPool_init(cxoSessionPool *pool, PyObject *args,
(uint32_t) strlen(dpiCommonParams.driverName); (uint32_t) strlen(dpiCommonParams.driverName);
if (dpiContext_initPoolCreateParams(cxoDpiContext, &dpiCreateParams) < 0) if (dpiContext_initPoolCreateParams(cxoDpiContext, &dpiCreateParams) < 0)
return cxoError_raiseAndReturnInt(); return cxoError_raiseAndReturnInt();
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|OOOiiiOObOOOssO", if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|OOOiiiOObOOOssOiii",
keywordList, &usernameObj, &passwordObj, &dsnObj, &minSessions, keywordList, &usernameObj, &passwordObj, &dsnObj, &minSessions,
&maxSessions, &sessionIncrement, &connectionType, &threadedObj, &maxSessions, &sessionIncrement, &connectionType, &threadedObj,
&dpiCreateParams.getMode, &eventsObj, &homogeneousObj, &dpiCreateParams.getMode, &eventsObj, &homogeneousObj,
&externalAuthObj, &dpiCommonParams.encoding, &externalAuthObj, &dpiCommonParams.encoding,
&dpiCommonParams.nencoding, &editionObj)) &dpiCommonParams.nencoding, &editionObj, &dpiCreateParams.timeout,
&dpiCreateParams.waitTimeout, &dpiCreateParams.maxLifetimeSession))
return -1; return -1;
if (!PyType_Check(connectionType)) { if (!PyType_Check(connectionType)) {
cxoError_raiseFromString(cxoProgrammingErrorException, cxoError_raiseFromString(cxoProgrammingErrorException,
@ -529,6 +534,17 @@ static PyObject *cxoSessionPool_getTimeout(cxoSessionPool *pool, void *unused)
} }
//-----------------------------------------------------------------------------
// cxoSessionPool_getWaitTimeout()
// Return the wait timeout for connections in the session pool.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_getWaitTimeout(cxoSessionPool *pool,
void *unused)
{
return cxoSessionPool_getAttribute(pool, dpiPool_getWaitTimeout);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// cxoSessionPool_setGetMode() // cxoSessionPool_setGetMode()
// Set the "get" mode for connections in the session pool. // Set the "get" mode for connections in the session pool.
@ -582,3 +598,14 @@ static int cxoSessionPool_setTimeout(cxoSessionPool *pool, PyObject *value,
return cxoSessionPool_setAttribute(pool, value, dpiPool_setTimeout); return cxoSessionPool_setAttribute(pool, value, dpiPool_setTimeout);
} }
//-----------------------------------------------------------------------------
// cxoSessionPool_setWaitTimeout()
// Set the wait timeout for connections in the session pool.
//-----------------------------------------------------------------------------
static int cxoSessionPool_setWaitTimeout(cxoSessionPool *pool, PyObject *value,
void *unused)
{
return cxoSessionPool_setAttribute(pool, value, dpiPool_setWaitTimeout);
}