=encoding utf8

=for comment POD_DERIVED_INDEX_GENERATED
The following documentation is automatically generated.  Please do not edit
this file, but rather the original, inline with Net::Async::Redis
at lib/Net/Async/Redis.pm
(on the system that originally ran this).
If you do edit this file, and don't want your changes to be removed, make
sure you change the first line.

=cut

=head1 NAME

Net::Async::Redis - talk to Redis servers via L<IO::Async>

=head1 SYNOPSIS

    use Net::Async::Redis;
    use Future::AsyncAwait;
    use IO::Async::Loop;
    my $loop = IO::Async::Loop->new;
    $loop->add(my $redis = Net::Async::Redis->new);
    my $value = await $redis->get('some_key');
    $value ||= await $redis->set(some_key => 'some_value');
    print "Value: $value\n";

    # You can also use ->then chaining, see L<Future> for more details
    $redis->connect->then(sub {
        $redis->get('some_key')
    })->then(sub {
        my $value = shift;
        return Future->done($value) if $value;
        $redis->set(some_key => 'some_value')
    })->on_done(sub {
        print "Value: " . shift;
    })->get;

=head1 DESCRIPTION

Provides client access for dealing with Redis servers.

6ee L<Net::Async::Redis::Commands> for the full list of commands, this list
is autogenerated from the official documentation here:

L<https://redis.io/commands>

This is intended to be a near-complete low-level client module for asynchronous Redis
support. See L<Net::Async::Redis::Server> for a (limited) Perl server implementation.

This is an unofficial Perl port, and not endorsed by the Redis server maintainers in any
way.

=head2 Supported features

Current features include:

=over 4

=item * L<all commands|https://redis.io/commands> as of 7.0 RC (February 2022), see L<https://redis.io/commands> for the methods and parameters

=item * L<pub/sub support|https://redis.io/topics/pubsub>, see L</METHODS - Subscriptions>

=item * L<pipelining|https://redis.io/topics/pipelining>, see L</pipeline_depth>

=item * L<transactions|https://redis.io/topics/transactions>, see L</METHODS - Transactions>

=item * L<streams|https://redis.io/topics/streams-intro> and consumer groups, via L<Net::Async::Redis::Commands/XADD> and related methods

=item * L<client-side caching|https://redis.io/topics/client-side-caching>, see L</METHODS - Clientside caching>

=item * L<RESP3/https://github.com/antirez/RESP3/blob/master/spec.md> protocol for Redis 6 and above, allowing pubsub on the same connection as regular commands

=back

=head2 Connecting

As with any other L<IO::Async::Notifier>-based module, you'll need to
add this to an L<IO::Async::Loop>:

    my $loop = IO::Async::Loop->new;
    $loop->add(
        my $redis = Net::Async::Redis->new
    );

then connect to the server:

    use Future::AsyncAwait;
    await $redis->connect;
    # You could achieve a similar result by passing client_name in
    # constructor or ->connect parameters
    await $redis->client_setname("example client");

=head2 Key-value handling

One of the most common Redis scenarios is as a key/value store. The L</get> and L</set>
methods are typically used here:

    use Future::AsyncAwait;
    await $redis->connect;
    $redis->set(some_key => 'some value');
    my ($value) = await $redis->get('some_key');
    print "Read back value [$value]\n";

See the next section for more information on what these methods are actually returning.

=head2 Requests and responses

Requests are implemented as methods on the L<Net::Async::Redis> object.
These typically return a L<Future> which will resolve once ready:

    my $future = $redis->incr("xyz")
        ->on_done(sub {
            print "result of increment was " . shift . "\n"
        });

For synchronous code, call C<< ->get >> on that L<Future>:

    print "Database has " . $redis->dbsize->get . " total keys\n";

This means you can end up with C<< ->get >> being called on the result of C<< ->get >>,
note that these are two very different methods:

 $redis
  ->get('some key') # this is being called on $redis, and is issuing a GET request
  ->get # this is called on the returned Future, and blocks until the value is ready

Typical async code would not be expected to use the L<Future/get> method extensively;
often only calling it in one place at the top level in the code.

=head3 RESP3 and RESP2 compatibility

In RESP3 some of the responses are structured differently from RESP2.
L<Net::Async::Redis> guarantees the same structure unless you have explicitly requested the new types
using the L</configure> C<hashrefs> option, which is disabled by default.

Generally RESP3 is recommended if you have Redis version 6 or later installed: it allows
subscription operations to share the same connection as regular Redis traffic.

=head2 Error handling

Since L<Future> is used for deferred results, failure is indicated
by a failing Future with L<failure category|Future/FAILURE-CATEGORIES>
of C<redis>.

The L<Future/catch> feature may be useful for handling these:

 $redis->lpush(key => $value)
     ->catch(
         redis => sub { warn "probably an incorrect type, cannot push value"; Future->done }
     )->get;

Note that this module uses L<Future::AsyncAwait> internally.

