Thread: Asynchronous interface help?

Asynchronous interface help?

From
Adam Haberlach
Date:
I'm working on using PostgreSQL to synchronize two seperate web connections
for some silly authentication reasons.  I'm adding a method to PHP that will
allow the generation of a page to wait on a named notify from another
backend process.  It doesn't seem to work correctly.  Here's the abridged
version of the code...

PHP_FUNCTION(pg_wait) {   zval **timeout, **pgsql_link;   int id = -1;   fd_set rfds;   int retval;   PGconn *pgsql;
PGnotify*notify;   struct timeval tv;   char *buf;   int nbytes;   int trycount=0;
 
/* ... */
   ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink);
convert_to_long_ex(timeout);
   FD_ZERO(&rfds);   FD_SET(PQsocket(pgsql), &rfds);
   tv.tv_sec = Z_STRVAL_PP(timeout);   tv.tv_usec = 0;
   retval = select(1, &rfds, NULL, NULL, &tv);   if(retval) {       PQconsumeInput(pgsql);       notify =
PQnotifies(pgsql);      if(notify) {           nbytes = strlen(notify->relname)+1;           buf = emalloc(nbytes);
     memcpy(buf, notify->relname, nbytes);           free(notify);
 
    /* ... */
       }   } else {       printf("Timed out.  Socket==%d\n", PQsocket(pgsql));       RETURN_FALSE;   }

This always seems to time out.  Is there some mode that I need to put
the backend into in order to make the socket valid?  I'm getting a
non-stdio/stdout/stderr value back from PQsocket, so things can't be
too messed up.

The following code seems to work, but polls--we would much rather
block on select().
   while(trycount < Z_STRVAL_PP(timeout)) {       PQconsumeInput(pgsql);       notify = PQnotifies(pgsql);
if(notify){           nbytes = strlen(notify->relname)+1;           buf = emalloc(nbytes);           memcpy(buf,
notify->relname,nbytes);           free(notify);
 
    /* ... */       }       sleep(1);       trycount++;   }


Anyone have any ideas?

-- 
Adam Haberlach            |A cat spends her life conflicted between a
adam@newsnipple.com       |deep, passionate, and profound desire for
http://www.newsnipple.com |fish and an equally deep, passionate, and
'88 EX500                 |profound desire to avoid getting wet.


Re: Asynchronous interface help?

From
Tom Lane
Date:
Adam Haberlach <adam@newsnipple.com> writes:
> This always seems to time out.  Is there some mode that I need to put
> the backend into in order to make the socket valid?

It seems like there should be a loop around the
select/consumeinput/notifies sequence, but perhaps that's provided
outside the pqwait() function?  As it stands, you're assuming that
the first data delivered will be the notify you want.

Another possible problem is if you are expecting this to fire within
a transaction block.  Notifications are only delivered outside of
transactions.
        regards, tom lane


Re: Asynchronous interface help?

From
Paul Breen
Date:
Hello Adam,

Sorry for the late reply, Christmas and all that...

I notice in your code snippet that the call to 'select()' is:

>     retval = select(1, &rfds, NULL, NULL, &tv);

Well, the 1st parameter to select is the highest file descriptor in any of
the fd sets + 1 NOT the number of file descriptors to check.  What you're
saying here is check fd 0 (1 == 0 + 1) which is 'stdin' !  Not what you're
after I believe?  To check your connection's socket you need:
select(PQsocket(pgsql) + 1, &rfds, NULL, NULL, &tv);

as the 1st parameter.  This gives the socket fd number + 1!

Hope this helps.


Paul M. Breen, Software Engineer - Computer Park Ltd.

Tel:   (01536) 417155
Email: pbreen@computerpark.co.uk

On Tue, 2 Jan 2001, Adam Haberlach wrote:

> I'm working on using PostgreSQL to synchronize two seperate web connections
> for some silly authentication reasons.  I'm adding a method to PHP that will
> allow the generation of a page to wait on a named notify from another
> backend process.  It doesn't seem to work correctly.  Here's the abridged
> version of the code...
> 
> PHP_FUNCTION(pg_wait) {
>     zval **timeout, **pgsql_link;
>     int id = -1;
>     fd_set rfds;
>     int retval;
>     PGconn *pgsql;
>     PGnotify *notify;
>     struct timeval tv;
>     char *buf;
>     int nbytes;
>     int trycount=0;
> 
>     /* ... */
> 
>     ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink);
>     convert_to_long_ex(timeout);
> 
>     FD_ZERO(&rfds);
>     FD_SET(PQsocket(pgsql), &rfds);
> 
>     tv.tv_sec = Z_STRVAL_PP(timeout);
>     tv.tv_usec = 0;
> 
>     retval = select(1, &rfds, NULL, NULL, &tv);
>     if(retval) {
>         PQconsumeInput(pgsql);
>         notify = PQnotifies(pgsql);
>         if(notify) {
>             nbytes = strlen(notify->relname)+1;
>             buf = emalloc(nbytes);
>             memcpy(buf, notify->relname, nbytes);
>             free(notify);
> 
>         /* ... */
> 
>         }
>     } else {
>         printf("Timed out.  Socket==%d\n", PQsocket(pgsql));
>         RETURN_FALSE;
>     }
> 
> This always seems to time out.  Is there some mode that I need to put
> the backend into in order to make the socket valid?  I'm getting a
> non-stdio/stdout/stderr value back from PQsocket, so things can't be
> too messed up.
> 
> The following code seems to work, but polls--we would much rather
> block on select().
> 
>     while(trycount < Z_STRVAL_PP(timeout)) {
>         PQconsumeInput(pgsql);
>         notify = PQnotifies(pgsql);
>         if(notify) {
>             nbytes = strlen(notify->relname)+1;
>             buf = emalloc(nbytes);
>             memcpy(buf, notify->relname, nbytes);
>             free(notify);
> 
>         /* ... */
>         }
>         sleep(1);
>         trycount++;
>     }
> 
> 
> Anyone have any ideas?
> 
> -- 
> Adam Haberlach            |A cat spends her life conflicted between a
> adam@newsnipple.com       |deep, passionate, and profound desire for
> http://www.newsnipple.com |fish and an equally deep, passionate, and
> '88 EX500                 |profound desire to avoid getting wet.
>