Move multi_client_executor.[ch] ontop of connection_management.[ch].

That way connections can be automatically closed after errors and such,
and the connection management infrastructure gets wider testing.  It
also fixes a few issues around connection string building.
pull/863/head
Andres Freund 2016-12-01 14:36:42 -08:00
parent a77cf36778
commit 2374905c89
2 changed files with 71 additions and 111 deletions

View File

@ -23,6 +23,7 @@
#include "distributed/connection_management.h" #include "distributed/connection_management.h"
#include "distributed/multi_client_executor.h" #include "distributed/multi_client_executor.h"
#include "distributed/multi_server_executor.h" #include "distributed/multi_server_executor.h"
#include "distributed/remote_commands.h"
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
@ -39,7 +40,7 @@
/* Local pool to track active connections */ /* Local pool to track active connections */
static PGconn *ClientConnectionArray[MAX_CONNECTION_COUNT]; static MultiConnection *ClientConnectionArray[MAX_CONNECTION_COUNT];
/* /*
* The value at any position on ClientPollingStatusArray is only defined when * The value at any position on ClientPollingStatusArray is only defined when
@ -49,8 +50,8 @@ static PostgresPollingStatusType ClientPollingStatusArray[MAX_CONNECTION_COUNT];
/* Local functions forward declarations */ /* Local functions forward declarations */
static void ClearRemainingResults(PGconn *connection); static void ClearRemainingResults(MultiConnection *connection);
static bool ClientConnectionReady(PGconn *connection, static bool ClientConnectionReady(MultiConnection *connection,
PostgresPollingStatusType pollingStatus); PostgresPollingStatusType pollingStatus);
@ -64,7 +65,7 @@ AllocateConnectionId(void)
/* allocate connectionId from connection pool */ /* allocate connectionId from connection pool */
for (connIndex = 0; connIndex < MAX_CONNECTION_COUNT; connIndex++) for (connIndex = 0; connIndex < MAX_CONNECTION_COUNT; connIndex++)
{ {
PGconn *connection = ClientConnectionArray[connIndex]; MultiConnection *connection = ClientConnectionArray[connIndex];
if (connection == NULL) if (connection == NULL)
{ {
connectionId = connIndex; connectionId = connIndex;
@ -88,12 +89,16 @@ int32
MultiClientConnect(const char *nodeName, uint32 nodePort, const char *nodeDatabase, MultiClientConnect(const char *nodeName, uint32 nodePort, const char *nodeDatabase,
const char *userName) const char *userName)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
char connInfoString[STRING_BUFFER_SIZE];
ConnStatusType connStatusType = CONNECTION_OK; ConnStatusType connStatusType = CONNECTION_OK;
int32 connectionId = AllocateConnectionId(); int32 connectionId = AllocateConnectionId();
char *effectiveDatabaseName = NULL; int connectionFlags = FORCE_NEW_CONNECTION; /* no cached connections for now */
char *effectiveUserName = NULL;
if (connectionId == INVALID_CONNECTION_ID)
{
ereport(WARNING, (errmsg("could not allocate connection in connection pool")));
return connectionId;
}
if (XactModificationLevel > XACT_MODIFICATION_NONE) if (XactModificationLevel > XACT_MODIFICATION_NONE)
{ {
@ -102,46 +107,11 @@ MultiClientConnect(const char *nodeName, uint32 nodePort, const char *nodeDataba
"command within a transaction"))); "command within a transaction")));
} }
if (connectionId == INVALID_CONNECTION_ID)
{
ereport(WARNING, (errmsg("could not allocate connection in connection pool")));
return connectionId;
}
if (nodeDatabase == NULL)
{
effectiveDatabaseName = get_database_name(MyDatabaseId);
}
else
{
effectiveDatabaseName = pstrdup(nodeDatabase);
}
if (userName == NULL)
{
effectiveUserName = CurrentUserName();
}
else
{
effectiveUserName = pstrdup(userName);
}
/*
* FIXME: This code is bad on several levels. It completely forgoes any
* escaping, it misses setting a number of parameters, it works with a
* limited string size without erroring when it's too long. We shouldn't
* even build a query string this way, there's PQconnectdbParams()!
*/
/* transcribe connection paremeters to string */
snprintf(connInfoString, STRING_BUFFER_SIZE, CONN_INFO_TEMPLATE,
nodeName, nodePort,
effectiveDatabaseName, effectiveUserName,
CLIENT_CONNECT_TIMEOUT);
/* establish synchronous connection to worker node */ /* establish synchronous connection to worker node */
connection = PQconnectdb(connInfoString); connection = GetNodeUserDatabaseConnection(connectionFlags, nodeName, nodePort,
connStatusType = PQstatus(connection); userName, nodeDatabase);
connStatusType = PQstatus(connection->pgConn);
if (connStatusType == CONNECTION_OK) if (connStatusType == CONNECTION_OK)
{ {
@ -149,15 +119,11 @@ MultiClientConnect(const char *nodeName, uint32 nodePort, const char *nodeDataba
} }
else else
{ {
WarnRemoteError(connection, NULL); ReportConnectionError(connection, WARNING);
CloseConnection(connection);
PQfinish(connection);
connectionId = INVALID_CONNECTION_ID; connectionId = INVALID_CONNECTION_ID;
} }
pfree(effectiveDatabaseName);
pfree(effectiveUserName);
return connectionId; return connectionId;
} }
@ -170,12 +136,11 @@ MultiClientConnect(const char *nodeName, uint32 nodePort, const char *nodeDataba
int32 int32
MultiClientConnectStart(const char *nodeName, uint32 nodePort, const char *nodeDatabase) MultiClientConnectStart(const char *nodeName, uint32 nodePort, const char *nodeDatabase)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
char connInfoString[STRING_BUFFER_SIZE]; ConnStatusType connStatusType = CONNECTION_OK;
ConnStatusType connStatusType = CONNECTION_BAD;
char *userName = CurrentUserName();
int32 connectionId = AllocateConnectionId(); int32 connectionId = AllocateConnectionId();
int connectionFlags = FORCE_NEW_CONNECTION; /* no cached connections for now */
if (connectionId == INVALID_CONNECTION_ID) if (connectionId == INVALID_CONNECTION_ID)
{ {
ereport(WARNING, (errmsg("could not allocate connection in connection pool"))); ereport(WARNING, (errmsg("could not allocate connection in connection pool")));
@ -189,13 +154,9 @@ MultiClientConnectStart(const char *nodeName, uint32 nodePort, const char *nodeD
"command within a transaction"))); "command within a transaction")));
} }
/* transcribe connection paremeters to string */
snprintf(connInfoString, STRING_BUFFER_SIZE, CONN_INFO_TEMPLATE,
nodeName, nodePort, nodeDatabase, userName, CLIENT_CONNECT_TIMEOUT);
/* prepare asynchronous request for worker node connection */ /* prepare asynchronous request for worker node connection */
connection = PQconnectStart(connInfoString); connection = StartNodeConnection(connectionFlags, nodeName, nodePort);
connStatusType = PQstatus(connection); connStatusType = PQstatus(connection->pgConn);
/* /*
* If prepared, we save the connection, and set its initial polling status * If prepared, we save the connection, and set its initial polling status
@ -209,9 +170,9 @@ MultiClientConnectStart(const char *nodeName, uint32 nodePort, const char *nodeD
} }
else else
{ {
WarnRemoteError(connection, NULL); ReportConnectionError(connection, WARNING);
CloseConnection(connection);
PQfinish(connection);
connectionId = INVALID_CONNECTION_ID; connectionId = INVALID_CONNECTION_ID;
} }
@ -223,7 +184,7 @@ MultiClientConnectStart(const char *nodeName, uint32 nodePort, const char *nodeD
ConnectStatus ConnectStatus
MultiClientConnectPoll(int32 connectionId) MultiClientConnectPoll(int32 connectionId)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
PostgresPollingStatusType pollingStatus = PGRES_POLLING_OK; PostgresPollingStatusType pollingStatus = PGRES_POLLING_OK;
ConnectStatus connectStatus = CLIENT_INVALID_CONNECT; ConnectStatus connectStatus = CLIENT_INVALID_CONNECT;
@ -241,7 +202,7 @@ MultiClientConnectPoll(int32 connectionId)
bool readReady = ClientConnectionReady(connection, PGRES_POLLING_READING); bool readReady = ClientConnectionReady(connection, PGRES_POLLING_READING);
if (readReady) if (readReady)
{ {
ClientPollingStatusArray[connectionId] = PQconnectPoll(connection); ClientPollingStatusArray[connectionId] = PQconnectPoll(connection->pgConn);
connectStatus = CLIENT_CONNECTION_BUSY; connectStatus = CLIENT_CONNECTION_BUSY;
} }
else else
@ -254,7 +215,7 @@ MultiClientConnectPoll(int32 connectionId)
bool writeReady = ClientConnectionReady(connection, PGRES_POLLING_WRITING); bool writeReady = ClientConnectionReady(connection, PGRES_POLLING_WRITING);
if (writeReady) if (writeReady)
{ {
ClientPollingStatusArray[connectionId] = PQconnectPoll(connection); ClientPollingStatusArray[connectionId] = PQconnectPoll(connection->pgConn);
connectStatus = CLIENT_CONNECTION_BUSY; connectStatus = CLIENT_CONNECTION_BUSY;
} }
else else
@ -264,7 +225,7 @@ MultiClientConnectPoll(int32 connectionId)
} }
else if (pollingStatus == PGRES_POLLING_FAILED) else if (pollingStatus == PGRES_POLLING_FAILED)
{ {
WarnRemoteError(connection, NULL); ReportConnectionError(connection, WARNING);
connectStatus = CLIENT_CONNECTION_BAD; connectStatus = CLIENT_CONNECTION_BAD;
} }
@ -277,14 +238,14 @@ MultiClientConnectPoll(int32 connectionId)
void void
MultiClientDisconnect(int32 connectionId) MultiClientDisconnect(int32 connectionId)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
const int InvalidPollingStatus = -1; const int InvalidPollingStatus = -1;
Assert(connectionId != INVALID_CONNECTION_ID); Assert(connectionId != INVALID_CONNECTION_ID);
connection = ClientConnectionArray[connectionId]; connection = ClientConnectionArray[connectionId];
Assert(connection != NULL); Assert(connection != NULL);
PQfinish(connection); CloseConnection(connection);
ClientConnectionArray[connectionId] = NULL; ClientConnectionArray[connectionId] = NULL;
ClientPollingStatusArray[connectionId] = InvalidPollingStatus; ClientPollingStatusArray[connectionId] = InvalidPollingStatus;
@ -298,7 +259,7 @@ MultiClientDisconnect(int32 connectionId)
bool bool
MultiClientConnectionUp(int32 connectionId) MultiClientConnectionUp(int32 connectionId)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
ConnStatusType connStatusType = CONNECTION_OK; ConnStatusType connStatusType = CONNECTION_OK;
bool connectionUp = true; bool connectionUp = true;
@ -306,7 +267,7 @@ MultiClientConnectionUp(int32 connectionId)
connection = ClientConnectionArray[connectionId]; connection = ClientConnectionArray[connectionId];
Assert(connection != NULL); Assert(connection != NULL);
connStatusType = PQstatus(connection); connStatusType = PQstatus(connection->pgConn);
if (connStatusType == CONNECTION_BAD) if (connStatusType == CONNECTION_BAD)
{ {
connectionUp = false; connectionUp = false;
@ -340,7 +301,7 @@ MultiClientExecute(int32 connectionId, const char *query, void **queryResult,
bool bool
MultiClientSendQuery(int32 connectionId, const char *query) MultiClientSendQuery(int32 connectionId, const char *query)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
bool success = true; bool success = true;
int querySent = 0; int querySent = 0;
@ -348,10 +309,10 @@ MultiClientSendQuery(int32 connectionId, const char *query)
connection = ClientConnectionArray[connectionId]; connection = ClientConnectionArray[connectionId];
Assert(connection != NULL); Assert(connection != NULL);
querySent = PQsendQuery(connection, query); querySent = PQsendQuery(connection->pgConn, query);
if (querySent == 0) if (querySent == 0)
{ {
char *errorMessage = PQerrorMessage(connection); char *errorMessage = PQerrorMessage(connection->pgConn);
ereport(WARNING, (errmsg("could not send remote query \"%s\"", query), ereport(WARNING, (errmsg("could not send remote query \"%s\"", query),
errdetail("Client error: %s", errorMessage))); errdetail("Client error: %s", errorMessage)));
@ -366,7 +327,7 @@ MultiClientSendQuery(int32 connectionId, const char *query)
bool bool
MultiClientCancel(int32 connectionId) MultiClientCancel(int32 connectionId)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
PGcancel *cancelObject = NULL; PGcancel *cancelObject = NULL;
int cancelSent = 0; int cancelSent = 0;
bool canceled = true; bool canceled = true;
@ -376,7 +337,7 @@ MultiClientCancel(int32 connectionId)
connection = ClientConnectionArray[connectionId]; connection = ClientConnectionArray[connectionId];
Assert(connection != NULL); Assert(connection != NULL);
cancelObject = PQgetCancel(connection); cancelObject = PQgetCancel(connection->pgConn);
cancelSent = PQcancel(cancelObject, errorBuffer, sizeof(errorBuffer)); cancelSent = PQcancel(cancelObject, errorBuffer, sizeof(errorBuffer));
if (cancelSent == 0) if (cancelSent == 0)
@ -397,7 +358,7 @@ MultiClientCancel(int32 connectionId)
ResultStatus ResultStatus
MultiClientResultStatus(int32 connectionId) MultiClientResultStatus(int32 connectionId)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
int consumed = 0; int consumed = 0;
ConnStatusType connStatusType = CONNECTION_OK; ConnStatusType connStatusType = CONNECTION_OK;
ResultStatus resultStatus = CLIENT_INVALID_RESULT_STATUS; ResultStatus resultStatus = CLIENT_INVALID_RESULT_STATUS;
@ -406,7 +367,7 @@ MultiClientResultStatus(int32 connectionId)
connection = ClientConnectionArray[connectionId]; connection = ClientConnectionArray[connectionId];
Assert(connection != NULL); Assert(connection != NULL);
connStatusType = PQstatus(connection); connStatusType = PQstatus(connection->pgConn);
if (connStatusType == CONNECTION_BAD) if (connStatusType == CONNECTION_BAD)
{ {
ereport(WARNING, (errmsg("could not maintain connection to worker node"))); ereport(WARNING, (errmsg("could not maintain connection to worker node")));
@ -414,10 +375,10 @@ MultiClientResultStatus(int32 connectionId)
} }
/* consume input to allow status change */ /* consume input to allow status change */
consumed = PQconsumeInput(connection); consumed = PQconsumeInput(connection->pgConn);
if (consumed != 0) if (consumed != 0)
{ {
int connectionBusy = PQisBusy(connection); int connectionBusy = PQisBusy(connection->pgConn);
if (connectionBusy == 0) if (connectionBusy == 0)
{ {
resultStatus = CLIENT_RESULT_READY; resultStatus = CLIENT_RESULT_READY;
@ -442,7 +403,7 @@ bool
MultiClientQueryResult(int32 connectionId, void **queryResult, int *rowCount, MultiClientQueryResult(int32 connectionId, void **queryResult, int *rowCount,
int *columnCount) int *columnCount)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
PGresult *result = NULL; PGresult *result = NULL;
ConnStatusType connStatusType = CONNECTION_OK; ConnStatusType connStatusType = CONNECTION_OK;
ExecStatusType resultStatus = PGRES_COMMAND_OK; ExecStatusType resultStatus = PGRES_COMMAND_OK;
@ -451,14 +412,14 @@ MultiClientQueryResult(int32 connectionId, void **queryResult, int *rowCount,
connection = ClientConnectionArray[connectionId]; connection = ClientConnectionArray[connectionId];
Assert(connection != NULL); Assert(connection != NULL);
connStatusType = PQstatus(connection); connStatusType = PQstatus(connection->pgConn);
if (connStatusType == CONNECTION_BAD) if (connStatusType == CONNECTION_BAD)
{ {
ereport(WARNING, (errmsg("could not maintain connection to worker node"))); ereport(WARNING, (errmsg("could not maintain connection to worker node")));
return false; return false;
} }
result = PQgetResult(connection); result = PQgetResult(connection->pgConn);
resultStatus = PQresultStatus(result); resultStatus = PQresultStatus(result);
if (resultStatus == PGRES_TUPLES_OK) if (resultStatus == PGRES_TUPLES_OK)
{ {
@ -468,7 +429,7 @@ MultiClientQueryResult(int32 connectionId, void **queryResult, int *rowCount,
} }
else else
{ {
WarnRemoteError(connection, result); ReportResultError(connection, result, WARNING);
PQclear(result); PQclear(result);
return false; return false;
@ -494,7 +455,7 @@ BatchQueryStatus
MultiClientBatchResult(int32 connectionId, void **queryResult, int *rowCount, MultiClientBatchResult(int32 connectionId, void **queryResult, int *rowCount,
int *columnCount) int *columnCount)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
PGresult *result = NULL; PGresult *result = NULL;
ConnStatusType connStatusType = CONNECTION_OK; ConnStatusType connStatusType = CONNECTION_OK;
ExecStatusType resultStatus = PGRES_COMMAND_OK; ExecStatusType resultStatus = PGRES_COMMAND_OK;
@ -509,14 +470,14 @@ MultiClientBatchResult(int32 connectionId, void **queryResult, int *rowCount,
(*rowCount) = -1; (*rowCount) = -1;
(*columnCount) = -1; (*columnCount) = -1;
connStatusType = PQstatus(connection); connStatusType = PQstatus(connection->pgConn);
if (connStatusType == CONNECTION_BAD) if (connStatusType == CONNECTION_BAD)
{ {
ereport(WARNING, (errmsg("could not maintain connection to worker node"))); ereport(WARNING, (errmsg("could not maintain connection to worker node")));
return CLIENT_BATCH_QUERY_FAILED; return CLIENT_BATCH_QUERY_FAILED;
} }
result = PQgetResult(connection); result = PQgetResult(connection->pgConn);
if (result == NULL) if (result == NULL)
{ {
return CLIENT_BATCH_QUERY_DONE; return CLIENT_BATCH_QUERY_DONE;
@ -537,7 +498,7 @@ MultiClientBatchResult(int32 connectionId, void **queryResult, int *rowCount,
} }
else else
{ {
WarnRemoteError(connection, result); ReportResultError(connection, result, WARNING);
PQclear(result); PQclear(result);
queryStatus = CLIENT_BATCH_QUERY_FAILED; queryStatus = CLIENT_BATCH_QUERY_FAILED;
} }
@ -576,7 +537,7 @@ MultiClientClearResult(void *queryResult)
QueryStatus QueryStatus
MultiClientQueryStatus(int32 connectionId) MultiClientQueryStatus(int32 connectionId)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
PGresult *result = NULL; PGresult *result = NULL;
int tupleCount PG_USED_FOR_ASSERTS_ONLY = 0; int tupleCount PG_USED_FOR_ASSERTS_ONLY = 0;
bool copyResults = false; bool copyResults = false;
@ -588,7 +549,7 @@ MultiClientQueryStatus(int32 connectionId)
connection = ClientConnectionArray[connectionId]; connection = ClientConnectionArray[connectionId];
Assert(connection != NULL); Assert(connection != NULL);
connStatusType = PQstatus(connection); connStatusType = PQstatus(connection->pgConn);
if (connStatusType == CONNECTION_BAD) if (connStatusType == CONNECTION_BAD)
{ {
ereport(WARNING, (errmsg("could not maintain connection to worker node"))); ereport(WARNING, (errmsg("could not maintain connection to worker node")));
@ -600,7 +561,7 @@ MultiClientQueryStatus(int32 connectionId)
* isn't ready yet (the caller didn't wait for the connection to be ready), * isn't ready yet (the caller didn't wait for the connection to be ready),
* we will block on this call. * we will block on this call.
*/ */
result = PQgetResult(connection); result = PQgetResult(connection->pgConn);
resultStatus = PQresultStatus(result); resultStatus = PQresultStatus(result);
if (resultStatus == PGRES_COMMAND_OK) if (resultStatus == PGRES_COMMAND_OK)
@ -631,7 +592,7 @@ MultiClientQueryStatus(int32 connectionId)
copyResults = true; copyResults = true;
} }
WarnRemoteError(connection, result); ReportResultError(connection, result, WARNING);
} }
/* clear the result object */ /* clear the result object */
@ -654,7 +615,7 @@ MultiClientQueryStatus(int32 connectionId)
CopyStatus CopyStatus
MultiClientCopyData(int32 connectionId, int32 fileDescriptor) MultiClientCopyData(int32 connectionId, int32 fileDescriptor)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
char *receiveBuffer = NULL; char *receiveBuffer = NULL;
int consumed = 0; int consumed = 0;
int receiveLength = 0; int receiveLength = 0;
@ -669,7 +630,7 @@ MultiClientCopyData(int32 connectionId, int32 fileDescriptor)
* Consume input to handle the case where previous copy operation might have * Consume input to handle the case where previous copy operation might have
* received zero bytes. * received zero bytes.
*/ */
consumed = PQconsumeInput(connection); consumed = PQconsumeInput(connection->pgConn);
if (consumed == 0) if (consumed == 0)
{ {
ereport(WARNING, (errmsg("could not read data from worker node"))); ereport(WARNING, (errmsg("could not read data from worker node")));
@ -677,7 +638,7 @@ MultiClientCopyData(int32 connectionId, int32 fileDescriptor)
} }
/* receive copy data message in an asynchronous manner */ /* receive copy data message in an asynchronous manner */
receiveLength = PQgetCopyData(connection, &receiveBuffer, asynchronous); receiveLength = PQgetCopyData(connection->pgConn, &receiveBuffer, asynchronous);
while (receiveLength > 0) while (receiveLength > 0)
{ {
/* received copy data; append these data to file */ /* received copy data; append these data to file */
@ -698,7 +659,7 @@ MultiClientCopyData(int32 connectionId, int32 fileDescriptor)
PQfreemem(receiveBuffer); PQfreemem(receiveBuffer);
receiveLength = PQgetCopyData(connection, &receiveBuffer, asynchronous); receiveLength = PQgetCopyData(connection->pgConn, &receiveBuffer, asynchronous);
} }
/* we now check the last received length returned by copy data */ /* we now check the last received length returned by copy data */
@ -710,7 +671,7 @@ MultiClientCopyData(int32 connectionId, int32 fileDescriptor)
else if (receiveLength == -1) else if (receiveLength == -1)
{ {
/* received copy done message */ /* received copy done message */
PGresult *result = PQgetResult(connection); PGresult *result = PQgetResult(connection->pgConn);
ExecStatusType resultStatus = PQresultStatus(result); ExecStatusType resultStatus = PQresultStatus(result);
if (resultStatus == PGRES_COMMAND_OK) if (resultStatus == PGRES_COMMAND_OK)
@ -721,7 +682,7 @@ MultiClientCopyData(int32 connectionId, int32 fileDescriptor)
{ {
copyStatus = CLIENT_COPY_FAILED; copyStatus = CLIENT_COPY_FAILED;
WarnRemoteError(connection, result); ReportResultError(connection, result, WARNING);
} }
PQclear(result); PQclear(result);
@ -731,7 +692,7 @@ MultiClientCopyData(int32 connectionId, int32 fileDescriptor)
/* received an error */ /* received an error */
copyStatus = CLIENT_COPY_FAILED; copyStatus = CLIENT_COPY_FAILED;
WarnRemoteError(connection, NULL); ReportConnectionError(connection, WARNING);
} }
/* if copy out completed, make sure we drain all results from libpq */ /* if copy out completed, make sure we drain all results from libpq */
@ -794,7 +755,7 @@ void
MultiClientRegisterWait(WaitInfo *waitInfo, TaskExecutionStatus executionStatus, MultiClientRegisterWait(WaitInfo *waitInfo, TaskExecutionStatus executionStatus,
int32 connectionId) int32 connectionId)
{ {
PGconn *connection = NULL; MultiConnection *connection = NULL;
struct pollfd *pollfd = NULL; struct pollfd *pollfd = NULL;
Assert(waitInfo->registeredWaiters < waitInfo->maxWaiters); Assert(waitInfo->registeredWaiters < waitInfo->maxWaiters);
@ -812,7 +773,7 @@ MultiClientRegisterWait(WaitInfo *waitInfo, TaskExecutionStatus executionStatus,
connection = ClientConnectionArray[connectionId]; connection = ClientConnectionArray[connectionId];
pollfd = &waitInfo->pollfds[waitInfo->registeredWaiters]; pollfd = &waitInfo->pollfds[waitInfo->registeredWaiters];
pollfd->fd = PQsocket(connection); pollfd->fd = PQsocket(connection->pgConn);
if (executionStatus == TASK_STATUS_SOCKET_READ) if (executionStatus == TASK_STATUS_SOCKET_READ)
{ {
pollfd->events = POLLERR | POLLIN; pollfd->events = POLLERR | POLLIN;
@ -904,13 +865,13 @@ MultiClientWait(WaitInfo *waitInfo)
* query. * query.
*/ */
static void static void
ClearRemainingResults(PGconn *connection) ClearRemainingResults(MultiConnection *connection)
{ {
PGresult *result = PQgetResult(connection); PGresult *result = PQgetResult(connection->pgConn);
while (result != NULL) while (result != NULL)
{ {
PQclear(result); PQclear(result);
result = PQgetResult(connection); result = PQgetResult(connection->pgConn);
} }
} }
@ -921,7 +882,8 @@ ClearRemainingResults(PGconn *connection)
* and libpq_select() at libpqwalreceiver.c. * and libpq_select() at libpqwalreceiver.c.
*/ */
static bool static bool
ClientConnectionReady(PGconn *connection, PostgresPollingStatusType pollingStatus) ClientConnectionReady(MultiConnection *connection,
PostgresPollingStatusType pollingStatus)
{ {
bool clientConnectionReady = false; bool clientConnectionReady = false;
int pollResult = 0; int pollResult = 0;
@ -942,7 +904,7 @@ ClientConnectionReady(PGconn *connection, PostgresPollingStatusType pollingStatu
pollEventMask = POLLERR | POLLOUT; pollEventMask = POLLERR | POLLOUT;
} }
pollFileDescriptor.fd = PQsocket(connection); pollFileDescriptor.fd = PQsocket(connection->pgConn);
pollFileDescriptor.events = pollEventMask; pollFileDescriptor.events = pollEventMask;
pollFileDescriptor.revents = 0; pollFileDescriptor.revents = 0;

View File

@ -15,10 +15,8 @@
#define MULTI_CLIENT_EXECUTOR_H #define MULTI_CLIENT_EXECUTOR_H
#define INVALID_CONNECTION_ID -1 /* identifies an invalid connection */ #define INVALID_CONNECTION_ID -1 /* identifies an invalid connection */
#define CLIENT_CONNECT_TIMEOUT 5 /* connection timeout in seconds */
#define MAX_CONNECTION_COUNT 2048 /* simultaneous client connection count */ #define MAX_CONNECTION_COUNT 2048 /* simultaneous client connection count */
#define STRING_BUFFER_SIZE 1024 /* buffer size for character arrays */ #define STRING_BUFFER_SIZE 1024 /* buffer size for character arrays */
#define CONN_INFO_TEMPLATE "host=%s port=%u dbname=%s user=%s connect_timeout=%u"
/* Enumeration to track one client connection's status */ /* Enumeration to track one client connection's status */