Async-Redis

 view release on metacpan or  search on metacpan

examples/pagi-chat/public/css/style.css  view on Meta::CPAN

.btn-secondary:hover {
    background: var(--border-color);
}

.btn-icon {
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 1.2rem;
    transition: all 0.2s;
}

.btn-icon:hover {
    background: var(--bg-tertiary);
    color: var(--text-primary);
}

examples/pagi-chat/public/css/style.css  view on Meta::CPAN

    align-self: center;
    background: var(--message-system-bg);
    font-size: 0.85rem;
    color: var(--text-secondary);
    padding: 0.5rem 1rem;
    max-width: 90%;
}

.message.action {
    align-self: center;
    background: transparent;
    font-style: italic;
    color: var(--text-secondary);
}

.message.pm {
    border-left: 3px solid var(--accent-color);
}

.message-header {
    display: flex;

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

    $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:

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

1;

__END__

=head1 NAME

Async::Redis::AutoPipeline - Automatic command batching

=head1 DESCRIPTION

AutoPipeline transparently batches Redis commands issued in the same
event loop tick into a single pipeline, reducing network round-trips
without changing the caller's API.

=head2 How It Works

    # These three commands are batched automatically
    my $f1 = $redis->set('a', 1);
    my $f2 = $redis->set('b', 2);
    my $f3 = $redis->get('a');

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

    my $redis = $script->redis;

Returns the default Redis connection associated with the script, if any.

=head1 EVALSHA OPTIMIZATION

Scripts automatically use EVALSHA for efficiency. If the script isn't
cached on the Redis server (NOSCRIPT error), it falls back to EVAL
which also loads the script for future calls.

This is transparent - you don't need to manually load scripts.

=head1 SEE ALSO

L<Async::Redis> - Main client with C<script()> and C<define_command()> methods

=cut

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

        channel => 'channel_name',
        pattern => 'pattern',      # defined for pmessage, undef otherwise
        data    => 'payload',
    }

The C<pattern> key is always present. It is defined for C<pmessage>
frames (the matching glob pattern) and C<undef> for C<message> and
C<smessage> frames. Consumers do not need C<exists $msg-E<gt>{pattern}>
checks.

C<next()> always returns real pub/sub messages. Reconnection is transparent.

=head1 RECONNECTION

When C<reconnect> is enabled on the Redis connection, subscriptions are
automatically re-established after a connection drop. To be notified:

    $sub->on_reconnect(sub {
        my ($sub) = @_;
        warn "Reconnected, may have lost messages";
        # re-poll state, log, etc.

t/30-pipeline/auto-pipeline.t  view on Meta::CPAN


        is(scalar @results, 100, 'all 100 completed');
        ok((grep { $_ eq 'OK' } @results) == 100, 'all returned OK');

        # Verify values
        my @get_futures = map { $redis->get("ap:$_") } (1..10);
        my @values = await_f(Future->needs_all(@get_futures));
        is(\@values, [1..10], 'values stored correctly');
    };

    subtest 'auto-pipeline transparent API' => sub {
        # Same API as non-pipelined
        my $result = run { $redis->set('ap:single', 'value') };
        is($result, 'OK', 'single command works');

        my $value = run { $redis->get('ap:single') };
        is($value, 'value', 'GET works');
    };

    subtest 'auto-pipeline faster than sequential' => sub {
        # Compare auto-pipelined to non-pipelined

t/50-pubsub/reconnect.t  view on Meta::CPAN


        # Server-initiated disconnect via KILL from pub connection.
        eval { run { $pub->client('KILL', 'ID', $sub_client_id) } };

        # Publish after reconnect window
        my $post_future = (async sub {
            await Future::IO->sleep(0.3);
            await $pub->publish('reconnect:test', 'after');
        })->();

        # next() should reconnect transparently and return real message
        my $next_f = $subscription->next;
        my $timeout_f = Future::IO->sleep($TEST_TIMEOUT)->then(sub {
            Future->fail("Timed out waiting for message after reconnect");
        });
        my $msg2 = eval { await_f(Future->wait_any($next_f, $timeout_f)); $next_f->get };

        if ($@) {
            fail("received message after reconnect: $@");
        } else {
            is($msg2->{type}, 'message', 'got real message type after reconnect');



( run in 2.027 seconds using v1.01-cache-2.11-cpan-ba708fea25c )