NAME
   Riak::Client - Fast and lightweight Perl client for Riak

VERSION
   version 1.94

SYNOPSIS
     use Riak::Client;

     # normal mode
     my $client = Riak::Client->new(
       host => '127.0.0.1',
       port => 8087,
       r => 2,
       w => 2,
       dw => 1,
       connection_timeout => 5,
       read_timeout => 5,
       write_timeout => 5,
       no_auto_connect => 0,
     );

     # AnyEvent mode
     my $client = Riak::Client->new(
       host => '127.0.0.1',
       port => 8087
       anyevent_mode => 1,
     );

     $client->is_alive() or die "riak is not alive";

     # store hashref. will be serialized as JSON
     $client->put( 'bucket_name', 'key_name', { some => 'structure' } );

     # store text
     $client->put( 'bucket_name', 'key_name', 'sometext', 'text/plain' );

     # store raw data
     $client->put_raw( 'bucket_name', 'key_name', 'rawdata' );

     # fetch hashref
     my $hash = $client->get( 'bucket_name', 'key_name' );

     # fetch raw data
     my $text = $client->get_raw( 'bucket_name', 'key_name');

     # delete data
     $client->del( 'bucket_name', 'key_name');

     # AnyEvent mode
     my $cv = AE::cv
     $client->get_raw( 'bucket_name', 'key_name'
                       sub { do_something_with($_[0]);
                             $cv->send();
                       }
                 );
     # ... later one
     $cv->recv();

     # list keys in stream
     $client->get_keys(foo => sub{
        my ($key, $done) = @_;

        # you should use another client inside this callback!
        $another_client->del(foo => $key);

     });

DESCRIPTION
   Riak::Client is a fast and light Perl client for Riak using PBC
   interface, with optional AnyEvent mode.

   It supports operations like ping, get, exists, put, del, secondary
   indexes (so-called 2i) setting and querying, and Map Reduce querying.

   It has two modes, a traditional procedural mode, and an event based
   mode, using AnyEvent.

   It started as a fork of "Riak::Light" to fix some bugs, but actually
   ended up in a complete rewrite with more features, but the same
   performance.

ATTRIBUTES
 anyevent_mode
   Enables the AnyEvent mode, allowing true asynchronous mode.

 host
   Str, Required. Riak IP or hostname.

 port
   Int, Required. Port of the PBC interface.

 r
   Int, Default 2. R value setting for this client.

 w
   Int, Default 2. W value setting for this client.

 dw
   Int, Default 1. DW value setting for this client.

 connection_timeout
   Float, Default 5. Timeout for connection operation, in seconds. Set to 0
   for no timeout.

 read_timeout
   Float, Default 5. Timeout for read operation, in seconds. Set to 0 for
   no timeout.

 no_delay
   Boolean, Default 0. If set to a true value, TCP_NODELAY will be enabled
   on the socket, which means deactivating Nagle's algorithm. Use only if
   you know what you're doing.

 no_auto_connect
   Bool, Default 0. If set to true, then the module won't automatically
   connect upon instanciation. Instead, you'll have to call "connect()"
   yourself.

 anyevent_mode
   Bool, Default 0. If set to true, then all methods can receive a
   callback, as last argument. If present, the method will return
   immediately, and the callback will be executed upon completion of the
   operation, receiving a condvar as first and only argument. If set to
   false (the default), then the client instance will be synchronous.

