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 )