=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);
    (async sub {
     await $redis->connect;
     my $value = await $redis->get('some_key');
     $value ||= await $redis->set(some_key => 'some_value');
     print "Value: $value";
    })->()->get;

    # 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;

    # ... or with Future::AsyncAwait (recommended)
    await $redis->connect;
    my $value = await $redis->get('some_key');
    $value ||= await $redis->set(some_key => 'some_value');
    print "Value: $value";

=head1 DESCRIPTION

Provides client access for dealing with Redis servers.

See 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.
It 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 6.0.7 (August 2020), 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>

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

    $redis->connect
        ->then(sub {
            # You could achieve a similar result by passing client_name in
            # constructor or ->connect parameters
            $redis->client_setname("example client")
        })->get;

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

 $redis->set(some_key => 'some value')
  ->then(sub {
   $redis->get('some_key')
  })->on_done(sub {
   my ($value) = @_;
   print "Read back value [$value]\n";
  })->retain;

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.

=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>.

=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/>.

=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.

=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, so it will
no longer be available for any other activity.

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

=head2 endpoint

The string describing the remote endpoint.

=head2 local_endpoint

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

=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 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 stream

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

=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 notify_close

Called when the socket is closed.

=head2 command_label

Generate a label for the given command list.

=head2 stream_read_len

Defines 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

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

See L</stream_read_len>.

=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>

=back

=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

=back

=head1 AUTHOR

Tom Molesworth <TEAM@cpan.org>

=head1 INHERITED METHODS

=over 4

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

L<acl_cat|Net::Async::Redis::Commands/acl_cat>, L<acl_deluser|Net::Async::Redis::Commands/acl_deluser>, L<acl_genpass|Net::Async::Redis::Commands/acl_genpass>, L<acl_getuser|Net::Async::Redis::Commands/acl_getuser>, L<acl_help|Net::Async::Redis::Commands/acl_help>, 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<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<bitop|Net::Async::Redis::Commands/bitop>, L<bitpos|Net::Async::Redis::Commands/bitpos>, L<blpop|Net::Async::Redis::Commands/blpop>, L<brpop|Net::Async::Redis::Commands/brpop>, L<brpoplpush|Net::Async::Redis::Commands/brpoplpush>, L<bzpopmax|Net::Async::Redis::Commands/bzpopmax>, L<bzpopmin|Net::Async::Redis::Commands/bzpopmin>, 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_kill|Net::Async::Redis::Commands/client_kill>, L<client_list|Net::Async::Redis::Commands/client_list>, 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_unblock|Net::Async::Redis::Commands/client_unblock>, L<cluster_addslots|Net::Async::Redis::Commands/cluster_addslots>, L<cluster_bumpepoch|Net::Async::Redis::Commands/cluster_bumpepoch>, 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_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_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_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_getkeys|Net::Async::Redis::Commands/command_getkeys>, L<command_info|Net::Async::Redis::Commands/command_info>, 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<dbsize|Net::Async::Redis::Commands/dbsize>, L<debug_object|Net::Async::Redis::Commands/debug_object>, L<debug_segfault|Net::Async::Redis::Commands/debug_segfault>, 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<evalsha|Net::Async::Redis::Commands/evalsha>, L<exists|Net::Async::Redis::Commands/exists>, L<expire|Net::Async::Redis::Commands/expire>, L<expireat|Net::Async::Redis::Commands/expireat>, L<flushall|Net::Async::Redis::Commands/flushall>, L<flushdb|Net::Async::Redis::Commands/flushdb>, 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<georadiusbymember|Net::Async::Redis::Commands/georadiusbymember>, L<getbit|Net::Async::Redis::Commands/getbit>, 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<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_doctor|Net::Async::Redis::Commands/latency_doctor>, L<latency_graph|Net::Async::Redis::Commands/latency_graph>, L<latency_help|Net::Async::Redis::Commands/latency_help>, 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<lindex|Net::Async::Redis::Commands/lindex>, L<linsert|Net::Async::Redis::Commands/linsert>, L<llen|Net::Async::Redis::Commands/llen>, 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_doctor|Net::Async::Redis::Commands/memory_doctor>, L<memory_help|Net::Async::Redis::Commands/memory_help>, 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_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<persist|Net::Async::Redis::Commands/persist>, L<pexpire|Net::Async::Redis::Commands/pexpire>, L<pexpireat|Net::Async::Redis::Commands/pexpireat>, L<pfadd|Net::Async::Redis::Commands/pfadd>, L<pfcount|Net::Async::Redis::Commands/pfcount>, L<pfmerge|Net::Async::Redis::Commands/pfmerge>, 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<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<replicaof|Net::Async::Redis::Commands/replicaof>, L<restore|Net::Async::Redis::Commands/restore>, 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_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<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<smembers|Net::Async::Redis::Commands/smembers>, L<smove|Net::Async::Redis::Commands/smove>, L<sort|Net::Async::Redis::Commands/sort>, L<spop|Net::Async::Redis::Commands/spop>, L<srandmember|Net::Async::Redis::Commands/srandmember>, L<srem|Net::Async::Redis::Commands/srem>, L<sscan|Net::Async::Redis::Commands/sscan>, L<stralgo|Net::Async::Redis::Commands/stralgo>, L<strlen|Net::Async::Redis::Commands/strlen>, L<sunion|Net::Async::Redis::Commands/sunion>, L<sunionstore|Net::Async::Redis::Commands/sunionstore>, 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<xclaim|Net::Async::Redis::Commands/xclaim>, L<xdel|Net::Async::Redis::Commands/xdel>, L<xgroup|Net::Async::Redis::Commands/xgroup>, L<xinfo|Net::Async::Redis::Commands/xinfo>, L<xlen|Net::Async::Redis::Commands/xlen>, L<xpending|Net::Async::Redis::Commands/xpending>, L<xrange|Net::Async::Redis::Commands/xrange>, L<xread|Net::Async::Redis::Commands/xread>, L<xreadgroup|Net::Async::Redis::Commands/xreadgroup>, L<xrevrange|Net::Async::Redis::Commands/xrevrange>, 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<zincrby|Net::Async::Redis::Commands/zincrby>, L<zinterstore|Net::Async::Redis::Commands/zinterstore>, L<zlexcount|Net::Async::Redis::Commands/zlexcount>, L<zpopmax|Net::Async::Redis::Commands/zpopmax>, L<zpopmin|Net::Async::Redis::Commands/zpopmin>, L<zrange|Net::Async::Redis::Commands/zrange>, L<zrangebylex|Net::Async::Redis::Commands/zrangebylex>, L<zrangebyscore|Net::Async::Redis::Commands/zrangebyscore>, 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<zrevrange|Net::Async::Redis::Commands/zrevrange>, L<zrevrangebylex|Net::Async::Redis::Commands/zrevrangebylex>, L<zrevrangebyscore|Net::Async::Redis::Commands/zrevrangebyscore>, L<zrevrank|Net::Async::Redis::Commands/zrevrank>, L<zscan|Net::Async::Redis::Commands/zscan>, L<zscore|Net::Async::Redis::Commands/zscore>, 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

=back

=head1 LICENSE

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