METHODS
 connect
     $client->connect();
     $client->connect($coderef);

   Connects to the Riak server. On error, will raise an exception. This is
   automatically done when "new()" is called, unless the "no_auto_connect"
   attribute is set to true. Accepts an optional callback, that will be
   executed when connected.

     # example in AnyEvent mode
     $cv = AE::cv;
     $client->connect(sub { print "connected!\n"; $cv->send(); });
     # ...
     $cv->recv();

 ping
    my $result = $client->ping();
    $client->ping($coderef);

   Performs a ping operation. On error, will raise an exception. Accepts an
   optional callback, that will be executed upon completion

     # example in AnyEvent mode
     $cv = AE::cv;
     $client->ping(sub { print "got $_[0] \n"; $cv->send(); });
     # ...
     $cv->recv();

     # an other example
     use Try::Tiny;
     try { $client->ping() } catch { "oops... something is wrong: $_" };

   See also "is_alive()".

 is_alive
    my $is_alive = $client->is_alive();
    $client->is_alive($coderef);

   Checks if the connection is alive. Returns true or false. On error, will
   raise an exception. Accepts an optional callback, that will be executed
   upon completion. Even in AnyEvent mode, this operation is synchronous.

     # example in AnyEvent mode
     $cv = AE::cv;
     $client->is_alive(sub { print($_[0] ? "alive\n" : "dead\n"); $cv->send(); });
     # ...
     $cv->recv();

 get
     my $value = $client->get($bucket, $key);
     $client->get($bucket, $key, $coderef);

     # example in AnyEvent mode
     $cv = AE::cv;
     $client->get('bucket', 'key', sub { do_stuff_with_value($_[0]); $cv->send() });
     # ...
     $cv->recv();

   Performs a fetch operation. Expects bucket and key names. Returns the
   value. On error, will raise an exception. Accepts an optional callback,
   that will be called upon completion, with the value as first argument.
   If the content_type of the fetched value is 'application/json',
   automatically decodes the JSON into a Perl structure. If you need the
   raw data you can use "get_raw".

 get_raw
     my $value = $client->get_raw($bucket, $key);
     $client->get_raw($bucket, $key, $coderef);

   Same as "get", but no automatic JSON decoding will be performed. If you
   want JSON to be automatically decoded, you should use "get()" instead.

 put
     $client->put($bucket, $key, $value);
     $client->put($bucket, $key, $value, $coderef);
     $client->put($bucket, $key, $value, $mime_type, $coderef);
     $client->put($bucket, $key, $value, $mime_type, $secondary_indexes, $coderef);
     $client->put($bucket, $key, $value, $mime_type, $secondary_indexes, $links, $coderef);

   Performs a store operation. Expects bucket and key names, the value, the
   content type (optional, default is 'application/json'), the indexes to
   set for this value (optional, default is none), the links to set for
   this value (optional, default is none), and an optional coderef. On
   error, will raise an exception

   Will encode the structure in json string if necessary. If you need to
   store the raw data you should use "put_raw" instead.

   IMPORTANT: all the index field names should end by either "_int" or
   "_bin", depending if the index type is integer or binary.

   To query secondary indexes, see "query_index".

     $client->put('bucket', 'key', { some_values => [1,2,3] });
     $client->put('bucket', 'key', { some_values => [1,2,3] }, 'application/json);
     $client->put('bucket', 'key', 'text', 'plain/text');

     # you can set secondary indexes (2i)
     $client->put( 'bucket', 'key', 'text_value', 'plain/text',
                   { field1_bin => 'abc', field2_int => 42 }
                 );
     $client->put( 'bucket', 'key', { some_values => [1,2,3] }, undef,
                   { field1_bin => 'abc', field2_int => 42 }
                 );

     # you can also set links
     $client->put( 'bucket', 'key', 'text', 'plain/text', undef,
                   { link_tag1 => 'bucket/key',
                     link_tag2 => 'other_bucket/key',
                   }
                 );

     # you can set multiple links for the same tag
     $client->put( 'bucket', 'key', 'text', 'plain/text', undef,
                   { link_tag1 => [ qw( bucket/key bucket2/key2 ) ],
                     link_tag2 => 'other_bucket/key',
                   }
                 );

     # you can also use this form (marginally faster)
     $client->put( 'bucket', 'key', 'text', 'plain/text', undef,
                   [ { tag => 'link_tag1', bucket => 'bucket1', key => 'key1'},
                     { tag => 'link_tag2', bucket => 'bucket2', key => 'key2'},
                   ],
                 );

     # example in AnyEvent mode
     $cv = AE::cv;
     $client->put( 'bucket', 'key', 'some_text', 'plain/text',
                   { field1_bin => 'abc', field2_int => 42 },
                   { next_key => 'bucket2/foo'},
                   sub { print "data is sent to Riak\n"; $cv->send() },
                 );
     # ...
     $cv->recv();

 put_raw
     $client->put_raw('bucket', 'key', encode_json({ some_values => [1,2,3] }), 'application/json');
     $client->put_raw('bucket', 'key', 'text');
     $client->put_raw('bucket', 'key', 'text', undef, {field_bin => 'foo'});
     $client->put_raw('bucket', 'key', 'text', undef, {field_bin => 'foo'}, $links);

   For more example, see "put".

   Perform a store operation. Expects bucket and key names, the value, the
   content type (optional, default is 'plain/text'), the indexes (optional,
   default is none), and links (optional, default is none) to set for this
   value

   This method won't encode the data, but pass it as such, trusting it's in
   the type you've indicated in the passed content-type. If you want the
   structure to be automatically encoded, use "put" instead.

   IMPORTANT: all the index field names should end by either "_int" or
   "_bin", depending if the index type is integer or binary.

   To query secondary indexes, see "query_index".

 del
     $client->del(bucket => key);

   Perform a delete operation. Expects bucket and key names.

 get_keys
     # in default mode
     $client->get_keys(foo => sub{
        my ($key, $done) = @_;
        # you should use another client inside this callback!
        $another_client->del(foo => $key);
     });

     # in anyevent mode
     my $cv = AE::cv;
     $client->get_keys(foo => sub{
        my ($key, $done) = @_;
        # ... do stuff with $key
        $done and $cv->send;
     });
     $cv->recv();

   WARNING, this method should not be called on a production Riak cluster,
   as it can have a big performance impact. See Riak's documentation.

   WARNING, because Riak doesn't handles pipelining, you cannot use the
   same "Riak::Client" instance inside the callback, it would raise an
   exception.

   Perform a list keys operation. Receive a callback and will call it for
   each key. The callback will receive two arguments: the key, and a
   boolean indicating if it's the last key

   The callback is optional, in which case an ArrayRef of all the keys are
   returned. But don't do that, and always provide a callback, to avoid
   your RAM usage to skyrocket...

 exists
     $client->exists(bucket => 'key') or warn "key not found";

   Perform a fetch operation but with head => 0, and the if there is
   something stored in the bucket/key.

 query_index
   Perform a secondary index (2i) query. Expects a bucket name, the index
   field name, the index value you're searching on, and optionally a
   callback.

   If a callback has been provided, doesn't return anything, but execute
   the callback on each matching keys. callback will receive the key name
   as first argument. key name will also be in $_. If no callback is
   provided, returns and ArrayRef of matching keys.

   The index value you're searching on can be of two types. If it's a
   Scalar, an exact match query will be performed. if the value is an
   ArrayRef, then a range query will be performed, the first element in the
   array will be the range_min, the second element the range_max. other
   elements will be ignored.

   Based on the example in "put", here is how to query it:

     # exact match
     my $matching_keys = $client->query_index( 'bucket',  'field2_int', 42 ),

     # range match
     my $matching_keys = $client->query_index( 'bucket',  'field2_int', [ 40, 50] ),

     # range match with callback
     $client->query_index( 'bucket',  'field2_int', [ 40, 50], sub { print "key : $_" } ),

 get_buckets
   WARNING, this method should not be called on a production Riak cluster,
   as it can have a big performance impact. See Riak's documentation.

 get_bucket_props
 set_bucket_props
 map_reduce
 map_reduce_raw
BENCHMARKS
   Note: These benchmarks are the one provided by "Riak::Light".

   Note: the AnyEvent mode is a bit slower below, because we are forcing
   synchronous mode, even in AnyEvent, so the benchmark is paying the price
   of having AnyEvent enabled but not used.

 GETS
                                     Rate Data::Riak (REST) Riak::Tiny (REST) Net::Riak (REST) Data::Riak::Fast (REST) Net::Riak (PBC) Riak::Client (PBC + AnyEvent) Riak::Light (PBC) Riak::Client (PBC)
     Data::Riak (REST)              427/s                --              -30%             -31%                    -43%            -65%                          -85%              -90%               -91%
     Riak::Tiny (REST)              611/s               43%                --              -2%                    -19%            -51%                          -79%              -86%               -87%
     Net::Riak (REST)               623/s               46%                2%               --                    -17%            -50%                          -78%              -86%               -87%
     Data::Riak::Fast (REST)        755/s               77%               24%              21%                      --            -39%                          -74%              -83%               -84%
     Net::Riak (PBC)               1238/s              190%              103%              99%                     64%              --                          -57%              -72%               -74%
     Riak::Client (PBC + AnyEvent) 2878/s              573%              371%             362%                    281%            132%                            --              -34%               -39%
     Riak::Light (PBC)             4348/s              917%              612%             598%                    476%            251%                           51%                --                -8%
     Riak::Client (PBC)            4706/s             1001%              671%             655%                    524%            280%                           64%                8%                 --

 PUTS
                                     Rate Net::Riak (REST) Data::Riak (REST) Riak::Tiny (REST) Data::Riak::Fast (REST) Net::Riak (PBC) Riak::Light (PBC) Riak::Client (PBC + AnyEvent) Riak::Client (PBC)
     Net::Riak (REST)               542/s               --              -15%              -29%                    -55%            -57%              -90%                          -92%               -92%
     Data::Riak (REST)              635/s              17%                --              -17%                    -47%            -49%              -89%                          -90%               -90%
     Riak::Tiny (REST)              765/s              41%               20%                --                    -36%            -39%              -86%                          -88%               -88%
     Data::Riak::Fast (REST)       1198/s             121%               89%               57%                      --             -4%              -79%                          -82%               -82%
     Net::Riak (PBC)               1254/s             131%               97%               64%                      5%              --              -78%                          -81%               -81%
     Riak::Light (PBC)             5634/s             939%              787%              637%                    370%            349%                --                          -14%               -14%
     Riak::Client (PBC + AnyEvent) 6557/s            1110%              933%              757%                    448%            423%               16%                            --                 0%
     Riak::Client (PBC)            6557/s            1110%              933%              757%                    448%            423%               16%                            0%                 --

SEE ALSO
   Net::Riak

   Data::Riak

   Data::Riak::Fast

   Action::Retry

   Riak::Light

   AnyEvent

CONTRIBUTORS
   Ivan Kruglov <[email protected]>

AUTHOR
   Damien Krotkine <[email protected]>

COPYRIGHT AND LICENSE
   This software is copyright (c) 2014 by Damien Krotkine.

   This is free software; you can redistribute it and/or modify it under
   the same terms as the Perl 5 programming language system itself.