… | |
… | |
16 | |
16 | |
17 | This can be used to make parallel sql requests using Coro, or to do |
17 | This can be used to make parallel sql requests using Coro, or to do |
18 | other stuff while mysql is rumbling in the background. |
18 | other stuff while mysql is rumbling in the background. |
19 | |
19 | |
20 | CAVEAT |
20 | CAVEAT |
21 | Note that this module must be linked against exactly the same |
21 | Note that this module must be linked against exactly the same (shared, |
|
|
22 | possibly not working with all OSes) libmysqlclient library as |
22 | libmysqlclient library as DBD::mysql, otherwise it will not work. |
23 | DBD::mysql, otherwise it will not work. |
23 | |
24 | |
24 | Also, while this module makes database handles non-blocking, you still |
25 | Also, while this module makes database handles non-blocking, you still |
25 | cannot run multiple requests in parallel on the same database handle. If |
26 | cannot run multiple requests in parallel on the same database handle. If |
26 | you want to run multiple queries in parallel, you have to create |
27 | you want to run multiple queries in parallel, you have to create |
27 | multiple database connections, one for each thread that runs queries. |
28 | multiple database connections, one for each thread that runs queries. |
… | |
… | |
30 | |
31 | |
31 | If you make sure that you never run two or more requests in parallel, |
32 | If you make sure that you never run two or more requests in parallel, |
32 | you can freely share the database handles between threads, of course. |
33 | you can freely share the database handles between threads, of course. |
33 | |
34 | |
34 | Also, this module uses a number of "unclean" techniques (patching an |
35 | Also, this module uses a number of "unclean" techniques (patching an |
35 | internal libmysql structure for one thing) and was hacked within a few |
36 | internal libmysql structure for one thing) and was initially hacked |
36 | hours on a long flight to Malaysia. |
37 | within a few hours on a long flight to Malaysia. |
37 | |
38 | |
38 | It does, however, check whether it indeed got the structure layout |
39 | It does, however, check whether it indeed got the structure layout |
39 | correct, so you should expect perl exceptions or early crashes as |
40 | correct, so you should expect perl exceptions or early crashes as |
40 | opposed to data corruption when something goes wrong during patching. |
41 | opposed to data corruption when something goes wrong during patching. |
41 | |
42 | |
42 | SPEED |
43 | SPEED |
43 | This module is implemented in XS, and as long as mysqld replies quickly |
44 | This module is implemented in XS, and as long as mysqld replies quickly |
44 | enough, it adds no overhead to the standard libmysql communication |
45 | enough, it adds no overhead to the standard libmysql communication |
45 | routines (which are very badly written, btw.). |
46 | routines (which are very badly written, btw.). In fact, since it has a |
|
|
47 | more efficient buffering and allows requests to run in parallel, it |
|
|
48 | often decreases the actual time to run many queries considerably. |
46 | |
49 | |
47 | For very fast queries ("select 0"), this module can add noticable |
50 | For very fast queries ("select 0"), this module can add noticable |
48 | overhead (around 15%) as it tries to switch to other coroutines when |
51 | overhead (around 15%, 7% when EV can be used) as it tries to switch to |
49 | mysqld doesn't deliver the data instantly. |
52 | other coroutines when mysqld doesn't deliver the data immediately, |
|
|
53 | although, again, when running queries in parallel, they will usually |
|
|
54 | execute faster. |
50 | |
55 | |
51 | For most types of queries, there will be no overhead, especially on |
56 | For most types of queries, there will be no extra latency, especially on |
52 | multicore systems where your perl process can do other things while |
57 | multicore systems where your perl process can do other things while |
53 | mysqld does its stuff. |
58 | mysqld does its stuff. |
54 | |
59 | |
55 | LIMITATIONS |
60 | LIMITATIONS |
56 | This module only supports "standard" mysql connection handles - this |
61 | This module only supports "standard" mysql connection handles - this |
57 | means unix domain or TCP sockets, and excludes SSL/TLS connections, |
62 | means unix domain or TCP sockets, and excludes SSL/TLS connections, |
58 | named pipes (windows) and shared memory (also windows). No support for |
63 | named pipes (windows) and shared memory (also windows). No support for |
59 | these connection types is planned, either. |
64 | these connection types is planned, either. |
|
|
65 | |
|
|
66 | CANCELLATION |
|
|
67 | Cancelling a thread that is within a mysql query will likely make the |
|
|
68 | handle unusable. As far as Coro::Mysql is concerned, the handle can be |
|
|
69 | safely destroyed, but it's not clear how mysql itself will react to a |
|
|
70 | cancellation. |
60 | |
71 | |
61 | FUNCTIONS |
72 | FUNCTIONS |
62 | Coro::Mysql offers a single user-accessible function: |
73 | Coro::Mysql offers a single user-accessible function: |
63 | |
74 | |
64 | $DBH = Coro::Mysql::unblock $DBH |
75 | $DBH = Coro::Mysql::unblock $DBH |
… | |
… | |
71 | It is safe to call this function on any database handle (or just |
82 | It is safe to call this function on any database handle (or just |
72 | about any value), but it will only do anything to DBD::mysql |
83 | about any value), but it will only do anything to DBD::mysql |
73 | handles, others are returned unchanged. That means it is harmless |
84 | handles, others are returned unchanged. That means it is harmless |
74 | when applied to database handles of other databases. |
85 | when applied to database handles of other databases. |
75 | |
86 | |
|
|
87 | It is also safe to pass "undef", so code like this is works as |
|
|
88 | expected: |
|
|
89 | |
|
|
90 | my $dbh = DBI->connect ($database, $user, $pass)->Coro::Mysql::unblock |
|
|
91 | or die $DBI::errstr; |
|
|
92 | |
76 | USAGE EXAMPLE |
93 | USAGE EXAMPLE |
77 | This example uses PApp::SQL and Coro::on_enter to implement a function |
94 | This example uses PApp::SQL and Coro::on_enter to implement a function |
78 | "with_db", that connects to a database, uses "unblock" on the resulting |
95 | "with_db", that connects to a database, uses "unblock" on the resulting |
79 | handle and then makes sure that $PApp::SQL::DBH is set to the |
96 | handle and then makes sure that $PApp::SQL::DBH is set to the |
80 | (per-thread) database handle when the given thread is running (it does |
97 | (per-thread) database handle when the given thread is running (it does |
… | |
… | |
85 | use PApp::SQL; |
102 | use PApp::SQL; |
86 | |
103 | |
87 | sub with_db($$$&) { |
104 | sub with_db($$$&) { |
88 | my ($database, $user, $pass, $cb) = @_; |
105 | my ($database, $user, $pass, $cb) = @_; |
89 | |
106 | |
90 | my $dbh = Coro::Mysql::unblock DBI->connect ($database, $user, $pass) |
107 | my $dbh = DBI->connect ($database, $user, $pass)->Coro::Mysql::unblock |
91 | or die $DBI::errstr; |
108 | or die $DBI::errstr; |
92 | |
109 | |
93 | Coro::on_enter { $PApp::SQL::DBH = $dbh }; |
110 | Coro::on_enter { $PApp::SQL::DBH = $dbh }; |
94 | |
111 | |
95 | $cb->(); |
112 | $cb->(); |