raku

3.0.2 • Public • Published

Raku (楽)

A simplified Javascript client for working with Riak 2.0, based on no-riak. "Raku" means "easy" or "simple" in Japanese and it kind of sounds like "Riak." Basically, I wanted a client where i could just type

set(key, value)

or

get(key)

but I found that most clients take in a slew of arguments that I didn't want to think about. So, I took the most reasonable promise-based client that I could find, no-riak and wrapped it in a class.

The API is somewhat inspired by Redis.

Usage

$ npm install --save raku
import Raku from Raku
 
raku = new Raku()
 
raku.set('mykey', 42)
  .then(() => raku.get('mykey'))
  .then(value => {
    console.log('mykey is ' + value)
  })

API

Currently, this client supports 3 distinct KV operations (get, put/set, del), counters (cget, cset, cinc, cdec, cdel), and sets (sadd, srem, smembers, sismember, sdel, scard).

KV (key-value) API

put

raku.put(key, value)

The value will be serialized as a JSON string before being stored.

set

raku.set is an alias for raku.put

get

raku.get(key)

The result will be a promise that resolves into the corresponding Javascript data type. For example, if the value was stored as a boolean, you'll get back a promise that resolves to a boolean.

del

raku.del(key)

This will delete the key in the Riak database.

Getting explicit

You can specify the bucket in the with the first argument with the following 3 KV functions.

bget

raku.bget(bucket, key)

Get the value at (bucket, key). Returns a promise.

bset

raku.bset(bucket, key, value)

Set the value at (bucket, key) to value. Returns a promise.

bdel

raku.bdel(bucket, key)

Delete the value at (bucket, key). Returns a promise.

CRDT Riak Counters

Note: Before using counters for the first time, you must activate a counter bucket type using the riak-admin at the command line. This will make your Riak cluster incompatible with earlier versions.

$ sudo riak-admin bucket-type create counters '{"props":{"datatype":"counter"}}'
$ sudo riak-admin bucket-type activate counters

CRDT Counters API

cset

raku.cset(key, value)

Set and save a counter to an arbitrary integer value (positive or negative). Returns a promise that evaluates to the new value.

cget

raku.cget(key)

Get a counter stored at key from the database. Returns a promise that evaluates to the value.

cinc

raku.cinc(key, amount)

Increment and save a counter by any amount. Negative amounts will decrement the value. Returns a promise that evaluats to the new value. If multiple clients nearly simultaneously increment a value by one, each client will resolve to a unique number, thanks to the magic of Riak CRDT counters. If no amount is given, it will be assumed to be 1.

cdec

raku.cdec(key, amount)

Decrement and save a counter. Positive amounts will decrement the counter, and negative amounts will increment the counter. If no amount argument is given, the counter will be decremented by 1. Returns a promise that evaluates to the new value.

cdel

raku.cdel(key)

Delete a counter. This will delete the key in the counters bucket. Returns a promise that evaluates to null.

CRDT Riak Sets

Note: As with counters, before using CRDT sets for the first time, you must activate a set bucket type using the riak-admin at the command line.

$ sudo riak-admin bucket-type create sets '{"props":{"datatype":"set"}}'
$ sudo riak-admin bucket-type activate sets

CRDT Sets API

Where possible, I tried to follow the Redis API for operations on sets.

sadd

raku.sadd(key, value)

Add a value to the set. Returns a promise.

srem

raku.srem(key, value)

Remove a value from the set. Returns a promise.

sismember

raku.sismember(key, value)

Check if a value is a member of the set. Returns a promise which resolves to a boolean.

smembers

raku.smembers(key)

List all members of the set. Returns a promise which resolves to a JS array of the set members.

sdel

raku.sdel(key)

Delete all members of the set. Returns a promise.

sreset

raku.sreset(key, values)

Reset the set to the new set of values. Returns a promise.

scard

raku.scard(key)

Count members in the set. Returns a promise that resolves to the set's count.

