Async-Redis
view release on metacpan or search on metacpan
t/02-nonblocking.t view on Meta::CPAN
is $v1, 'value1', 'got value1';
is $v2, 'value2', 'got value2';
run { $redis1->del('parallel:1') };
run { $redis2->del('parallel:2') };
$redis1->disconnect;
$redis2->disconnect;
};
# ============================================================================
# Test 2: Pipelining is faster than sequential
# ============================================================================
subtest 'pipelining performance' => sub {
my $redis = Async::Redis->new(host => redis_host(), port => redis_port());
run { $redis->connect };
my $n = 10; # Reduced for testing
# Sequential
my $seq_start = time();
for my $i (1..$n) {
run { $redis->set("pipe_seq:$i", "value_$i") };
}
my $seq_time = time() - $seq_start;
# Cleanup - one by one
for my $i (1..$n) {
run { $redis->del("pipe_seq:$i") };
}
# Pipelined
my $pipe_start = time();
my $pipeline = $redis->pipeline;
for my $i (1..$n) {
$pipeline->set("pipe_pipe:$i", "value_$i");
}
run { $pipeline->execute };
my $pipe_time = time() - $pipe_start;
ok $pipe_time <= $seq_time,
"pipeline (${pipe_time}s) not slower than sequential (${seq_time}s)";
my $speedup = $seq_time / ($pipe_time || 0.001);
diag sprintf("Pipeline speedup: %.1fx (%d ops)", $speedup, $n);
# Cleanup - one by one
for my $i (1..$n) {
run { $redis->del("pipe_pipe:$i") };
}
$redis->disconnect;
};
# ============================================================================
# Test 3: Timer can run during Redis operations
# ============================================================================
subtest 'event loop not blocked' => sub {
my $redis = Async::Redis->new(host => redis_host(), port => redis_port());
run { $redis->connect };
my @futures = map { $redis->set("nb:nonblocking:$_", $_) } (1..50);
my $start = Time::HiRes::time();
run { Future->needs_all(@futures) };
my $elapsed = Time::HiRes::time() - $start;
ok($elapsed < 5, "50 concurrent ops completed in ${elapsed}s");
run { $redis->del(map { "nb:nonblocking:$_" } 1..50) };
$redis->disconnect;
};
# ============================================================================
# Test 4: Connection pool pattern
# ============================================================================
subtest 'connection pool' => sub {
# Create a pool of connections
my @pool;
for my $i (1..3) {
my $r = Async::Redis->new(host => redis_host(), port => redis_port());
run { $r->connect };
push @pool, $r;
}
my $start = time();
# Run operations in parallel across pool
my @futures;
for my $i (0..2) {
push @futures, $pool[$i]->set("pool:$i", "val$i");
}
Future->needs_all(@futures)->get;
my $elapsed = time() - $start;
ok $elapsed < 0.5, "pool ops completed (${elapsed}s)";
# Verify
for my $i (0..2) {
my $v = run { $pool[$i]->get("pool:$i") };
is $v, "val$i", "got pool:$i value";
}
# Cleanup
for my $i (0..2) {
run { $pool[$i]->del("pool:$i") };
$pool[$i]->disconnect;
}
};
done_testing;
( run in 0.992 second using v1.01-cache-2.11-cpan-df04353d9ac )