=head1 CONSTANTS

=head2 OPENTRACING_ENABLED

Defaults to false, this can be controlled by the C<USE_OPENTRACING>
environment variable. This provides a way to set the default opentracing
mode for all L<Net::Async::Redis> instances - you can enable/disable
for a specific instance via L</configure>:

 $redis->configure(opentracing => 1);

When enabled, this will create a span for every Redis request. See
L<OpenTracing::Any> for details.

=head1 METHODS

B<NOTE>: For a full list of the Redis methods supported by this module,
please see L<Net::Async::Redis::Commands>.

=head2 configure

Applies configuration parameters - currently supports:

=over 4

=item * C<host>

=item * C<port>

=item * C<auth>

=item * C<database>

=item * C<pipeline_depth>

=item * C<stream_read_len>

=item * C<stream_write_len>

=item * C<on_disconnect>

=item * C<client_name>

=item * C<opentracing>

=item * C<protocol> - either 'resp2' or 'resp3', default is autodetect

=item * C<hashrefs> - RESP3 (Redis 6.0+) supports more data types, currently the only difference this
makes to us is that it now supports hashrefs for key/value pairs. This is disabled by default to ensure
compatibility across newer+older versions.

=back

Note that enabling C<hashrefs> will cause connections to fail if the server does not support RESP3.

=head2 host

Returns the host or IP address for the Redis server.

=head2 port

Returns the port used for connecting to the Redis server.

=head2 database

Returns the database index used when connecting to the Redis server.

See the L<Net::Async::Redis::Commands/select> method for details.

=head2 uri

Returns the Redis endpoint L<URI> instance.

=head2 stream_read_len

Returns the buffer size when reading from a Redis connection.

Defaults to 1MB, reduce this if you're dealing with a lot of connections and
want to minimise memory usage. Alternatively, if you're reading large amounts
of data and spend too much time in needless C<epoll_wait> calls, try a larger
value.

=head2 stream_write_len

Returns the buffer size when writing to Redis connections, in bytes. Defaults to 1MB.

See L</stream_read_len>.

=head2 client_name

Returns the name used for this client when connecting.

=head1 METHODS - Connection

=head2 connect

Connects to the Redis server.

Will use the L</configure>d parameters if available, but as a convenience
can be passed additional parameters which will then be applied as if you
had called L</configure> with those beforehand. This also means that they
will be preserved for subsequent L</connect> calls.

=head2 connected

Establishes a connection if needed, otherwise returns an immediately-available
L<Future> instance.

=head2 endpoint

The string describing the remote endpoint.

=head2 local_endpoint

A string describing the local endpoint, usually C<host:port>.

=head1 METHODS - Subscriptions

See L<https://redis.io/topics/pubsub> for more details on this topic.
There's also more details on the internal implementation in Redis here:
L<https://making.pusher.com/redis-pubsub-under-the-hood/>.

B<NOTE>: On Redis versions prior to 6.0, you will need a I<separate> connection
for subscriptions; you cannot share a connection for regular requests once
any of the L</subscribe> or L</psubscribe> methods have been called on an
existing connection.

With Redis 6.0, a newer protocol version (RESP3) is used by default, and
this is quite happy to support pubsub activity on the same connection
as other traffic.

=head2 psubscribe

Subscribes to a pattern.

Example:

 # Subscribe to 'info::*' channels, i.e. any message
 # that starts with the C<info::> prefix, and prints them
 # with a timestamp.
 $redis_connection->psubscribe('info::*')
    ->then(sub {
        my $sub = shift;
        $sub->map('payload')
            ->each(sub {
             print localtime . ' ' . $_ . "\n";
            })->retain
    })->get;
 # this will block until the subscribe is confirmed. Note that you can't publish on
 # a connection that's handling subscriptions due to Redis protocol restrictions.
 $other_redis_connection->publish('info::example', 'a message here')->get;

Returns a L<Future> which resolves to a L<Net::Async::Redis::Subscription> instance.

=head2 subscribe

Subscribes to one or more channels.

Returns a L<Future> which resolves to a L<Net::Async::Redis::Subscription> instance.

Example:

 # Subscribe to 'notifications' channel,
 # print the first 5 messages, then unsubscribe
 $redis->subscribe('notifications')
    ->then(sub {
        my $sub = shift;
        $sub->events
            ->map('payload')
            ->take(5)
            ->say
            ->completed
    })->then(sub {
        $redis->unsubscribe('notifications')
    })->get

=head1 METHODS - Transactions

=head2 multi

Executes the given code in a Redis C<MULTI> transaction.

This will cause each of the requests to be queued on the server, then applied in a single
atomic transaction.

Note that the commands will resolve only after the transaction is committed: for example,
when the L</set> command is issued, Redis will return C<QUEUED>. This information
is B<not> used as the result - we only pass through the immediate
response if there was an error. The L<Future> representing
the response will be marked as done once the C<EXEC> command is applied and we have the
results back.

