EV-Memcached
view release on metacpan or search on metacpan
t/26_connect_error_reentry.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use EV;
use EV::Memcached;
use FindBin;
use lib "$FindBin::Bin/lib";
use FakeMemcached;
# A synchronous failure handler can choose a healthy replacement endpoint.
for my $reconnect (0, 1) {
my $srv = FakeMemcached->new(script => sub {
my $c = FakeMemcached->accept(shift);
my $r = $c->read_request or exit 0;
$c->respond_hit(op => $r->[0], opaque => $r->[1], value => 'healthy');
sleep 2;
});
my ($value, $error, $connected, @errors);
EV::now_update;
my $mc = EV::Memcached->new(reconnect => $reconnect, reconnect_delay => 10,
on_error => sub {});
$mc->on_connect(sub { ++$connected });
$mc->on_error(sub {
push @errors, $_[0];
return if @errors > 1;
$mc->connect_unix($srv->path);
$mc->get('k', sub { ($value, $error) = @_; EV::break });
});
$mc->connect_unix($srv->path . '.missing');
my $t = EV::timer 2, 0, sub { EV::break };
EV::run;
is($value, 'healthy', "reconnect=$reconnect: replacement command survives error handler");
is($error, undef, "reconnect=$reconnect: no stale cancellation");
# Stay up past reconnect_delay to catch an extra timer on the new session.
my $settle = EV::timer 0.05, 0, sub { EV::break };
EV::run;
is($connected, 1, "reconnect=$reconnect: replacement connects exactly once");
is(scalar @errors, 1, "reconnect=$reconnect: only the original failure reported");
$mc->disconnect;
$srv->finish;
}
# A disconnect handler reconnecting manually must own the new session.
{
my $srv = FakeMemcached->new(script => sub {
my $listen = shift;
my $first = FakeMemcached->accept($listen);
$first->read_request;
$first->sock->close;
my $next = FakeMemcached->accept($listen);
my $r = $next->read_request or exit 0;
$next->respond_hit(op => $r->[0], opaque => $r->[1], value => 'next');
sleep 2;
});
my ($value, $connected);
EV::now_update;
my $mc = EV::Memcached->new(path => $srv->path, reconnect => 1,
reconnect_delay => 10, on_error => sub {});
$mc->on_connect(sub { ++$connected });
$mc->on_disconnect(sub {
$mc->connect_unix($srv->path);
$mc->get('k', sub { $value = $_[0]; EV::break });
});
$mc->noop;
my $t = EV::timer 2, 0, sub { EV::break };
EV::run;
is($value, 'next', 'manual reconnect from on_disconnect delivers work');
my $settle = EV::timer 0.05, 0, sub { EV::break };
EV::run;
is($connected, 2, 'no redundant automatic connect after manual reconnect');
( run in 0.699 second using v1.01-cache-2.11-cpan-cb04b646d8c )