Async-Redis

 view release on metacpan or  search on metacpan

t/60-scripting/pipeline-scripts.t  view on Meta::CPAN

    subtest 'dynamic key script in pipeline' => sub {
        my $r = Async::Redis->new(host => $ENV{REDIS_HOST} // 'localhost');
        run { $r->connect };

        $r->define_command(sum_keys => {
            keys => 'dynamic',
            lua  => <<'LUA',
                local sum = 0
                for i, key in ipairs(KEYS) do
                    sum = sum + tonumber(redis.call('GET', key) or 0)
                end
                return sum
LUA
        });

        run { $r->mset('sum:a', 10, 'sum:b', 20, 'sum:c', 30) };

        my $pipe = $r->pipeline;
        $pipe->run_script('sum_keys', 2, 'sum:a', 'sum:b');      # 30
        $pipe->run_script('sum_keys', 3, 'sum:a', 'sum:b', 'sum:c');  # 60
        $pipe->run_script('sum_keys', 1, 'sum:c');              # 30

        my $results = run { $pipe->execute };
        is($results, [30, 60, 30], 'dynamic key scripts in pipeline');

        run { cleanup_keys($r, 'sum:*') };
        $r->disconnect;
    };

    subtest 'same script multiple times (dedup loading)' => sub {
        my $r = Async::Redis->new(host => $ENV{REDIS_HOST} // 'localhost');
        run { $r->connect };

        # Clear scripts
        run { $r->script_flush };

        $r->define_command(counter => {
            keys => 1,
            lua  => 'return redis.call("INCR", KEYS[1])',
        });

        # Use same script many times
        my $pipe = $r->pipeline;
        for (1..10) {
            $pipe->run_script('counter', "dedup:key");
        }

        my $results = run { $pipe->execute };
        is($results, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'same script 10 times works');

        run { cleanup_keys($r, 'dedup:*') };
        $r->disconnect;
    };

    subtest 'unknown script in pipeline error' => sub {
        my $r = Async::Redis->new(host => $ENV{REDIS_HOST} // 'localhost');
        run { $r->connect };

        my $pipe = $r->pipeline;
        $pipe->set('err:key', 'value');
        $pipe->run_script('not_defined', 'err:key');

        like(
            dies { run { $pipe->execute } },
            qr/Unknown script.*not_defined/,
            'pipeline dies on unknown script'
        );

        $r->disconnect;
    };

    subtest 'pipeline with script after script_flush' => sub {
        my $r = Async::Redis->new(host => $ENV{REDIS_HOST} // 'localhost');
        run { $r->connect };

        $r->define_command(simple_get => {
            keys => 1,
            lua  => 'return redis.call("GET", KEYS[1])',
        });

        run { $r->set('flush:key', 'flush:value') };

        # Flush all scripts from server
        run { $r->script_flush };

        # Pipeline should still work (preloads before execution)
        my $pipe = $r->pipeline;
        $pipe->run_script('simple_get', 'flush:key');

        my $results = run { $pipe->execute };
        is($results, ['flush:value'], 'pipeline works after script_flush');

        run { cleanup_keys($r, 'flush:*') };
        $r->disconnect;
    };

    $redis->disconnect;
}

done_testing;



( run in 3.590 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )