On Fri, Jan 16, 2009 at 05:43:36AM +0100, Marc Lehmann wrote:
> On Thu, Jan 15, 2009 at 10:01:32PM +0000, Tim Bunce <[email protected]> 
> wrote:
> > Marc, what would need to be added to the DBI (or DBD::Gofer) to support
> > asynchronous use via the Coro module?

Extra question: can Coro work when there's XS code in the class stack?
In terms of the DBI, the driver code gets called by the DBI method
dispatch code, which is implemented in XS.

If the answer is no then it's not a show-stopper so long as users are
happy to use DBI::PurePerl.

> Method 1, add hooks to DBD::Gofer:
> 
> Right now, the only sensible way to go is to use DBD::Gofer and add some
> hooks. Basically, each time you block, e.g. in select or read (or write,
> if pipelining is to be an option), you need to use some event mechanism
> to wait.
> 
> There are many ways to achieve that. Coro has an optional (slowish) wrapper
> around "select", so instead of doing:
> 
>    print $fh $data;
> 
> You could do:
> 
>    select .... $fh writable; # slightly messy
>    print $fh $data;


> Method 2: use unblock or subclass:
> 
> Another option is to let the user optionally modify the filehandle, e.g.
> in addition to:
> 
>    nonblock($rfh);
> 
> one could do:
> 
>    $rfh = $user_callback_to_condition_fh->($rfh)
> 
> and the user callback could be:
> 
>    sub { Coro::Handle::unblock $_[0] }
> 
> "unblock" returns something that acts like a perl file handle on the perl
> level, but allows other coroutines to schedule when blocking on it.
> 
> Yet another option would be to write a DBD::Gofer::Transport::corostream
> which would hardcode the above. It probably should be part of the Coro
> module itself (and was on my todo list). Now that I looked at it, it might
> be as trivial as subclassing ::stream and overriding start_pipe_command.

Great. Want to give it a try? (I've no time myself.)

> The only added complexity is that DBD::Gofer suddenly might receive two
> concurrent requests on the same backend - this would not work without some
> synchronisation, but a simple "workaround" would be to simply disallow
> that, i.e. "you must not make concurrent calls on the same gofer object
> without locking yourself", which, in my experience, is enough.

To avoid reentrancy, ok. Would be easy to add.

Tim.

Reply via email to