Skip to content

Commit

Permalink
Improve dead connection detection in certain scenarios.
Browse files Browse the repository at this point in the history
  • Loading branch information
anthony-tuininga committed May 7, 2021
1 parent 0dbec76 commit c0a406a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
1 change: 1 addition & 0 deletions doc/src/releasenotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Version 4.2 (TBD)
in order to provide for greater safety. Although there may be instances
where threaded mode is not strictly needed, these are few and any
advantages are minimal.
#) Improved dead connection detection in a number of scenarios.
#) Improved documentation and the test suite.


Expand Down
3 changes: 2 additions & 1 deletion src/dpiConn.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ static int dpiConn__check(dpiConn *conn, const char *fnName, dpiError *error)
//-----------------------------------------------------------------------------
int dpiConn__checkConnected(dpiConn *conn, dpiError *error)
{
if (!conn->handle || conn->closing || (conn->pool && !conn->pool->handle))
if (!conn->handle || conn->closing || conn->deadSession ||
(conn->pool && !conn->pool->handle))
return dpiError__set(error, "check connected", DPI_ERR_NOT_CONNECTED);
return DPI_SUCCESS;
}
Expand Down
23 changes: 19 additions & 4 deletions src/dpiError.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ int dpiError__set(dpiError *error, const char *action, dpiErrorNum errorNum,
int dpiError__setFromOCI(dpiError *error, int status, dpiConn *conn,
const char *action)
{
uint32_t callTimeout;
uint32_t callTimeout, serverStatus;

// special error cases
if (status == DPI_OCI_INVALID_HANDLE)
Expand Down Expand Up @@ -178,10 +178,24 @@ int dpiError__setFromOCI(dpiError *error, int status, dpiConn *conn,
(void*) &error->buffer->isRecoverable, 0,
DPI_OCI_ATTR_ERROR_IS_RECOVERABLE, NULL, error);

// check for certain errors which indicate that the session is dead and
// should be dropped from the session pool (if a session pool was used)
// also check for call timeout and raise unified message instead
// check the health of the connection (if one was specified in this call)
if (conn && !conn->deadSession) {

// first check the attribute specifically designed to check the health
// of the connection, if possible
if (conn->serverHandle) {
if (dpiOci__attrGet(conn->serverHandle, DPI_OCI_HTYPE_SERVER,
&serverStatus, NULL, DPI_OCI_ATTR_SERVER_STATUS,
"get server status", error) < 0 ||
serverStatus != DPI_OCI_SERVER_NORMAL) {
conn->deadSession = 1;
return DPI_FAILURE;
}
}

// otherwise, check for certain errors which indicate that the session
// is dead; also check for call timeout and raise unified message
// instead
switch (error->buffer->code) {
case 22: // invalid session ID; access denied
case 28: // your session has been killed
Expand Down Expand Up @@ -226,6 +240,7 @@ int dpiError__setFromOCI(dpiError *error, int status, dpiConn *conn,
}
break;
}

}

return DPI_FAILURE;
Expand Down

0 comments on commit c0a406a

Please sign in to comment.