ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro-Mysql/Mysql.pm
(Generate patch)

Comparing Coro-Mysql/Mysql.pm (file contents):
Revision 1.6 by root, Wed Sep 1 16:38:07 2010 UTC vs.
Revision 1.9 by root, Thu Feb 17 02:05:14 2011 UTC

20This can be used to make parallel sql requests using Coro, or to do other 20This can be used to make parallel sql requests using Coro, or to do other
21stuff while mysql is rumbling in the background. 21stuff while mysql is rumbling in the background.
22 22
23=head2 CAVEAT 23=head2 CAVEAT
24 24
25Note that this module must be linked against exactly the same 25Note that this module must be linked against exactly the same (shared,
26F<libmysqlclient> library as DBD::mysql, otherwise it will not work. 26possibly not working with all OSes) F<libmysqlclient> library as
27DBD::mysql, otherwise it will not work.
27 28
28Also, while this module makes database handles non-blocking, you still 29Also, while this module makes database handles non-blocking, you still
29cannot run multiple requests in parallel on the same database handle. If 30cannot run multiple requests in parallel on the same database handle. If
30you want to run multiple queries in parallel, you have to create multiple 31you want to run multiple queries in parallel, you have to create multiple
31database connections, one for each thread that runs queries. Not doing so 32database connections, one for each thread that runs queries. Not doing so
33 34
34If you make sure that you never run two or more requests in parallel, you 35If you make sure that you never run two or more requests in parallel, you
35can freely share the database handles between threads, of course. 36can freely share the database handles between threads, of course.
36 37
37Also, this module uses a number of "unclean" techniques (patching an 38Also, this module uses a number of "unclean" techniques (patching an
38internal libmysql structure for one thing) and was hacked within a few 39internal libmysql structure for one thing) and was initially hacked within
39hours on a long flight to Malaysia. 40a few hours on a long flight to Malaysia.
40 41
41It does, however, check whether it indeed got the structure layout 42It does, however, check whether it indeed got the structure layout
42correct, so you should expect perl exceptions or early crashes as opposed 43correct, so you should expect perl exceptions or early crashes as opposed
43to data corruption when something goes wrong during patching. 44to data corruption when something goes wrong during patching.
44 45
45=head2 SPEED 46=head2 SPEED
46 47
47This module is implemented in XS, and as long as mysqld replies quickly 48This module is implemented in XS, and as long as mysqld replies quickly
48enough, it adds no overhead to the standard libmysql communication 49enough, it adds no overhead to the standard libmysql communication
49routines (which are very badly written, btw.). 50routines (which are very badly written, btw.). In fact, since it has a
51more efficient buffering and allows requests to run in parallel, it often
52decreases the actual time to run many queries considerably.
50 53
51For very fast queries ("select 0"), this module can add noticable overhead 54For very fast queries ("select 0"), this module can add noticable overhead
52(around 15%) as it tries to switch to other coroutines when mysqld doesn't 55(around 15%, 7% when EV can be used) as it tries to switch to other
53deliver the data instantly. 56coroutines when mysqld doesn't deliver the data immediately, although,
57again, when running queries in parallel, they will usually execute faster.
54 58
55For most types of queries, there will be no overhead, especially on 59For most types of queries, there will be no extra latency, especially on
56multicore systems where your perl process can do other things while mysqld 60multicore systems where your perl process can do other things while mysqld
57does its stuff. 61does its stuff.
58 62
59=head2 LIMITATIONS 63=head2 LIMITATIONS
60 64
61This module only supports "standard" mysql connection handles - this 65This module only supports "standard" mysql connection handles - this
62means unix domain or TCP sockets, and excludes SSL/TLS connections, named 66means unix domain or TCP sockets, and excludes SSL/TLS connections, named
63pipes (windows) and shared memory (also windows). No support for these 67pipes (windows) and shared memory (also windows). No support for these
64connection types is planned, either. 68connection types is planned, either.
65 69
70=head1 CANCELLATION
71
72Cancelling a thread that is within a mysql query will likely make the
73handle unusable. As far as Coro::Mysql is concerned, the handle can be
74safely destroyed, but it's not clear how mysql itself will react to a
75cancellation.
76
66=head1 FUNCTIONS 77=head1 FUNCTIONS
67 78
68Coro::Mysql offers a single user-accessible function: 79Coro::Mysql offers a single user-accessible function:
69 80
70=over 4 81=over 4
78 89
79use Scalar::Util (); 90use Scalar::Util ();
80use Carp qw(croak); 91use Carp qw(croak);
81 92
82use Guard; 93use Guard;
94use AnyEvent ();
83use Coro::Handle (); 95use Coro ();
96use Coro::AnyEvent (); # not necessary with newer Coro versions
84 97
85# we need this extra indirection, as Coro doesn't support 98# we need this extra indirection, as Coro doesn't support
86# calling SLF-like functions via call_sv. 99# calling SLF-like functions via call_sv.
87 100
88sub readable { &Coro::Handle::FH::readable } 101sub readable { &Coro::Handle::FH::readable }
117 my $sock = $DBH->{sock}; 130 my $sock = $DBH->{sock};
118 131
119 open my $fh, "+>&" . $DBH->{sockfd} 132 open my $fh, "+>&" . $DBH->{sockfd}
120 or croak "Coro::Mysql unable to clone mysql fd"; 133 or croak "Coro::Mysql unable to clone mysql fd";
121 134
135 if (AnyEvent::detect ne "AnyEvent::Impl::EV" || !_use_ev) {
136 require Coro::Handle;
122 $fh = Coro::Handle::unblock $fh; 137 $fh = Coro::Handle::unblock ($fh);
138 }
123 139
124 _patch $sock, $DBH->{sockfd}, $fh, tied ${$fh}; 140 _patch $sock, $DBH->{sockfd}, $fh, tied ${$fh};
125 } 141 }
126 142
127 $DBH 143 $DBH
144 use PApp::SQL; 160 use PApp::SQL;
145 161
146 sub with_db($$$&) { 162 sub with_db($$$&) {
147 my ($database, $user, $pass, $cb) = @_; 163 my ($database, $user, $pass, $cb) = @_;
148 164
149 my $dbh = Coro::Mysql::unblock DBI->connect ($database, $user, $pass) 165 my $dbh = DBI->connect ($database, $user, $pass)->Coro::Mysql::unblock
150 or die $DBI::errstr; 166 or die $DBI::errstr;
151 167
152 Coro::on_enter { $PApp::SQL::DBH = $dbh }; 168 Coro::on_enter { $PApp::SQL::DBH = $dbh };
153 169
154 $cb->(); 170 $cb->();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines