timed PgConnection::Connect

Lists: pgsql-patches
From: Denis A Ustimenko <denis(at)oldham(dot)ru>
To: pgsql-patches(at)postgresql(dot)org
Subject: timed PgConnection::Connect
Date: 2002-08-07 11:20:00
Message-ID: 20020807112000.GA20564@denis.oldham.ru
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Hi, there!

I write this to put timeout parameter in PgConnection::Connect. It is really useful if you need something like that:
try {
write();
}
catch ( const DBError& e) {
timeval timeout;
timeout.tv_sec = reconnectTimeout;
timeout.tv_usec = 0;

while ( ConnectionBad()) {
sleep( reconnectTimeout);
Connect( conninfo.data(), &timeout);
}
}

this is patch for 7.2.1
*********************************************************
*** fe-connect.c.orig Ср Авг 7 17:35:31 2002
--- fe-connect.c Ср Авг 7 16:25:31 2002
***************
*** 173,179 ****


static int connectDBStart(PGconn *conn);
! static int connectDBComplete(PGconn *conn);
static bool PQsetenvStart(PGconn *conn);
static PostgresPollingStatusType PQsetenvPoll(PGconn *conn);
static PGconn *makeEmptyPGconn(void);
--- 173,179 ----


static int connectDBStart(PGconn *conn);
! static int connectDBComplete(PGconn *conn, struct timeval *timeout);
static bool PQsetenvStart(PGconn *conn);
static PostgresPollingStatusType PQsetenvPoll(PGconn *conn);
static PGconn *makeEmptyPGconn(void);
***************
*** 235,244 ****
PGconn *
PQconnectdb(const char *conninfo)
{
PGconn *conn = PQconnectStart(conninfo);

if (conn && conn->status != CONNECTION_BAD)
! (void) connectDBComplete(conn);

return conn;
}
--- 235,250 ----
PGconn *
PQconnectdb(const char *conninfo)
{
+ return PQconnectdbTimed( conninfo, NULL);
+ }
+
+ PGconn *
+ PQconnectdbTimed(const char *conninfo, struct timeval *timeout)
+ {
PGconn *conn = PQconnectStart(conninfo);

if (conn && conn->status != CONNECTION_BAD)
! (void) connectDBComplete(conn, timeout);

return conn;
}
***************
*** 513,519 ****
else
{
if (connectDBStart(conn))
! (void) connectDBComplete(conn);
}

return conn;
--- 519,525 ----
else
{
if (connectDBStart(conn))
! (void) connectDBComplete(conn, NULL);
}

return conn;
***************
*** 1046,1052 ****
* Returns 1 on success, 0 on failure.
*/
static int
! connectDBComplete(PGconn *conn)
{
PostgresPollingStatusType flag = PGRES_POLLING_WRITING;

--- 1052,1058 ----
* Returns 1 on success, 0 on failure.
*/
static int
! connectDBComplete(PGconn *conn, struct timeval *timeout)
{
PostgresPollingStatusType flag = PGRES_POLLING_WRITING;

***************
*** 1069,1075 ****
return 1; /* success! */

case PGRES_POLLING_READING:
! if (pqWait(1, 0, conn))
{
conn->status = CONNECTION_BAD;
return 0;
--- 1075,1081 ----
return 1; /* success! */

case PGRES_POLLING_READING:
! if (pqWaitTimed(1, 0, conn, timeout))
{
conn->status = CONNECTION_BAD;
return 0;
***************
*** 1077,1083 ****
break;

case PGRES_POLLING_WRITING:
! if (pqWait(0, 1, conn))
{
conn->status = CONNECTION_BAD;
return 0;
--- 1083,1089 ----
break;

case PGRES_POLLING_WRITING:
! if (pqWaitTimed(0, 1, conn, timeout))
{
conn->status = CONNECTION_BAD;
return 0;
***************
*** 2026,2032 ****
closePGconn(conn);

if (connectDBStart(conn))
! (void) connectDBComplete(conn);
}
}

--- 2032,2038 ----
closePGconn(conn);

if (connectDBStart(conn))
! (void) connectDBComplete(conn, NULL);
}
}
******************************************************************
*** fe-misc.c.orig Ср Авг 7 17:35:08 2002
--- fe-misc.c Ср Авг 7 16:04:19 2002
***************
*** 748,753 ****
--- 748,759 ----
int
pqWait(int forRead, int forWrite, PGconn *conn)
{
+ return pqWaitTimed( forRead, forWrite, conn, (struct timeval *) NULL);
+ }
+
+ int
+ pqWaitTimed(int forRead, int forWrite, PGconn *conn, struct timeval *timeout)
+ {
fd_set input_mask;
fd_set output_mask;
fd_set except_mask;
***************
*** 770,777 ****
if (forWrite)
FD_SET(conn->sock, &output_mask);
FD_SET(conn->sock, &except_mask);
! if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask,
! (struct timeval *) NULL) < 0)
{
if (SOCK_ERRNO == EINTR)
goto retry;
--- 776,783 ----
if (forWrite)
FD_SET(conn->sock, &output_mask);
FD_SET(conn->sock, &except_mask);
! if (select(conn->sock + 1, &input_mask, &output_mask,
! &except_mask, timeout) < 0)
{
if (SOCK_ERRNO == EINTR)
goto retry;
******************************************************************
*** libpq-fe.h.orig Ср Авг 7 17:36:03 2002
--- libpq-fe.h Ср Авг 7 16:20:54 2002
***************
*** 185,190 ****
--- 185,191 ----

/* Synchronous (blocking) */
extern PGconn *PQconnectdb(const char *conninfo);
+ extern PGconn *PQconnectdbTimed(const char *conninfo, struct timeval *timeout);
extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport,
const char *pgoptions, const char *pgtty,
const char *dbName,
******************************************************************
*** libpq-int.h.orig Ср Авг 7 17:36:46 2002
--- libpq-int.h Ср Авг 7 15:55:26 2002
***************
*** 324,329 ****
--- 324,330 ----
extern int pqReadData(PGconn *conn);
extern int pqFlush(PGconn *conn);
extern int pqWait(int forRead, int forWrite, PGconn *conn);
+ extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn, struct timeval* timeout);
extern int pqReadReady(PGconn *conn);
extern int pqWriteReady(PGconn *conn);

******************************************************************
*** ../libpq++/pgconnection.cc.orig Ср Авг 7 17:38:01 2002
--- ../libpq++/pgconnection.cc Ср Авг 7 16:35:24 2002
***************
*** 68,83 ****
}
}