Example:

 $redis->multi(sub {
  my $tx = shift;
  $tx->incr('some::key')->on_done(sub { print "Final value for incremented key was " . shift . "\n"; });
  $tx->set('other::key => 'test data')
 })->then(sub {
  my ($success, $failure) = @_;
  return Future->fail("Had $failure failures, expecting everything to succeed") if $failure;
  print "$success succeeded\m";
  return Future->done;
 })->retain;

=head1 METHODS - Clientside caching

Enable clientside caching by passing a true value for C<client_side_caching_enabled> in
L</configure> or L</new>. This is currently B<experimental>, and only operates on
L<Net::Async::Redis::Commands/get> requests.

See L<https://redis.io/topics/client-side-caching> for more details on this feature.

=head2 clientside_cache_events

A L<Ryu::Source> which emits key names as they are invalidated.

With client-side caching enabled, can be used to monitor which keys
are changing.

=head2 client_side_cache_ready

Returns a L<Future> representing the client-side cache connection status,
if there is one.

=head2 client_side_cache

Returns the L<Cache::LRU> instance used for the client-side cache.

=head2 is_client_side_cache_enabled

Returns true if the client-side cache is enabled.

=head2 client_side_cache_size

Returns the current client-side cache size, as a number of entries.

=head1 METHODS - Generic

=head2 keys

=head2 watch_keyspace

A convenience wrapper around the keyspace notifications API.

Provides the necessary setup to establish a C<PSUBSCRIBE> subscription
on the C<__keyspace@*__> namespace, setting the configuration required
for this to start emitting events, and then calls C<$code> with each
event.

Note that this will switch the connection into pubsub mode on versions
of Redis older than 6.0, so it will no longer be available for any
other activity. This limitation does not apply on Redis 6 or above.

Use C<*> to listen for all keyspace changes.

Resolves to a L<Ryu::Source> instance.

=head2 pipeline_depth

Number of requests awaiting responses before we start queuing.
This defaults to an arbitrary value of 100 requests.

Note that this does not apply when in L<transaction|METHODS - Transactions> (C<MULTI>) mode.

See L<https://redis.io/topics/pipelining> for more details on this concept.

=head2 opentracing

Indicates whether L<OpenTracing::Any> support is enabled.

=head1 METHODS - Deprecated

This are still supported, but no longer recommended.

=head1 METHODS - Internal

=head2 on_message

Called for each incoming message.

Passes off the work to L</handle_pubsub_message> or the next queue
item, depending on whether we're dealing with subscriptions at the moment.

=head2 next_in_pipeline

Attempt to process next pending request when in pipeline mode.

=head2 on_error_message

Called when there's an error response.

=head2 handle_pubsub_message

Deal with an incoming pubsub-related message.

=head2 stream

Represents the L<IO::Async::Stream> instance for the active Redis connection.

=head2 notify_close

Called when the socket is closed.

=head2 command_label

Generate a label for the given command list.

=head2 execute_command

Queues or executes the given command.

=head2 ryu

A L<Ryu::Async> instance for source/sink creation.

=head2 future

Factory method for creating new L<Future> instances.

=head2 wire_protocol

Returns the L<Net::Async::Redis::Protocol> instance used for
encoding and decoding messages.

=head2 enable_clientside_cache

Used internally to prepare for client-side caching: subscribes to the
invalidation events.

=head2 _init

=head2 _add_to_loop

=head1 SEE ALSO

Some other Redis implementations on CPAN:

=over 4

=item * L<Mojo::Redis2> - nonblocking, using the L<Mojolicious> framework, actively maintained

=item * L<MojoX::Redis> - changelog mentions that this was obsoleted by L<Mojo::Redis>, although there
have been new versions released since then

=item * L<RedisDB> - another synchronous (blocking) implementation, handles pub/sub and autoreconnect

=item * L<Cache::Redis> - wrapper around L<RedisDB>

=item * L<Redis::Fast> - wraps C<hiredis>, faster than L<Redis>

=item * L<Redis::Jet> - also XS-based, docs mention C<very early development stage> but appears to support
pipelining and can handle newer commands via C<< ->command >>.

=item * L<Redis> - synchronous (blocking) implementation, handles pub/sub and autoreconnect

=item * L<HiRedis::Raw> - another C<hiredis> wrapper

=back

=head1 AUTHOR

Tom Molesworth <TEAM@cpan.org>

=head1 INHERITED METHODS

=over 4

=item L<Net::Async::Redis::Commands>

L<acl|Net::Async::Redis::Commands/acl>, L<acl_cat|Net::Async::Redis::Commands/acl_cat>, L<acl_deluser|Net::Async::Redis::Commands/acl_deluser>, L<acl_dryrun|Net::Async::Redis::Commands/acl_dryrun>, L<acl_genpass|Net::Async::Redis::Commands/acl_genpass>, L<acl_getuser|Net::Async::Redis::Commands/acl_getuser>, L<acl_list|Net::Async::Redis::Commands/acl_list>, L<acl_load|Net::Async::Redis::Commands/acl_load>, L<acl_log|Net::Async::Redis::Commands/acl_log>, L<acl_save|Net::Async::Redis::Commands/acl_save>, L<acl_setuser|Net::Async::Redis::Commands/acl_setuser>, L<acl_users|Net::Async::Redis::Commands/acl_users>, L<acl_whoami|Net::Async::Redis::Commands/acl_whoami>, L<append|Net::Async::Redis::Commands/append>, L<asking|Net::Async::Redis::Commands/asking>, L<auth|Net::Async::Redis::Commands/auth>, L<bgrewriteaof|Net::Async::Redis::Commands/bgrewriteaof>, L<bgsave|Net::Async::Redis::Commands/bgsave>, L<bitcount|Net::Async::Redis::Commands/bitcount>, L<bitfield|Net::Async::Redis::Commands/bitfield>, L<bitfield_ro|Net::Async::Redis::Commands/bitfield_ro>, L<bitop|Net::Async::Redis::Commands/bitop>, L<bitpos|Net::Async::Redis::Commands/bitpos>, L<blmove|Net::Async::Redis::Commands/blmove>, L<blmpop|Net::Async::Redis::Commands/blmpop>, L<blpop|Net::Async::Redis::Commands/blpop>, L<brpop|Net::Async::Redis::Commands/brpop>, L<brpoplpush|Net::Async::Redis::Commands/brpoplpush>, L<bzmpop|Net::Async::Redis::Commands/bzmpop>, L<bzpopmax|Net::Async::Redis::Commands/bzpopmax>, L<bzpopmin|Net::Async::Redis::Commands/bzpopmin>, L<client|Net::Async::Redis::Commands/client>, L<client_caching|Net::Async::Redis::Commands/client_caching>, L<client_getname|Net::Async::Redis::Commands/client_getname>, L<client_getredir|Net::Async::Redis::Commands/client_getredir>, L<client_id|Net::Async::Redis::Commands/client_id>, L<client_info|Net::Async::Redis::Commands/client_info>, L<client_kill|Net::Async::Redis::Commands/client_kill>, L<client_list|Net::Async::Redis::Commands/client_list>, L<client_no|Net::Async::Redis::Commands/client_no>, L<client_no_evict|Net::Async::Redis::Commands/client_no_evict>, L<client_pause|Net::Async::Redis::Commands/client_pause>, L<client_reply|Net::Async::Redis::Commands/client_reply>, L<client_setname|Net::Async::Redis::Commands/client_setname>, L<client_tracking|Net::Async::Redis::Commands/client_tracking>, L<client_trackinginfo|Net::Async::Redis::Commands/client_trackinginfo>, L<client_unblock|Net::Async::Redis::Commands/client_unblock>, L<client_unpause|Net::Async::Redis::Commands/client_unpause>, L<cluster|Net::Async::Redis::Commands/cluster>, L<cluster_addslots|Net::Async::Redis::Commands/cluster_addslots>, L<cluster_addslotsrange|Net::Async::Redis::Commands/cluster_addslotsrange>, L<cluster_bumpepoch|Net::Async::Redis::Commands/cluster_bumpepoch>, L<cluster_count|Net::Async::Redis::Commands/cluster_count>, L<cluster_count_failure|Net::Async::Redis::Commands/cluster_count_failure>, L<cluster_count_failure_reports|Net::Async::Redis::Commands/cluster_count_failure_reports>, L<cluster_countkeysinslot|Net::Async::Redis::Commands/cluster_countkeysinslot>, L<cluster_delslots|Net::Async::Redis::Commands/cluster_delslots>, L<cluster_delslotsrange|Net::Async::Redis::Commands/cluster_delslotsrange>, L<cluster_failover|Net::Async::Redis::Commands/cluster_failover>, L<cluster_flushslots|Net::Async::Redis::Commands/cluster_flushslots>, L<cluster_forget|Net::Async::Redis::Commands/cluster_forget>, L<cluster_getkeysinslot|Net::Async::Redis::Commands/cluster_getkeysinslot>, L<cluster_info|Net::Async::Redis::Commands/cluster_info>, L<cluster_keyslot|Net::Async::Redis::Commands/cluster_keyslot>, L<cluster_links|Net::Async::Redis::Commands/cluster_links>, L<cluster_meet|Net::Async::Redis::Commands/cluster_meet>, L<cluster_myid|Net::Async::Redis::Commands/cluster_myid>, L<cluster_nodes|Net::Async::Redis::Commands/cluster_nodes>, L<cluster_replicas|Net::Async::Redis::Commands/cluster_replicas>, L<cluster_replicate|Net::Async::Redis::Commands/cluster_replicate>, L<cluster_reset|Net::Async::Redis::Commands/cluster_reset>, L<cluster_saveconfig|Net::Async::Redis::Commands/cluster_saveconfig>, L<cluster_set|Net::Async::Redis::Commands/cluster_set>, L<cluster_set_config|Net::Async::Redis::Commands/cluster_set_config>, L<cluster_set_config_epoch|Net::Async::Redis::Commands/cluster_set_config_epoch>, L<cluster_setslot|Net::Async::Redis::Commands/cluster_setslot>, L<cluster_slaves|Net::Async::Redis::Commands/cluster_slaves>, L<cluster_slots|Net::Async::Redis::Commands/cluster_slots>, L<command|Net::Async::Redis::Commands/command>, L<command_count|Net::Async::Redis::Commands/command_count>, L<command_docs|Net::Async::Redis::Commands/command_docs>, L<command_getkeys|Net::Async::Redis::Commands/command_getkeys>, L<command_getkeysandflags|Net::Async::Redis::Commands/command_getkeysandflags>, L<command_info|Net::Async::Redis::Commands/command_info>, L<command_list|Net::Async::Redis::Commands/command_list>, L<config|Net::Async::Redis::Commands/config>, L<config_get|Net::Async::Redis::Commands/config_get>, L<config_resetstat|Net::Async::Redis::Commands/config_resetstat>, L<config_rewrite|Net::Async::Redis::Commands/config_rewrite>, L<config_set|Net::Async::Redis::Commands/config_set>, L<copy|Net::Async::Redis::Commands/copy>, L<dbsize|Net::Async::Redis::Commands/dbsize>, L<decr|Net::Async::Redis::Commands/decr>, L<decrby|Net::Async::Redis::Commands/decrby>, L<del|Net::Async::Redis::Commands/del>, L<dump|Net::Async::Redis::Commands/dump>, L<echo|Net::Async::Redis::Commands/echo>, L<eval|Net::Async::Redis::Commands/eval>, L<eval_ro|Net::Async::Redis::Commands/eval_ro>, L<evalsha|Net::Async::Redis::Commands/evalsha>, L<evalsha_ro|Net::Async::Redis::Commands/evalsha_ro>, L<exists|Net::Async::Redis::Commands/exists>, L<expire|Net::Async::Redis::Commands/expire>, L<expireat|Net::Async::Redis::Commands/expireat>, L<expiretime|Net::Async::Redis::Commands/expiretime>, L<failover|Net::Async::Redis::Commands/failover>, L<fcall|Net::Async::Redis::Commands/fcall>, L<fcall_ro|Net::Async::Redis::Commands/fcall_ro>, L<flushall|Net::Async::Redis::Commands/flushall>, L<flushdb|Net::Async::Redis::Commands/flushdb>, L<function|Net::Async::Redis::Commands/function>, L<function_delete|Net::Async::Redis::Commands/function_delete>, L<function_dump|Net::Async::Redis::Commands/function_dump>, L<function_flush|Net::Async::Redis::Commands/function_flush>, L<function_kill|Net::Async::Redis::Commands/function_kill>, L<function_list|Net::Async::Redis::Commands/function_list>, L<function_load|Net::Async::Redis::Commands/function_load>, L<function_restore|Net::Async::Redis::Commands/function_restore>, L<function_stats|Net::Async::Redis::Commands/function_stats>, L<geoadd|Net::Async::Redis::Commands/geoadd>, L<geodist|Net::Async::Redis::Commands/geodist>, L<geohash|Net::Async::Redis::Commands/geohash>, L<geopos|Net::Async::Redis::Commands/geopos>, L<georadius|Net::Async::Redis::Commands/georadius>, L<georadius_ro|Net::Async::Redis::Commands/georadius_ro>, L<georadiusbymember|Net::Async::Redis::Commands/georadiusbymember>, L<georadiusbymember_ro|Net::Async::Redis::Commands/georadiusbymember_ro>, L<geosearch|Net::Async::Redis::Commands/geosearch>, L<geosearchstore|Net::Async::Redis::Commands/geosearchstore>, L<getbit|Net::Async::Redis::Commands/getbit>, L<getdel|Net::Async::Redis::Commands/getdel>, L<getex|Net::Async::Redis::Commands/getex>, L<getrange|Net::Async::Redis::Commands/getrange>, L<getset|Net::Async::Redis::Commands/getset>, L<hdel|Net::Async::Redis::Commands/hdel>, L<hello|Net::Async::Redis::Commands/hello>, L<hexists|Net::Async::Redis::Commands/hexists>, L<hget|Net::Async::Redis::Commands/hget>, L<hgetall|Net::Async::Redis::Commands/hgetall>, L<hincrby|Net::Async::Redis::Commands/hincrby>, L<hincrbyfloat|Net::Async::Redis::Commands/hincrbyfloat>, L<hkeys|Net::Async::Redis::Commands/hkeys>, L<hlen|Net::Async::Redis::Commands/hlen>, L<hmget|Net::Async::Redis::Commands/hmget>, L<hmset|Net::Async::Redis::Commands/hmset>, L<hrandfield|Net::Async::Redis::Commands/hrandfield>, L<hscan|Net::Async::Redis::Commands/hscan>, L<hset|Net::Async::Redis::Commands/hset>, L<hsetnx|Net::Async::Redis::Commands/hsetnx>, L<hstrlen|Net::Async::Redis::Commands/hstrlen>, L<hvals|Net::Async::Redis::Commands/hvals>, L<incr|Net::Async::Redis::Commands/incr>, L<incrby|Net::Async::Redis::Commands/incrby>, L<incrbyfloat|Net::Async::Redis::Commands/incrbyfloat>, L<info|Net::Async::Redis::Commands/info>, L<lastsave|Net::Async::Redis::Commands/lastsave>, L<latency|Net::Async::Redis::Commands/latency>, L<latency_doctor|Net::Async::Redis::Commands/latency_doctor>, L<latency_graph|Net::Async::Redis::Commands/latency_graph>, L<latency_histogram|Net::Async::Redis::Commands/latency_histogram>, L<latency_history|Net::Async::Redis::Commands/latency_history>, L<latency_latest|Net::Async::Redis::Commands/latency_latest>, L<latency_reset|Net::Async::Redis::Commands/latency_reset>, L<lcs|Net::Async::Redis::Commands/lcs>, L<lindex|Net::Async::Redis::Commands/lindex>, L<linsert|Net::Async::Redis::Commands/linsert>, L<llen|Net::Async::Redis::Commands/llen>, L<lmove|Net::Async::Redis::Commands/lmove>, L<lmpop|Net::Async::Redis::Commands/lmpop>, L<lolwut|Net::Async::Redis::Commands/lolwut>, L<lpop|Net::Async::Redis::Commands/lpop>, L<lpos|Net::Async::Redis::Commands/lpos>, L<lpush|Net::Async::Redis::Commands/lpush>, L<lpushx|Net::Async::Redis::Commands/lpushx>, L<lrange|Net::Async::Redis::Commands/lrange>, L<lrem|Net::Async::Redis::Commands/lrem>, L<lset|Net::Async::Redis::Commands/lset>, L<ltrim|Net::Async::Redis::Commands/ltrim>, L<memory|Net::Async::Redis::Commands/memory>, L<memory_doctor|Net::Async::Redis::Commands/memory_doctor>, L<memory_malloc|Net::Async::Redis::Commands/memory_malloc>, L<memory_malloc_stats|Net::Async::Redis::Commands/memory_malloc_stats>, L<memory_purge|Net::Async::Redis::Commands/memory_purge>, L<memory_stats|Net::Async::Redis::Commands/memory_stats>, L<memory_usage|Net::Async::Redis::Commands/memory_usage>, L<mget|Net::Async::Redis::Commands/mget>, L<migrate|Net::Async::Redis::Commands/migrate>, L<module|Net::Async::Redis::Commands/module>, L<module_list|Net::Async::Redis::Commands/module_list>, L<module_load|Net::Async::Redis::Commands/module_load>, L<module_unload|Net::Async::Redis::Commands/module_unload>, L<monitor|Net::Async::Redis::Commands/monitor>, L<move|Net::Async::Redis::Commands/move>, L<mset|Net::Async::Redis::Commands/mset>, L<msetnx|Net::Async::Redis::Commands/msetnx>, L<object|Net::Async::Redis::Commands/object>, L<object_encoding|Net::Async::Redis::Commands/object_encoding>, L<object_freq|Net::Async::Redis::Commands/object_freq>, L<object_idletime|Net::Async::Redis::Commands/object_idletime>, L<object_refcount|Net::Async::Redis::Commands/object_refcount>, L<persist|Net::Async::Redis::Commands/persist>, L<pexpire|Net::Async::Redis::Commands/pexpire>, L<pexpireat|Net::Async::Redis::Commands/pexpireat>, L<pexpiretime|Net::Async::Redis::Commands/pexpiretime>, L<pfadd|Net::Async::Redis::Commands/pfadd>, L<pfcount|Net::Async::Redis::Commands/pfcount>, L<pfdebug|Net::Async::Redis::Commands/pfdebug>, L<pfmerge|Net::Async::Redis::Commands/pfmerge>, L<pfselftest|Net::Async::Redis::Commands/pfselftest>, L<ping|Net::Async::Redis::Commands/ping>, L<psetex|Net::Async::Redis::Commands/psetex>, L<psync|Net::Async::Redis::Commands/psync>, L<pttl|Net::Async::Redis::Commands/pttl>, L<publish|Net::Async::Redis::Commands/publish>, L<pubsub|Net::Async::Redis::Commands/pubsub>, L<pubsub_channels|Net::Async::Redis::Commands/pubsub_channels>, L<pubsub_numpat|Net::Async::Redis::Commands/pubsub_numpat>, L<pubsub_numsub|Net::Async::Redis::Commands/pubsub_numsub>, L<pubsub_shardchannels|Net::Async::Redis::Commands/pubsub_shardchannels>, L<punsubscribe|Net::Async::Redis::Commands/punsubscribe>, L<quit|Net::Async::Redis::Commands/quit>, L<randomkey|Net::Async::Redis::Commands/randomkey>, L<readonly|Net::Async::Redis::Commands/readonly>, L<readwrite|Net::Async::Redis::Commands/readwrite>, L<rename|Net::Async::Redis::Commands/rename>, L<renamenx|Net::Async::Redis::Commands/renamenx>, L<replconf|Net::Async::Redis::Commands/replconf>, L<replicaof|Net::Async::Redis::Commands/replicaof>, L<reset|Net::Async::Redis::Commands/reset>, L<restore|Net::Async::Redis::Commands/restore>, L<restore_asking|Net::Async::Redis::Commands/restore_asking>, L<role|Net::Async::Redis::Commands/role>, L<rpop|Net::Async::Redis::Commands/rpop>, L<rpoplpush|Net::Async::Redis::Commands/rpoplpush>, L<rpush|Net::Async::Redis::Commands/rpush>, L<rpushx|Net::Async::Redis::Commands/rpushx>, L<sadd|Net::Async::Redis::Commands/sadd>, L<save|Net::Async::Redis::Commands/save>, L<scan|Net::Async::Redis::Commands/scan>, L<scard|Net::Async::Redis::Commands/scard>, L<script|Net::Async::Redis::Commands/script>, L<script_debug|Net::Async::Redis::Commands/script_debug>, L<script_exists|Net::Async::Redis::Commands/script_exists>, L<script_flush|Net::Async::Redis::Commands/script_flush>, L<script_kill|Net::Async::Redis::Commands/script_kill>, L<script_load|Net::Async::Redis::Commands/script_load>, L<sdiff|Net::Async::Redis::Commands/sdiff>, L<sdiffstore|Net::Async::Redis::Commands/sdiffstore>, L<select|Net::Async::Redis::Commands/select>, L<set|Net::Async::Redis::Commands/set>, L<setbit|Net::Async::Redis::Commands/setbit>, L<setex|Net::Async::Redis::Commands/setex>, L<setnx|Net::Async::Redis::Commands/setnx>, L<setrange|Net::Async::Redis::Commands/setrange>, L<shutdown|Net::Async::Redis::Commands/shutdown>, L<sinter|Net::Async::Redis::Commands/sinter>, L<sintercard|Net::Async::Redis::Commands/sintercard>, L<sinterstore|Net::Async::Redis::Commands/sinterstore>, L<sismember|Net::Async::Redis::Commands/sismember>, L<slaveof|Net::Async::Redis::Commands/slaveof>, L<slowlog|Net::Async::Redis::Commands/slowlog>, L<slowlog_get|Net::Async::Redis::Commands/slowlog_get>, L<slowlog_len|Net::Async::Redis::Commands/slowlog_len>, L<slowlog_reset|Net::Async::Redis::Commands/slowlog_reset>, L<smembers|Net::Async::Redis::Commands/smembers>, L<smismember|Net::Async::Redis::Commands/smismember>, L<smove|Net::Async::Redis::Commands/smove>, L<sort|Net::Async::Redis::Commands/sort>, L<sort_ro|Net::Async::Redis::Commands/sort_ro>, L<spop|Net::Async::Redis::Commands/spop>, L<spublish|Net::Async::Redis::Commands/spublish>, L<srandmember|Net::Async::Redis::Commands/srandmember>, L<srem|Net::Async::Redis::Commands/srem>, L<sscan|Net::Async::Redis::Commands/sscan>, L<ssubscribe|Net::Async::Redis::Commands/ssubscribe>, L<strlen|Net::Async::Redis::Commands/strlen>, L<substr|Net::Async::Redis::Commands/substr>, L<sunion|Net::Async::Redis::Commands/sunion>, L<sunionstore|Net::Async::Redis::Commands/sunionstore>, L<sunsubscribe|Net::Async::Redis::Commands/sunsubscribe>, L<swapdb|Net::Async::Redis::Commands/swapdb>, L<sync|Net::Async::Redis::Commands/sync>, L<time|Net::Async::Redis::Commands/time>, L<touch|Net::Async::Redis::Commands/touch>, L<ttl|Net::Async::Redis::Commands/ttl>, L<type|Net::Async::Redis::Commands/type>, L<unlink|Net::Async::Redis::Commands/unlink>, L<unsubscribe|Net::Async::Redis::Commands/unsubscribe>, L<unwatch|Net::Async::Redis::Commands/unwatch>, L<wait|Net::Async::Redis::Commands/wait>, L<watch|Net::Async::Redis::Commands/watch>, L<xack|Net::Async::Redis::Commands/xack>, L<xadd|Net::Async::Redis::Commands/xadd>, L<xautoclaim|Net::Async::Redis::Commands/xautoclaim>, L<xclaim|Net::Async::Redis::Commands/xclaim>, L<xdel|Net::Async::Redis::Commands/xdel>, L<xgroup|Net::Async::Redis::Commands/xgroup>, L<xgroup_create|Net::Async::Redis::Commands/xgroup_create>, L<xgroup_createconsumer|Net::Async::Redis::Commands/xgroup_createconsumer>, L<xgroup_delconsumer|Net::Async::Redis::Commands/xgroup_delconsumer>, L<xgroup_destroy|Net::Async::Redis::Commands/xgroup_destroy>, L<xgroup_setid|Net::Async::Redis::Commands/xgroup_setid>, L<xinfo|Net::Async::Redis::Commands/xinfo>, L<xinfo_consumers|Net::Async::Redis::Commands/xinfo_consumers>, L<xinfo_groups|Net::Async::Redis::Commands/xinfo_groups>, L<xinfo_stream|Net::Async::Redis::Commands/xinfo_stream>, L<xlen|Net::Async::Redis::Commands/xlen>, L<xpending|Net::Async::Redis::Commands/xpending>, L<xrange|Net::Async::Redis::Commands/xrange>, L<xrevrange|Net::Async::Redis::Commands/xrevrange>, L<xsetid|Net::Async::Redis::Commands/xsetid>, L<xtrim|Net::Async::Redis::Commands/xtrim>, L<zadd|Net::Async::Redis::Commands/zadd>, L<zcard|Net::Async::Redis::Commands/zcard>, L<zcount|Net::Async::Redis::Commands/zcount>, L<zdiff|Net::Async::Redis::Commands/zdiff>, L<zdiffstore|Net::Async::Redis::Commands/zdiffstore>, L<zincrby|Net::Async::Redis::Commands/zincrby>, L<zinter|Net::Async::Redis::Commands/zinter>, L<zintercard|Net::Async::Redis::Commands/zintercard>, L<zinterstore|Net::Async::Redis::Commands/zinterstore>, L<zlexcount|Net::Async::Redis::Commands/zlexcount>, L<zmpop|Net::Async::Redis::Commands/zmpop>, L<zmscore|Net::Async::Redis::Commands/zmscore>, L<zpopmax|Net::Async::Redis::Commands/zpopmax>, L<zpopmin|Net::Async::Redis::Commands/zpopmin>, L<zrandmember|Net::Async::Redis::Commands/zrandmember>, L<zrangebylex|Net::Async::Redis::Commands/zrangebylex>, L<zrangestore|Net::Async::Redis::Commands/zrangestore>, L<zrank|Net::Async::Redis::Commands/zrank>, L<zrem|Net::Async::Redis::Commands/zrem>, L<zremrangebylex|Net::Async::Redis::Commands/zremrangebylex>, L<zremrangebyrank|Net::Async::Redis::Commands/zremrangebyrank>, L<zremrangebyscore|Net::Async::Redis::Commands/zremrangebyscore>, L<zrevrangebylex|Net::Async::Redis::Commands/zrevrangebylex>, L<zrevrank|Net::Async::Redis::Commands/zrevrank>, L<zscan|Net::Async::Redis::Commands/zscan>, L<zscore|Net::Async::Redis::Commands/zscore>, L<zunion|Net::Async::Redis::Commands/zunion>, L<zunionstore|Net::Async::Redis::Commands/zunionstore>

=item L<IO::Async::Notifier>

L<add_child|IO::Async::Notifier/add_child>, L<adopt_future|IO::Async::Notifier/adopt_future>, L<adopted_futures|IO::Async::Notifier/adopted_futures>, L<can_event|IO::Async::Notifier/can_event>, L<children|IO::Async::Notifier/children>, L<configure_unknown|IO::Async::Notifier/configure_unknown>, L<debug_printf|IO::Async::Notifier/debug_printf>, L<get_loop|IO::Async::Notifier/get_loop>, L<invoke_error|IO::Async::Notifier/invoke_error>, L<invoke_event|IO::Async::Notifier/invoke_event>, L<loop|IO::Async::Notifier/loop>, L<make_event_cb|IO::Async::Notifier/make_event_cb>, L<maybe_invoke_event|IO::Async::Notifier/maybe_invoke_event>, L<maybe_make_event_cb|IO::Async::Notifier/maybe_make_event_cb>, L<new|IO::Async::Notifier/new>, L<notifier_name|IO::Async::Notifier/notifier_name>, L<parent|IO::Async::Notifier/parent>, L<remove_child|IO::Async::Notifier/remove_child>, L<remove_from_parent|IO::Async::Notifier/remove_from_parent>

=back

=head1 CONTRIBUTORS

With thanks to the following for contributing patches, bug reports,
tests and feedback:

=over 4

=item * C<BINARY@cpan.org>

=item * C<PEVANS@cpan.org>

=item * C<@eyadof>

=item * Nael Alolwani

=item * Marc Frank

=back

=head1 LICENSE

Copyright Tom Molesworth and others 2015-2022.
Licensed under the same terms as Perl itself.

