Problem Using PQcancel in a Synchronous Query

Started by Eric Simonover 15 years ago3 messageshackers
Jump to latest
#1Eric Simon
esimon@theiqgroup.com

Hi,

I am using Perl (DBD::Pg) with Postgres. DBD::Pg already fully supports
asynchronous queries, and the canceling of those queries, but I need to
cancel a synchronous query. So to do that, I am trying to write
$sth->cancel() support for DBD::Pg. Here's my example in Perl:

my $aborted = 0;
my $action = POSIX::SigAction->new(
sub {$sth->cancel; $aborted = 1},
POSIX::SigSet->new(SIGALRM)
);
my $oldaction = POSIX::SigAction->new;
POSIX::sigaction(SIGALRM,$action,$oldaction);

my $sth = $dbh->prepare('SELECT id FROM user_session FOR UPDATE');
alarm(10); # wait 10 seconds before time out
$sth->execute;
alarm(0); # cancel alarm (if execute worked fast)

POSIX::sigaction(SIGALRM,$oldaction); # restore original handler
warn "warning: query timed out" if $aborted;

Now that I've established some context, here's where I'm at: I've written
$sth->cancel() for DBD::Pg using PQcancel(), and it works (it returns the
status 57014: QUERY CANCELED). The problem is that the $sth->execute call
(which resides between the two alarm() calls above) doesn't continue on, but
rather stays frozen, waiting for data. Does PQcancel not communicate back
to the execute statement so that it unblocks?

--
Eric Simon
The IQ Group, Inc.

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Eric Simon (#1)
Re: Problem Using PQcancel in a Synchronous Query

"Eric Simon" <esimon@theiqgroup.com> writes:

Now that I've established some context, here's where I'm at: I've written
$sth->cancel() for DBD::Pg using PQcancel(), and it works (it returns the
status 57014: QUERY CANCELED). The problem is that the $sth->execute call
(which resides between the two alarm() calls above) doesn't continue on, but
rather stays frozen, waiting for data. Does PQcancel not communicate back
to the execute statement so that it unblocks?

Um ... PQcancel returns no such thing, only true or false. I'm guessing
you've coded your signal handler in such a way that it eats the query
result message intended for the mainline execute code. You should not
be calling anything except PQcancel itself in the signal handler.

regards, tom lane

#3Eric Simon
esimon@theiqgroup.com
In reply to: Tom Lane (#2)
Re: Problem Using PQcancel in a Synchronous Query

Tom,

That was it! My implementation of cancel() was swallowing the result
message. Thanks so much, I've got it working now.

--
Eric Simon
The IQ Group, Inc.

-----Original Message-----
From: pgsql-hackers-owner@postgresql.org
[mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of Tom Lane
Sent: Monday, August 23, 2010 7:06 PM
To: Eric Simon
Cc: pgsql-hackers@postgresql.org
Subject: Re: [HACKERS] Problem Using PQcancel in a Synchronous Query

"Eric Simon" <esimon@theiqgroup.com> writes:

Now that I've established some context, here's where I'm at: I've written
$sth->cancel() for DBD::Pg using PQcancel(), and it works (it returns the
status 57014: QUERY CANCELED). The problem is that the $sth->execute call
(which resides between the two alarm() calls above) doesn't continue on,

but

rather stays frozen, waiting for data. Does PQcancel not communicate back
to the execute statement so that it unblocks?

Um ... PQcancel returns no such thing, only true or false. I'm guessing
you've coded your signal handler in such a way that it eats the query
result message intended for the mainline execute code. You should not
be calling anything except PQcancel itself in the signal handler.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers