Re: [GENERAL] LISTEN/NOTIFY problem

2009-03-24 Thread Dmitri Girski
Thank you guys for your replies!

It is definitely something wrong with my code, here is the thread which does
the listening:
http://mitek.id.au/flex/DBListener.cpp

The rest of application is fairly big and does not relate to the database.
For libpq calls I am using the SPTK (http://sptk.net) library. I've added
additional wrappers for PGsocket, PQfreemem.

So the current code works without any problem, but as soon as I remove
subcribe() function from the loop and call it just once, daemon eventually
will stop getting notifications.
There is nothing wrong with the socket or db connections - all possible
error will be logged.


Cheers,
Dmitri.


On Mon, Mar 23, 2009 at 10:00 PM, Dmitri Girski mi...@lizardsw.com wrote:

 Hi everybody,
 I've got a weird problem with LISTEN/NOTIFY.

 My C++ app subscribes for the notifications, just like in libpq examples:
 http://www.postgresql.org/docs/8.3/static/libpq-example.html

 The only difference, that I am setting the timeout on select just to check
 if application wants to exit.

 //open session

 //subscribe

 while(!exit)
 {
 sock = PGsocket(conn)

 res = select(sock);

 if (res)

//check if it timeout
//or if there was a notification


 }

 The problem that I am facing is that after some time notifications stop
 coming.
 select() returns on timeout and nothing else.

 Just as a test a included UNLISTEN/LISTEN sequence into the loop, so after
 timeout or event application re-subscribes. And this helps.

 The question is, what I am doing wrong with the code in the first place?

 Any help is appreciated.

 Cheers,
 Dmitri.










 --
 @Gmail




-- 
@Gmail


[GENERAL] LISTEN/NOTIFY problem

2009-03-23 Thread Dmitri Girski
Hi everybody,
I've got a weird problem with LISTEN/NOTIFY.

My C++ app subscribes for the notifications, just like in libpq examples:
http://www.postgresql.org/docs/8.3/static/libpq-example.html

The only difference, that I am setting the timeout on select just to check
if application wants to exit.

//open session

//subscribe

while(!exit)
{
sock = PGsocket(conn)

res = select(sock);

if (res)

   //check if it timeout
   //or if there was a notification


}

The problem that I am facing is that after some time notifications stop
coming.
select() returns on timeout and nothing else.

Just as a test a included UNLISTEN/LISTEN sequence into the loop, so after
timeout or event application re-subscribes. And this helps.

The question is, what I am doing wrong with the code in the first place?

Any help is appreciated.

Cheers,
Dmitri.










-- 
@Gmail


Re: [GENERAL] LISTEN/NOTIFY problem

2009-03-23 Thread Harvey, Allan AC
 

-Original Message-
From: pgsql-general-ow...@postgresql.org 
[mailto:pgsql-general-ow...@postgresql.org]on Behalf Of Dmitri Girski
Sent: Monday, 23 March 2009 10:00 PM
To: pgsql-general@postgresql.org
Subject: [GENERAL] LISTEN/NOTIFY problem


Hi everybody, 

I've got a weird problem with LISTEN/NOTIFY.

My C++ app subscribes for the notifications, just like in libpq examples:
http://www.postgresql.org/docs/8.3/static/libpq-example.html

The only difference, that I am setting the timeout on select just to check if 
application wants to exit.

//open session

//subscribe

while(!exit)
{
sock = PGsocket(conn)
 
res = select(sock);

if (res)

   //check if it timeout
   //or if there was a notification


}

The problem that I am facing is that after some time notifications stop coming.
select() returns on timeout and nothing else.


Just as a test a included UNLISTEN/LISTEN sequence into the loop, so after 
timeout or event application re-subscribes. And this helps.

The question is, what I am doing wrong with the code in the first place?

Any help is appreciated.

Cheers,
Dmitri.











-- 
@Gmail
 

Cannot tell what is wrong with you piece of code.
But below is a routine I use for notifications.
No problems with it so far.
 
Hope it helps.
 
Allan
 
 /*
** Structure to hold the connection data
*/
typedef struct _condetails
{
char *pghost;
char *pgport;
char *pgoptions;
char *pgtty;
char *dbname;
char *pguser;
char *pgpswd;
PGconn *conn;
int bpid;
} CONDETAILS;
 
 
/*
** Register for a database notification
*/
int reg_notification( CONDETAILS *cd, const char *notif )
{
char *sqlnotify, sql[128];
PGconn* conn;
PGresult* res;
 
conn = cd-conn;
 
sqlnotify = listen %s;
 
/* 
** check to see that the backend connection was successfully made
*/
if ( PQstatus( conn ) == CONNECTION_BAD )
{
sysErr( reg_notification(). %s, PQerrorMessage( conn ) );
PQfinish( conn );
condetails( cd );
return -1;
}
 
/*
** Register
*/
sprintf( sql, sqlnotify, notif );
res = PQexec( conn, sql );
if ( PQresultStatus( res ) != PGRES_COMMAND_OK )
{
sysErr( reg_notification(). listen command failed. %s, 
PQerrorMessage( conn ) );
PQclear( res );
return -1;
}
 
PQclear( res );
 
return 0;
}

/*
** Wait for a database notification or time out
** This is an async method.
**
** Return only the first notification not generated by me
** and flush the rest.
**
** Probly should do something smarter.
*/
int wait_db_notification( CONDETAILS *cd, char *notif, const long sec, const 
long usec )
{
int sock, ret;
fd_set input_mask;
PGconn* conn;
PGnotify *notify;
struct timeval timeout;
 
conn = cd-conn;
 
/* 
** check to see that the backend connection was successfully made
*/
if ( PQstatus( conn ) == CONNECTION_BAD )
{
sysErr( wait_db_notification(). %s, PQerrorMessage( conn ) );
PQfinish( conn );
condetails( cd );
return -1;
}
 
sock = PQsocket( conn );
if ( sock  0 )
{
sysErr( wait_db_notification(). Could not get socket 
descriptor. %s, PQerrorMessage( conn ) );
return -1;
}
 
FD_ZERO( input_mask );
FD_SET( sock, input_mask );
timeout.tv_sec = sec;
timeout.tv_usec = usec;
 
ret = select( sock + 1, input_mask, NULL, NULL, timeout );
if ( ret  0 )
{
sysErr( %d: %s, __LINE__, wait_db_notification(). Select on 
db socket failed );
 
if ( errno != EINTR )
exit( 1 );
 
/*
** Been interrupted by a trappable signal
** Force going to the top of the loop to handle it.
-*/
return -1;
}
if ( ret == 0 )
{
/*
** Time out occurred.
*/
return 0;
}
 
/*
** Some activity on the db
*/
ret = -1;
PQconsumeInput( conn );
do
{
notify = PQnotifies( conn );
if ( notify != NULL )
{
if ( cd-bpid != notify-be_pid )
{
strcpy( notif, notify-relname );
ret = 1