Bucket and bucket types API

For the aforementioned KV, counter, and set functions rely on an unspecified fall-back value, one for each data type. To change the fall-back value just assign it a new value:

For KV data types,

bucket=

raku.bucket = "mybucket"

KV functions have a default bucket but don't have a default bucket type.

CRDT Counters have a default bucket type of "counters" and a default bucket also named "counters". You can change these defaults like so:

counter_bucket=

raku.counter_bucket = "user_ids"

counter_bucket_type=

raku.counter_bucket_type = "last_ids"

CRDT sets have a default bucket type of "sets". The default bucket is also called "sets" and can be changed similar to the counters bucket type. To avoid confusion with the operation called "set", when referring to the data type "set" I use the word "sets".

sets_bucket=

raku.sets_bucket = "fk_Post"

sets_bucket_type=

raku.sets_bucket_type = "foreign_keys"

Listing keys, buckets, bucket_types

keys()

raku.keys()

List all keys in the database. Returns an array of objects [{key, bucket, type}].

buckets()

raku.buckets()

List all buckets in the database. Since, one must provide the bucket type to get a list of buckets within the bucket type, this function assumes a hard-coded list of bucket types stored in Raku.KNOWN_BUCKET_TYPES. Default values are ['default', 'counters', 'sets'].

bucket_types()

raku.bucket_types()

List all buckets types in the database. Since there is no bucket types API in Riak, this function returns a hard-coded list of bucket types stored in Raku.KNOWN_BUCKET_TYPES. Default values are ['default', 'counters', 'sets']. You can manually override that list by simply assigning your own array of known bucket types. A list of known bucket types can be obtained at the command line:

riak-admin bucket-type list

Config

Riak's default configuration has a 3 second delay before deleting an object. I ran into this during testing when trying to clear my test database before each test. Apparently, deleting objects in a distributed environment designed for availability is a big deal. For the official documentation explaining why, you can read more here. If you want your Riak cluster to behave more like a strongly consistent database (maybe for testing purposes), you can set the "delete_mode" parameter in advanced.config to have the value "immediate". On Ubuntu, advanced.config is found /etc/riak/advanced.config. It contains an array of configuration parameters. Just make the following entry in the configuration array:

 {riak_kv, [
        {delete_mode, immediate}
    ]},

You can view an example of a complete advanced.config file here.

Then restart Riak:

sudo riak restart

More power

If you want the full power of a more sophisticated client, you can access the wrapped no-riak client like this:

  raku.client   # a no-riak client
  raku.NoRiak   # the no-riak module

See no-riak for details.

Notes

2017-05-21: changing deleteAll() and bucketTypes() to underscore naming style: delete_all() and bucket_types(). delete_all() only deletes keys whose buckets match /^test/ so that we don't delete the production database.

2017-03-22: Added deleteAll() to delete whole database (for testing purposes only). Added functions to list important types: keys(), buckets(), bucketTypes().

2017-02-20: Added CRDT set operations: sismember, smembers, sadd, srem, sdel, scard.

2017-01-16: Just added cdel for deleting a counter: cdel.

2017-01-13: Just added support for incrementing counters: cset, cget, cinc, cdec.

2016-12-19: I just released v2.0.0. That doesn't mean it's mature. Following the semantic versioning convention, it just means that there's a breaking change. There's breaking because the fall-back value of the bucket is no longer DEFAULT_BUCKET but instead it is this.bucket of the client instance, raku.

2016-12-13: I just started learning Riak, and just released this little wrapper for myself. I'll be adding features as I learn more about Riak. I'm happy to hear from anybody using this. You can email me here: thirdreplicator@gmail.com

License

MIT, enjoy.

Package Sidebar

Install

npm i raku

Weekly Downloads

3

Version

3.0.2

License

MIT

Unpacked Size

24 kB

Total Files

4

Last publish

Collaborators

  • thirdreplicator