AnyEvent-DBI
view release on metacpan or search on metacpan
->new # create new template
->require ("AnyEvent::DBI::Slave"); # preload AnyEvent::DBI::Slave module
for (...) {
$dbh = new AnyEvent::DBI ...
fork_template => $template;
=item timeout => seconds
If you supply a timeout parameter (fractional values are supported), then
a timer is started any time the DBI handle expects a response from the
server. This includes connection setup as well as requests made to the
backend. The timeout spans the duration from the moment the first data
is written (or queued to be written) until all expected responses are
returned, but is postponed for "timeout" seconds each time more data is
returned from the server. If the timer ever goes off then a fatal error is
generated. If you have an C<on_error> handler installed, then it will be
called, otherwise your program will die().
When altering your databases with timeouts it is wise to use
transactions. If you quit due to timeout while performing insert, update
or schema-altering commands you can end up not knowing if the action was
submitted to the database, complicating recovery.
Timeout errors are always fatal.
{
Convert::Scalar::weaken (my $self = $self);
my $cbor = new CBOR::XS;
$self->{rw} = AE::io $client, 0, sub {
my $len = Convert::Scalar::extend_read $client, $rbuf, 65536;
if ($len > 0) {
# we received data, so reset the timer
$self->{last_activity} = AE::now;
for my $res ($cbor->incr_parse_multiple ($rbuf)) {
last unless $self;
my $req = shift @{ $self->{queue} };
if (defined $res->[0]) {
$res->[0] = $self;
$req->[0](@$res);
};
$self->{tw_cb} = sub {
if ($self->{timeout} && $self->{last_activity}) {
if (AE::now > $self->{last_activity} + $self->{timeout}) {
# we did time out
my $req = $self->{queue}[0];
$self->_error (timeout => $req->[1], $req->[2], 1); # timeouts are always fatal
} else {
# we need to re-set the timeout watcher
$self->{tw} = AE::timer
$self->{last_activity} + $self->{timeout} - AE::now,
0,
$self->{tw_cb},
;
}
} else {
# no timeout check wanted, or idle
undef $self->{tw};
}
};
Sets (or clears, with C<undef>) the database timeout. Useful to extend the
timeout when you are about to make a really long query.
=cut
sub timeout {
my ($self, $timeout) = @_;
$self->{timeout} = $timeout;
# reschedule timer if one was running
$self->{tw_cb}->();
}
sub _req {
my ($self, $cb, $filename, $line) = splice @_, 0, 4, ();
unless ($self->{fh}) {
local $@ = my $err = 'no database connection';
$cb->($self);
$self->_error ($err, $filename, $line, 1);
my $template = AnyEvent::Fork
->new # create new template
->require ("AnyEvent::DBI::Slave"); # preload AnyEvent::DBI::Slave module
for (...) {
$dbh = new AnyEvent::DBI ...
fork_template => $template;
timeout => seconds
If you supply a timeout parameter (fractional values are
supported), then a timer is started any time the DBI handle
expects a response from the server. This includes connection
setup as well as requests made to the backend. The timeout spans
the duration from the moment the first data is written (or
queued to be written) until all expected responses are returned,
but is postponed for "timeout" seconds each time more data is
returned from the server. If the timer ever goes off then a
fatal error is generated. If you have an "on_error" handler
installed, then it will be called, otherwise your program will
die().
When altering your databases with timeouts it is wise to use
transactions. If you quit due to timeout while performing
insert, update or schema-altering commands you can end up not
knowing if the action was submitted to the database,
complicating recovery.
t/01_fake_mysql.t view on Meta::CPAN
push @handles, $dbh3;
}
$cv->recv();
is(scalar @handles,3,'created three handles');
is(scalar @handle_errors,0,'no errors during handle creation');
my @pids = map {$_->_server_pid} @handles;
ok( defined pexists(@pids, {all=>1}),'Found three slave processes');
undef @handles;
$cv = AnyEvent->condvar;
my $cleanup = AnyEvent->timer(after=>0.5,cb=>sub {$cv->send()});
$cv->recv();
ok(!defined pexists(@pids, {any=>1}),'All slave processes exited');
}
# connect to the server again
$cv = AnyEvent->condvar;
$dbh = new AnyEvent::DBI(
"dbi:mysql:database=database;host=127.0.0.1;port=23306",'','',
PrintError => 0,
timeout => 2,
( run in 0.975 second using v1.01-cache-2.11-cpan-49f99fa48dc )