timed PgConnection::Connect

Started by Denis A Ustimenkoalmost 24 years ago3 messagespatches
Jump to latest
#1Denis A Ustimenko
denis@oldham.ru

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

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Denis A Ustimenko (#1)
Re: timed PgConnection::Connect

Denis A Ustimenko <denis@oldham.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

#3Denis A Ustimenko
denis@oldham.ru
In reply to: Tom Lane (#2)
Re: timed PgConnection::Connect

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@oldham.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

Attachments:

postgres-7.2.1-TIMED_CONNECT.patchtext/plain; charset=koi8-rDownload+56-10