Async-Redis

 view release on metacpan or  search on metacpan

lib/Async/Redis.pm  view on Meta::CPAN

Load all registered scripts to Redis server. Useful before pipeline
execution to ensure EVALSHA will succeed.

=head2 script_load / script_exists / script_flush / script_kill

    my $sha = await $redis->script_load($lua);
    my $flags = await $redis->script_exists($sha1, $sha2);
    await $redis->script_flush('ASYNC');
    await $redis->script_kill;

Thin wrappers around Redis C<SCRIPT> subcommands.

=head2 is_dirty

    my $dirty = $redis->is_dirty;

Return true if the connection has state that makes it unsafe to return to a
pool: active transaction, watched keys, pub/sub mode, or pending responses.

=head2 in_multi / watching / in_pubsub / inflight_count

State accessors used by L<Async::Redis::Pool> and useful for diagnostics.

=head1 LUA SCRIPTING

Async::Redis provides comprehensive support for Redis Lua scripting with
automatic EVALSHA optimization.

=head2 Quick Start

    # Define a reusable script
    $redis->define_command(atomic_incr => {
        keys => 1,
        lua  => <<'LUA',
            local current = tonumber(redis.call('GET', KEYS[1]) or 0)
            local result = current + tonumber(ARGV[1])
            redis.call('SET', KEYS[1], result)
            return result
LUA
    });

    # Use it
    my $result = await $redis->run_script('atomic_incr', 'counter', 5);

=head2 Pipeline Integration

Registered scripts work in pipelines:

    my $pipe = $redis->pipeline;
    $pipe->run_script('atomic_incr', 'counter:a', 1);
    $pipe->run_script('atomic_incr', 'counter:b', 1);
    $pipe->set('other:key', 'value');
    my $results = await $pipe->execute;

Scripts are automatically preloaded before pipeline execution.

=head2 EVALSHA Optimization

Scripts automatically use EVALSHA (by SHA1 hash) for efficiency.
If the script isn't cached on the server, it falls back to EVAL
and caches for future calls. This is transparent to your code.

=head2 scan_iter

    my $iter = $redis->scan_iter(match => 'user:*', count => 100);
    while (my $keys = await $iter->next) {
        for my $key (@$keys) { ... }
    }

Create an iterator for SCAN. Also available:

    my $hash_iter = $redis->hscan_iter('hash', match => 'field:*');
    my $set_iter  = $redis->sscan_iter('set', count => 100);
    my $zset_iter = $redis->zscan_iter('zset');

Iterators return batches. C<ZSCAN> batches are the Redis flat
member/score list.

=head1 CONNECTION POOLING

For high-throughput applications, use L<Async::Redis::Pool>:

    use Async::Redis::Pool;

    my $pool = Async::Redis::Pool->new(
        host => 'localhost',
        min  => 2,
        max  => 10,
    );

    # Use with() for automatic acquire/release
    my $result = await $pool->with(sub {
        my ($conn) = @_;
        return $conn->get('key');
    });

=head1 ERROR HANDLING

Errors are thrown as exception objects:

    eval {
        await $redis->get('key');
        1;
    } or do {
        my $error = $@;
        if (ref($error) && $error->isa('Async::Redis::Error::Connection')) {
            # Connection error
        } elsif (ref($error) && $error->isa('Async::Redis::Error::Timeout')) {
            # Timeout error
        } elsif (ref($error) && $error->isa('Async::Redis::Error::Redis')) {
            # Redis error (e.g., WRONGTYPE)
        }
    };

Exception classes:

=over 4

=item Async::Redis::Error::Connection

Connection-related errors (refused, reset, etc.)



( run in 0.924 second using v1.01-cache-2.11-cpan-ba708fea25c )