-
// PgConnection::connect
// establish a connection to a backend
! ConnStatusType PgConnection::Connect(const char conninfo[])
{
// if the connection is open, close it first
CloseConnection();

// Connect to the database
! pgConn = PQconnectdb(conninfo);

// Now we have a connection we must close (even if it's bad!)
pgCloseConnection = true;
--- 68,82 ----
}
}

// PgConnection::connect
// establish a connection to a backend
! ConnStatusType PgConnection::Connect(const char conninfo[], timeval const *const timeout)
{
// if the connection is open, close it first
CloseConnection();

// Connect to the database
! pgConn = PQconnectdbTimed(conninfo, const_cast<timeval *const timeout>(timeout));

// Now we have a connection we must close (even if it's bad!)
pgCloseConnection = true;
******************************************************************
*** ../libpq++/pgconnection.h.orig Ср Авг 7 17:38:11 2002
--- ../libpq++/pgconnection.h Ср Авг 7 16:32:47 2002
***************
*** 81,87 ****
PGnotify* Notifies();

protected:
! ConnStatusType Connect(const char* conninfo);
void CloseConnection();
static PGSTD string IntToString(int);
// Default constructor is only available to subclasses
--- 81,87 ----
PGnotify* Notifies();

protected:
! ConnStatusType Connect(const char* conninfo, timeval const *const timeout = NULL);
void CloseConnection();
static PGSTD string IntToString(int);
// Default constructor is only available to subclasses

--
Regards
Denis


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Denis A Ustimenko <denis(at)oldham(dot)ru>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: timed PgConnection::Connect
Date: 2002-08-07 13:52:05
Message-ID: 15216.1028728325@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Denis A Ustimenko <denis(at)oldham(dot)ru> writes:
> I write this to put timeout parameter in PgConnection::Connect.

This patch seems really messy. In the first place, the timeout isn't on
total connection delay, but on individual waits of which there will be
several. I'd think that's not really what you want. In the second
place, I'd expect a timeout to be specified as a new optional parameter
in connection strings, not as an ad-hoc additional parameter in the API.

regards, tom lane


From: Denis A Ustimenko <denis(at)oldham(dot)ru>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: timed PgConnection::Connect
Date: 2002-08-09 09:48:57
Message-ID: 20020809094857.GB1210@denis.oldham.ru
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Hi!

Here is rewrited version. Time out can be specified as "connect_timeout" parameter. API hadn't changed.

On Wed, Aug 07, 2002 at 09:52:05AM -0400, Tom Lane wrote:
> Denis A Ustimenko <denis(at)oldham(dot)ru> writes:
> > I write this to put timeout parameter in PgConnection::Connect.
>
> This patch seems really messy. In the first place, the timeout isn't on
> total connection delay, but on individual waits of which there will be
> several. I'd think that's not really what you want. In the second
> place, I'd expect a timeout to be specified as a new optional parameter
> in connection strings, not as an ad-hoc additional parameter in the API.
>
> regards, tom lane

--
Regards
Denis

Attachment Content-Type Size
postgres-7.2.1-TIMED_CONNECT.patch text/plain 6.6 KB