After experimenting with Redis in Mojo (http://github.com/vti/mojox-socket_stream) I wanted to do something asynchronously with DBI also, using my another Async::ORM module. But apparently doing async with DBI is not that easy. By itself DBI blocks everything and thus there are a few workarounds on CPAN with forks, sockets and pipes like AnyEvent::DBI, POE::Component::EasyDBI, POE::Component::SimpleDBI, IO::Lambda::DBI and others. That is why I have AnyEvent::DBI driver inside of Async::ORM. But I wanted to use Mojo::IOLoop as an event loop.
Writing another forking hack module is cool but I am not that smart, that's why I googled with a hope to find some event loop independent async DBI. And I found dbslayer (http://code.nytimes.com/projects/dbslayer/wiki). DBSlayer is a proxy between HTTP+JSON and MySQL. You send your SQL query as a GET request in JSON format and get JSON response. So what I needed is a http client that can send json requests and parse json responses. Mojo has got both.
So I've written DBSlayer driver for Async::ORM that talks to DBSlayer server. Implementation details are not that interesting, but interesting part is in using Mojo::Client and Mojo::JSON.
Start dbslayer server
dbslayer -c myconf.cnf -s localhost -u foo -x bar
Create an Async::ORM::DBI::DBSlayer handler
my $client = Mojo::Client->new;
my $json = Mojo::JSON->new;
my $dbh = Async::ORM::DBI::DBSlayer->new(
database => 'async_orm',
json_encode => sub { $json->encode(@_) },
json_decode => sub { $json->decode(@_) },
http_req_cb => sub {
my ($url, $method, $headers, $body, $cb) = @_;
$url = Mojo::URL->new($url);
$url->query($body);
$client->get(
$url->to_string => sub {
my ($self, $tx) = @_;
$cb->(
$url, $tx->res->code, $tx->res->headers->to_hash,
$tx->res->body
);
}
)->process;
}
);
http_req_cb is a callback for making requests to dbslayer server, json_* utilities are for parsing JSON.
Then use it in async Async::ORM manner.
Article->new(title => 'foo')->create(
$dbh => sub {
my ($dbh, $article_) = @_;
}
);
This way I can use Mojo::IOLoop (which means in every Mojolicious application) for managing DBI queries inside of Async::ORM!
You can find the latest code at github http://github.com/vti/async-orm/.
