--- Coro-Mysql/Mysql.pm 2010/08/31 14:42:28 1.5 +++ Coro-Mysql/Mysql.pm 2011/02/17 02:06:55 1.10 @@ -22,8 +22,9 @@ =head2 CAVEAT -Note that this module must be linked against exactly the same -F library as DBD::mysql, otherwise it will not work. +Note that this module must be linked against exactly the same (shared, +possibly not working with all OSes) F library as +DBD::mysql, otherwise it will not work. Also, while this module makes database handles non-blocking, you still cannot run multiple requests in parallel on the same database handle. If @@ -35,8 +36,8 @@ can freely share the database handles between threads, of course. Also, this module uses a number of "unclean" techniques (patching an -internal libmysql structure for one thing) and was hacked within a few -hours on a long flight to Malaysia. +internal libmysql structure for one thing) and was initially hacked within +a few hours on a long flight to Malaysia. It does, however, check whether it indeed got the structure layout correct, so you should expect perl exceptions or early crashes as opposed @@ -46,13 +47,16 @@ This module is implemented in XS, and as long as mysqld replies quickly enough, it adds no overhead to the standard libmysql communication -routines (which are very badly written, btw.). +routines (which are very badly written, btw.). In fact, since it has a +more efficient buffering and allows requests to run in parallel, it often +decreases the actual time to run many queries considerably. For very fast queries ("select 0"), this module can add noticable overhead -(around 15%) as it tries to switch to other coroutines when mysqld doesn't -deliver the data instantly. +(around 15%, 7% when EV can be used) as it tries to switch to other +coroutines when mysqld doesn't deliver the data immediately, although, +again, when running queries in parallel, they will usually execute faster. -For most types of queries, there will be no overhead, especially on +For most types of queries, there will be no extra latency, especially on multicore systems where your perl process can do other things while mysqld does its stuff. @@ -63,6 +67,13 @@ pipes (windows) and shared memory (also windows). No support for these connection types is planned, either. +=head1 CANCELLATION + +Cancelling a thread that is within a mysql query will likely make the +handle unusable. As far as Coro::Mysql is concerned, the handle can be +safely destroyed, but it's not clear how mysql itself will react to a +cancellation. + =head1 FUNCTIONS Coro::Mysql offers a single user-accessible function: @@ -80,7 +91,9 @@ use Carp qw(croak); use Guard; -use Coro::Handle (); +use AnyEvent (); +use Coro (); +use Coro::AnyEvent (); # not necessary with newer Coro versions # we need this extra indirection, as Coro doesn't support # calling SLF-like functions via call_sv. @@ -89,7 +102,7 @@ sub writable { &Coro::Handle::FH::writable } BEGIN { - our $VERSION = '1.01'; + our $VERSION = '1.02'; require XSLoader; XSLoader::load Coro::Mysql::, $VERSION; @@ -108,18 +121,26 @@ returned unchanged. That means it is harmless when applied to database handles of other databases. +It is also safe to pass C, so code like this is works as expected: + + my $dbh = DBI->connect ($database, $user, $pass)->Coro::Mysql::unblock + or die $DBI::errstr; + =cut sub unblock { my ($DBH) = @_; - if ($DBH->{Driver}{Name} eq "mysql") { + if ($DBH && $DBH->{Driver}{Name} eq "mysql") { my $sock = $DBH->{sock}; open my $fh, "+>&" . $DBH->{sockfd} or croak "Coro::Mysql unable to clone mysql fd"; - $fh = Coro::Handle::unblock $fh; + if (AnyEvent::detect ne "AnyEvent::Impl::EV" || !_use_ev) { + require Coro::Handle; + $fh = Coro::Handle::unblock ($fh); + } _patch $sock, $DBH->{sockfd}, $fh, tied ${$fh}; } @@ -146,7 +167,7 @@ sub with_db($$$&) { my ($database, $user, $pass, $cb) = @_; - my $dbh = Coro::Mysql::unblock DBI->connect ($database, $user, $pass) + my $dbh = DBI->connect ($database, $user, $pass)->Coro::Mysql::unblock or die $DBI::errstr; Coro::on_enter { $PApp::SQL::DBH = $dbh };