From: | Raimon Fernandez <coder(at)montx(dot)com> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | pgsql-general List <pgsql-general(at)postgresql(dot)org> |
Subject: | Re: libpq ASYNC with PQgetResult and PQisBusy |
Date: | 2010-12-20 20:49:35 |
Message-ID: | 2C5CFB1E-FAAA-4CFD-A7F2-1DFBCD194010@montx.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On 20dic, 2010, at 18:48 , Tom Lane wrote:
>> So, now I'm using the PQisBusy to check if postgre is still busy and I can safely call the PQgetResult wihtout blocking, or just wait *some time* before sending a new PQisBusy.
>
> Your proposed code is still a busy-wait loop.
This is how are made all the examples I've found.
Last year I was implementing the FE/BE protocol v3 and there I was using what you proposed, a TCP/Socket with events, no loops and no waits, just events.
> What you should be doing is waiting for some data to arrive on the socket.
where I have to wait, in a function inside my plugin or from the framework that uses my plugin ?
> Once you see
> read-ready on the socket, call PQconsumeInput, then check PQisBusy to
> see if the query is complete or not. If not, go back to waiting on the
> socket. Typically you'd use select() or poll() to watch for both data
> on libpq's socket and whatever other events your app is interested in.
Here is what I've found:
extern int PQsocket(const PGconn *conn);
There are some examples in the postgreSQL documentation:
/*
* Sleep untilsomething happens on the connection. We use select(2)
* to wait for input, but you could also use poll() or similar
* facilities.
*/
int sock;
fd_set input_mask;
sock = PQsocket(conn);
if (sock < 0) break; /* shouldn’t happen */
FD_ZERO(&input_mask);
FD_SET(sock, &input_mask);
if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0) {
fprintf(stderr, "select() failed: %s\n", strerror(errno));
exit_nicely(conn);
}
/* Now check for input */
PQconsumeInput(conn);
while ((notify = PQnotifies(conn)) != NULL) {
fprintf(stderr, "ASYNC NOTIFY of ’%s’ received from backend pid %d\n", notify->relname, notify->be_pid);
PQfreemem(notify);
}
The select(2) that says that are using for wait is this line ? if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0) {
I can't see where is 'sleeping'
and the approach you are refering, is the only way to non-block the plugin calls and postgreSQL ?
>> here is my montxPG_isBusy
>
>> static long montxPG_isBusy()
>
>> { int execStatus;
>> int consumeeVar;
>
>> consumeeVar = PQconsumeInput(gPGconn);
>
>> if (consumeeVar == 0) return (long) PGRES_FATAL_ERROR;
>
>> execStatus = PQisBusy(gPGconn);
>
>> return (long) execStatus;
>
>> }
>
> This code seems a bit confused. PQisBusy returns a bool (1/0), not a
> value of ExecStatusType.
yes, here the execStatus is the name of the int, and yes, I know, a bad name ...
thanks again,
regards,
r.
From | Date | Subject | |
---|---|---|---|
Next Message | Kenneth Buckler | 2010-12-20 21:05:15 | Re: PostgreSQL Trusted Startup |
Previous Message | Scott Marlowe | 2010-12-20 20:48:25 | Re: PostgreSQL Trusted Startup |