Martin J. Evans wrote:
>
>>Since I'm going to need to implement some support
>>for it in DBIx::Threaded soon, I thought I'd stir up the
>>hornets nest (tho only briefly).
>>
>>After reviewing this thread:
>>
>>http://www.mail-archive.com/[email protected]/msg03408.html
>>
Dean,
I somehow missed the thread you refer to.
ODBC does support asynchronous mode and the following summary may help:
Asynchrous mode is controlled using the connection or statement level attribute
SQL_ATTR_ASYNC_ENABLE - which may be set to SQL_ASYNC_ENABLE_OFF or
SQL_ASYNC_ENABLE_ON.
<snip>
I know ODBC provides an async i/f (as do many/most native
DBMS client libs). The issue is whether any DBD's expose those i/f's.
As for DBD::ODBC odbc_async_exec does enable asynchronous mode (if the driver
returns SQL_AM_STATEMENT) but it was added as a way of obtaining messages from
procedures rather than supporting full asynchronous mode. i.e. When DBD::ODBC
turns asynchronous mode on it loops on any function returning
SQL_STILL_EXECUTING attempting to retrieve any diagnostics each loop. It does
not return back to DBI. I think there is a test in the test suite which does
this.
Understood, hence my comments in my original post.
My primary need is for support of async cancel/abort of in-progress
queries. While DBI defines a $sth->cancel() i/f, it's only useful
to either "cut-off" results of a query before results have been
fully consumed, or in the context of signal handling, which will likely
adversely impact DBIx::Threaded (and many DBD's, for that matter).
In a fully threaded environment, it may be useful to be able to cancel
in-progress queries. E.g.,
Client app:
my $dbh = DBIx::Threaded->connect($dsn, $user, $pass);
my $reqid = $dbh->dbix_threaded_start($long_running_sql);
#
# do some other stuff, then...
#
my $results = $dbh->dbix_threaded_wait_until($id, $timeout);
#
# we timed out
#
$dbh->dbix_threaded_cancel($id)
unless $results;
#=====================================
In DBIx::Threaded (client side):
sub DBIx::Threaded::db::dbix_threaded_cancel {
my ($self, $id) = @_;
$self->{_cmdq}->mark($id, 'CANCEL');
return $self;
}
#=====================================
In DBIx::Threaded::Server :
A Helper class must be defined to support true
async execution; said helper class implements
a "start()" method which starts execution, but
occasionally polls the Thread::Queue::Duplex request
to determine if its been cancelled:
while (! $done) {
$rc = $driverif->wait($timeout);
last if $rc;
if ($self->{_cmdq}->marked($reqid, 'CANCEL')) {
$driverif->cancel(); # no reply to this
$self->{_cmdq}->unmark($reqid);
}
}
_END_
FWIW: Said helper class will also provide a std. more_results()
wrapper i/f for those DBD's that support same.
Dean Arnold
Presicient Corp.