Mailing List

Nested
Re: AnyEvent::DBI + Apache + Plack
User: mcholste
Date: 12/3/2011 3:33 pm
Views: 453
Rating: 0
Ok, nevermind Rob, it does indeed work.  The trick is that you need a
separate new DBH for every concurrent query so they have a different
file descriptor.  Here's the proof-of-concept code:

#!/usr/bin/perl
use strict;
use Data::Dumper;
use DBI;
use AnyEvent;

my %ret;
my %watchers;
my $cv = AnyEvent->condvar;
$cv->begin(sub { shift->send; });

my $db_params = [ 'dbi:mysql:database=test', 'root', '', { RaiseError => 1 } ];
# This query sleeps 3 seconds
async_query(1, $db_params, 'SELECT SLEEP(3), 1', $cv, \%ret, \%watchers);
# This query sleeps 5 seconds
async_query(2, $db_params, 'SELECT SLEEP(5), 2', $cv, \%ret, \%watchers);

$cv->end;
$cv->recv;
# We don't get here until both queries are done
print "Done!\n";
print Dumper(\%ret);


sub async_query {
       my $id = shift;
       my $dbh_args = shift;
       my $query = shift;
       my $cv = shift;
       my $ret = shift;
       my $watchers = shift;

       $cv->begin;
       my $dbh = DBI->connect(@$dbh_args) or die($DBI::errstr);
       my $sth = $dbh->prepare($query, { async => 1 });
       $sth->execute;
       print "Executing query $query\n";
       $watchers{$id} = AnyEvent->io( fh => $dbh->mysql_fd, poll =>
'r', cb => sub {
               print "MySQL result for query $query\n";
               $ret->{$id} = $sth->fetchall_arrayref;
               $cv->end;
               print "Got result for query $query\n";
       });
}


On Sat, Dec 3, 2011 at 2:52 PM, Martin Holste  wrote:
> Hm, ok, but here's a second wrinkle: if you have any
> AnyEvent->condvar->recv calls in your code, you can't run it under an
> AnyEvent-based HTTP server like Twiggy or Feersum because of recursive
> blocking recv calls.
>
> Rob, have you used your MySQL async interface with AnyEvent in such a
> way that you wait until parallelized SQL calls to different servers
> are all in before proceeding?  It seems theoretically feasible to me
> if you wrap the async calls in an AnyEvent sub, but I could see how it
> might not be possible given that you need to use the condvar.  That
> would allow the parallel MySQL calls without having to use
> AnyEvent::DBI, which forks and creates the Apache problems.
>
> On Fri, Dec 2, 2011 at 5:11 PM,   wrote:
>> jt wrote:
>>
>> The general rule is that you only use AnyEvent stuff inside of non-forking
>> servers such as Feersum (https://github.com/stash/Feersum). And then proxy
>> with Apache or nginx or whatever.
>>
>>
>>
>> On Dec 2, 2011, at 4:01 PM,   wrote:
>>
>> mcholste wrote:
>>
>> I'm having a really tough time getting AnyEvent::DBI working correctly
>> under Apache.  The problem is that the parent process in Apache never
>> goes away, which leaves the child forks of AnyEvent::DBI running and
>> consuming memory.  A workaround is to forcefully ->DESTROY the DBH as
>> soon as it's done being used, but that leaves some zombies around for
>> awhile and produces a ton of warnings.  Anyone dealt with this kind of
>> thing before?
>>
>> View Online
>>
>>
>>
>> Madison Area Perl Mongers - MadMongers
>> http://www.madmongers.org
>>
>>
>> View Online
>>
>>
>>
>> Madison Area Perl Mongers - MadMongers
>> http://www.madmongers.org
PreviousNext
Madison Area Perl Mongers