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.

Reply via email to