mirror of https://github.com/citusdata/citus.git
Add NonblockingForgetResults().
This is very similar to ForgetResults() except that no network IO is performed. Primarily useful in error handling cases.pull/1650/head
parent
c8f7c7fc59
commit
25cabe634e
|
@ -46,8 +46,8 @@ IsResponseOK(PGresult *result)
|
||||||
/*
|
/*
|
||||||
* ForgetResults clears a connection from pending activity.
|
* ForgetResults clears a connection from pending activity.
|
||||||
*
|
*
|
||||||
* XXX: In the future it might be a good idea to use use PQcancel() if results
|
* Note that this might require network IO. If that's not acceptable, use
|
||||||
* would require network IO.
|
* NonblockingForgetResults().
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ForgetResults(MultiConnection *connection)
|
ForgetResults(MultiConnection *connection)
|
||||||
|
@ -73,6 +73,74 @@ ForgetResults(MultiConnection *connection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NonblockingForgetResults clears a connection from pending activity if doing
|
||||||
|
* so does not require network IO. Returns true if successful, false
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
NonblockingForgetResults(MultiConnection *connection)
|
||||||
|
{
|
||||||
|
PGconn *pgConn = connection->pgConn;
|
||||||
|
|
||||||
|
if (PQstatus(pgConn) != CONNECTION_OK)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(PQisnonblocking(pgConn));
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
PGresult *result = NULL;
|
||||||
|
|
||||||
|
/* just in case there's a lot of results */
|
||||||
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If busy, there might still be results already received and buffered
|
||||||
|
* by the OS. As connection is in non-blocking mode, we can check for
|
||||||
|
* that without blocking.
|
||||||
|
*/
|
||||||
|
if (PQisBusy(pgConn))
|
||||||
|
{
|
||||||
|
if (PQflush(pgConn) == -1)
|
||||||
|
{
|
||||||
|
/* write failed */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (PQconsumeInput(pgConn) == 0)
|
||||||
|
{
|
||||||
|
/* some low-level failure */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clearing would require blocking IO, return */
|
||||||
|
if (PQisBusy(pgConn))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = PQgetResult(pgConn);
|
||||||
|
if (PQresultStatus(result) == PGRES_COPY_IN)
|
||||||
|
{
|
||||||
|
/* in copy, can't reliably recover without blocking */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == NULL)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PQclear(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
pg_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SqlStateMatchesCategory returns true if the given sql state (which may be
|
* SqlStateMatchesCategory returns true if the given sql state (which may be
|
||||||
* NULL if unknown) is in the given error category. Note that we use
|
* NULL if unknown) is in the given error category. Note that we use
|
||||||
|
|
|
@ -26,6 +26,7 @@ extern bool LogRemoteCommands;
|
||||||
/* simple helpers */
|
/* simple helpers */
|
||||||
extern bool IsResponseOK(struct pg_result *result);
|
extern bool IsResponseOK(struct pg_result *result);
|
||||||
extern void ForgetResults(MultiConnection *connection);
|
extern void ForgetResults(MultiConnection *connection);
|
||||||
|
extern bool NonblockingForgetResults(MultiConnection *connection);
|
||||||
extern bool SqlStateMatchesCategory(char *sqlStateString, int category);
|
extern bool SqlStateMatchesCategory(char *sqlStateString, int category);
|
||||||
|
|
||||||
/* report errors & warnings */
|
/* report errors & warnings */
|
||||||
|
|
Loading…
Reference in New Issue