Coder Social home page Coder Social logo

riakpbc's Introduction

RiakPBC build statusCode ClimateGitter

RiakPBC is a low-level riak 2.0 protocol buffer client for node.js.

Contents

Installation

npm install --save riakpbc

Client

var RiakPBC = require('riakpbc');
var client = RiakPBC.createClient(/* options */);

Options

The options object accepts the following parameters:

  • connectTimeout: The timeout (in milliseconds) for creating a new connection. (Default: 1000)
  • idleTimeout: The amount of time (in milliseconds) that a node can be idle in the connection pool before it is released. (Default: 30000)
  • maxLifetime: The amount of time (in milliseconds) that a node is used in the connection pool before it is released, regardless of activity. (Default: Infinity)
  • minConnections: The minimum number of connections to keep active in the connection pool. (Default: 0)
  • maxConnections: The maximum number of connections that may be active in the connection pool at any given time. (Default: 10)
  • parseValues: If set to false, values will be returned as buffers rather than strings or parsed JSON. (Default: true)
  • nodes: An array of { host: 'string', port: number } objects specifying all of the riak nodes to use. These are then load balanced via round-robin.
  • host: If only connecting to a single node, you may specify the host property directly rather than passing an array of nodes. (Default: '127.0.0.1')
  • port: Again, if only connecting to a single node, you may specify the port directly. (Default: 8087)
  • auth: User and password, specified as a { user: 'string', password: 'string' } object, to use for authentication if using riak security.

Usage

For a full reference of all available methods, see the API Reference.

Methods that accept input have the signature (params, callback), where params is an object containing the message to be sent to riak.

Methods that do not accept input have the signature (callback).

Callbacks have the signature (err, response).

If an error occurs, the err object will be a standard Error object wrapping the riak supplied RpbErrorResp message.

If the call was successful, response will be the riak supplied message. Many calls do not return a value, or only return a value when certain flags are set, in these cases the response will be an empty object {}.

client.ping(function (err, response) {
  if (err) {
    return console.error('Failed to ping:', err);
  }

  console.log(response); // {}
});

Note that callbacks are always optional, and if not supplied the call will return a stream instead.

These streams will emit only an error event if an error occurs. If the call is successful, the stream will emit one or more data events and an end event.

var keys = client.getKeys({ bucket: 'test' });

keys.on('error', function (err) {
  console.error('An error occurred:', err);
});

keys.on('data', function (response) {
  console.log('Got some keys:', response.keys); // this could fire multiple times
});

keys.on('end', function () {
  console.log('Finished listing keys');
});

Data Conversions

RiakPBC attempts to stay as accurate as possible when converting data to and from protocol buffer encoding.

All available messages are documented in the Messages reference.

The primary data types that riak uses are handled as follows:

bytes

The bytes type may be supplied as either a string or a Buffer.

By default, when translating a response message these fields will be converted to a string unless they are the vclock or context properties. Since these values are intended to be binary only, they are left as a Buffer.

In the case of RpbContent values, RiakPBC will convert the value field to a string only if a content_type was set, and begins with the string text (as in text/plain or text/xml). In addition, if content_type is set to application/json RiakPBC will parse the value as JSON automatically.

This behavior can be overridden and Buffer objects returned for all bytes fields by setting { parseValues: false } in your client options.

uint32/float

These fields will always be treated as a plain javascript number.

sint64

Since javascript does not properly handle 64 bit numbers, these are a special case.

When used as input, you may pass either a number (42), a string ('-98549321293'), or a long.js object.

In a reply, you will always receive a long.js object. These objects allow RiakPBC to properly support real 64 bit number values.

bool

These fields will always be treated as a plain javascript boolean (i.e. true or false).

enums

Several messages accept an enum field. RiakPBC exports these as variables on the main object to simplify input. They are as follows:

  • IndexQueryType:
    • RiakPBC.IndexType.Exact
    • RiakPBC.IndexType.Range
  • DataType:
    • RiakPBC.DataType.Counter
    • RiakPBC.DataType.Set
    • RiakPBC.DataType.Map
  • MapFieldType:
    • RiakPBC.FieldType.Counter
    • RiakPBC.FieldType.Set
    • RiakPBC.FieldType.Register
    • RiakPBC.FieldType.Flag
    • RiakPBC.FieldType.Map
  • FlagOp:
    • RiakPBC.Flag.Enable
    • RiakPBC.Flag.Disable

These variables are all simple numbers, however, so when RiakPBC returns a message containing one of these types you will receive a plain number. I would recommend using the exported variables for comparison purposes to maintain readable code.

Embedded Messages

All other types not documented here are an embedded message and are recursively encoded/decoded in the same fashion as the above types.

License

The MIT License (MIT)

riakpbc's People

Contributors

ahiipsa avatar alexmcpherson avatar awenger avatar colinmutter avatar countrodrigo avatar gitter-badger avatar keikku avatar mde avatar natural avatar nisaacson avatar nlf avatar oleksiyk avatar pgte avatar roidrage avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

riakpbc's Issues

Streams cannot be piped

Current

The streaming interface is a great feature, but is incompatible with other node streams in its current implementation.

var keyStream = client.getKeys({ bucket: 'test' }, true)

keyStream.on('data', function (err, reply) {
  console.log('batch of keys:', reply.keys);
});

var someWriteableStream = through() // any writeable stream here

keyStream.pipe(someWritableStream) // this breaks here

Proposal

Replacing the EventEmitter with an actual readable/writeable stream would allow streaming output from riakpbc to be piped into other streams. The downside is this require a breaking api change in riakpbc. The data event callback in standard node.js style streams takes a single data parameter. The errors are instead handled via an error event on the stream itself

var keyStream = client.getKeys({ bucket: 'test' }, true)

// note only a single data parameter in the callback with no error object
keyStream.on('data', function (reply) {
  console.log('batch of keys:', reply.keys);
});

// handle errors via the 'error' event on the stream
keyStream.on('error', function(err) {
  console.log('got an error')
  console.dir(err)
})
var someWriteableStream = through() // any writeable stream here

keyStream.pipe(someWritableStream) // this would now work

I am thinking about implementing this but wanted to get other thoughts before making breaking api changes.

Integer (_int) secondary indexes/indices

Currently only string secondary index keys work in the client. It would be nice to be able to specify integer secondary index keys

Desired Int key value

The following gives an error Uncaught TypeError: Argument should be a String.

var indexes = [
  { key: 'key1_int', value: 2 },
  { key: 'key2_int', value: 100 }
]
var options = { 
  bucket: 'test', 
  key: 'test-put-index-integer', 
  content: { 
    value: '{"test":"data"}', 
    content_type: 'application/json', 
    indexes: indexes 
  }, 
  return_body: true 
};
client.put(options, function (err, reply) {
  if(err) { throw err }
  console.dir(reply)
})

String Workaround with incorrect order

A workaround is to just stringify the index values. This allows secondary index to be set in Riak.

However when querying the keys come back in the wrong order. In the example below the key corresponding to the secondary index value of '100' comes back before the key for the secondary index value '2'

var indexes = [
  { key: 'key1_bin', value: '2' },
  { key: 'key2_bin', value: '100' }
]
var options = { 
  bucket: 'test', 
  key: 'test-put-index-string', 
  content: { 
    value: '{"test":"data"}', 
    content_type: 'application/json', 
    indexes: indexes 
  }, 
  return_body: true 
};
client.put(options, function (err, reply) {
  if(err) { throw err }
  console.dir(reply)
})

client.get() appears to be automatically retrying the get on a connection timeout.

client.get() appears to be automatically retrying the get on a connection timeout. I noticed this when a callback was run twice. For example:

client.get({...}, function(err, res){
if (err) console.log('error');
else console.log('no error');
})

If the first connection timed out, and the automatic retry was successful, this would produce:

error
no error

Testing Riak 2.0.0 branch.

I am aware that riak2 branch is still being built but I just wanted to document what I found when writing lots (100s of gb) of data so we can research it.

Error: {too_many_siblings,101}
      at RiakPBC._processMessage (/var/www/vhosts/riak-backfill/releases/20140416222439/node_modules/riakpbc/index.js:40:15)
      at ConnectionManager._receive (/var/www/vhosts/riak-backfill/releases/20140416222439/node_modules/riakpbc/lib/connection-manager.js:119:10)
      at Socket.EventEmitter.emit (events.js:95:17)
      at Socket.<anonymous> (_stream_readable.js:746:14)
      at Socket.EventEmitter.emit (events.js:92:17)
      at emitReadable_ (_stream_readable.js:408:10)
      at emitReadable (_stream_readable.js:404:5)
      at readableAddChunk (_stream_readable.js:165:9)
      at Socket.Readable.push (_stream_readable.js:127:10)
      at TCP.onread (net.js:528:21)
     Failed to write

getKeys() error 'Trying to access beyond buffer length'

When I have a large number of maps in a bucket, and call getKeys, I get the error 'Trying to access beyond buffer length'. I have the problem intermittently when I have around 35,000 maps in the bucket, which seems very odd but another bucket has hundreds of thousands of maps in it, and it gives me this error every time. From what I can tell from Riak's documentation, this should still work regardless of the number of keys.

buffer.js:582
    throw new RangeError('Trying to access beyond buffer length');
    ^
RangeError: Trying to access beyond buffer length
    at checkOffset (buffer.js:582:11)
    at Buffer.readInt32BE (buffer.js:750:5)

Update Counter Inconsistent, Errors with Negative Values

The tests don't cover this, but there's some funk in updateCounter such that an amount of 1 increases the counter by 2.

Probably related, when the amount is negative, the client throws an error and does not update the counter value.

Verified expected behavior with the HTTP interface.

Console log:

> client.updateCounter({bucket:'test', key:'counter_x', returnvalue: true, amount:1}, console.log)
undefined
> { value: 1 }
> client.updateCounter({bucket:'test', key:'counter_x', returnvalue: true, amount:1}, console.log)
undefined
> { value: 3 }

And then:

> client.updateCounter({bucket:'test', key:'counter_x', returnvalue: true, amount:-1}, console.log)
undefined
> { errmsg: 'Error processing incoming message: error:badarg:[{protobuffs,decode_varint,
(snip)

tests may report a false positive

I wanted to test this module with node 0.12.0 to send a PR to update package.json engines however I may be doing something wrong because I wanted to get a test failure but I couldn't.

The reason why I tried to make a test to fail is because I didn't have riak install in my machine, I was creating a docker image to allows to test this modules without having to install riak in the host machine and to test that the image (container when it executes) works I added this simple instruction return done(new Error('I want it fails here')); in https://github.com/nlf/riakpbc/blob/master/test/sets.js#L43

When I've realised that docker containers exit with code 0, I've decided to install riak in my host machine, however I got the same result, then can you tell me what I need to run the test properly? I use make test to execute the tests.

Sending empty or non-string value.

Starting from a fresh install of Riak 1.4.2-1 (ubuntu/basho packages).

$ curl -is 'http://127.0.0.1:8098/buckets/people/keys/empty'
HTTP/1.1 404 Object Not Found
Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
Date: Tue, 10 Dec 2013 18:32:28 GMT
Content-Type: text/plain
Content-Length: 10

not found

Put empty data in:

$ curl -i -H 'Content-Type: application/json' -X PUT 'http://127.0.0.1:8098/buckets/people/keys/empty' -d ''
HTTP/1.1 204 No Content
Vary: Accept-Encoding
Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
Date: Tue, 10 Dec 2013 18:35:03 GMT
Content-Type: application/json
Content-Length: 0

Everything appears well:

$ curl -is 'http://127.0.0.1:8098/buckets/people/keys/empty'
HTTP/1.1 200 OK
X-Riak-Vclock: a85hYGBgzGDKBVIcypz/fgYtj7PIYEpkzGNluH5L+gxfFgA=
Vary: Accept-Encoding
Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
Link: </buckets/people>; rel="up"
Last-Modified: Tue, 10 Dec 2013 18:35:03 GMT
ETag: "1MvrYundbdRZA34IOByQVF"
Date: Tue, 10 Dec 2013 18:35:28 GMT
Content-Type: application/json
Content-Length: 0

Now restesting with riakpbc:

$ cat test-empty-put.coffee
riakpbc = require 'riakpbc'
client = riakpbc.createClient()

options =
  bucket: 'person'
  key: 'empty'
  content:
    content_type: 'application/json'
    value: ''
client.put options, (error, reply) ->
  console.log error, reply
  client.disconnect()
$ coffee test-empty-put.coffee
undefined {}
$ cat test-emtpy-get.coffee
riakpbc = require 'riakpbc'
client = riakpbc.createClient()

options =
  bucket: 'person'
  key: 'empty'
  notfound_ok: true
client.get options, (error, reply) ->
  console.log error, reply
  client.disconnect()
$ coffee test-empty-get.coffee

undefined:0

^
SyntaxError: Unexpected end of input
  at Object.parse (native)
  at parseContent (/home/ccase/link-walking/node_modules/riakpbc/lib/parse-content.js:16:27)
  at Array.forEach (native)
  at processSingleResBuffer (/home/ccase/link-walking/node_modules/riakpbc/index.js:140:30)
  at Array.forEach (native)
  at RiakPBC.processAllResBuffers (/home/ccase/link-walking/node_modules/riakpbc/index.js:116:16)
  at RiakPBC._processPacket (/home/ccase/link-walking/node_modules/riakpbc/index.js:108:26)
  at Socket.EventEmitter.emit (events.js:95:17)
  at Socket.<anonymous> (_stream_readable.js:746:14)
  at Socket.EventEmitter.emit (events.js:92:17)
  at emitReadable_ (_stream_readable.js:408:10)
  at emitReadable (_stream_readable.js:404:5)
  at readableAddChunk (_stream_readable.js:165:9)
  at Socket.Readable.push (_stream_readable.js:127:10)
  at TCP.onread (net.js:526:21)

HTTP interface still thinks everything is ok:

$ curl -is 'http://127.0.0.1:8098/buckets/people/keys/empty'
HTTP/1.1 200 OK
X-Riak-Vclock: a85hYGBgzGDKBVIcypz/fgYtj7PIYEpkzGNluH5L+gxfFgA=
Vary: Accept-Encoding
Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
Link: </buckets/people>; rel="up"
Last-Modified: Tue, 10 Dec 2013 18:35:03 GMT
ETag: "1MvrYundbdRZA34IOByQVF"
Date: Tue, 10 Dec 2013 18:38:55 GMT
Content-Type: application/json
Content-Length: 0

But now the protobuf interface is in a bad state.

Removing the document doesn't fix it:

$ curl -is -X DELETE 'http://127.0.0.1:8098/buckets/people/keys/empty'
HTTP/1.1 204 No Content
Vary: Accept-Encoding
Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
Date: Tue, 10 Dec 2013 18:41:19 GMT
Content-Type: application/json
Content-Length: 0

$ coffee test-empty-get.coffee

undefined:0

^
SyntaxError: Unexpected end of input
  at Object.parse (native)
  at parseContent (/home/ccase/link-walking/node_modules/riakpbc/lib/parse-content.js:16:27)
  at Array.forEach (native)
  at processSingleResBuffer (/home/ccase/link-walking/node_modules/riakpbc/index.js:140:30)
  at Array.forEach (native)
  at RiakPBC.processAllResBuffers (/home/ccase/link-walking/node_modules/riakpbc/index.js:116:16)
  at RiakPBC._processPacket (/home/ccase/link-walking/node_modules/riakpbc/index.js:108:26)
  at Socket.EventEmitter.emit (events.js:95:17)
  at Socket.<anonymous> (_stream_readable.js:746:14)
  at Socket.EventEmitter.emit (events.js:92:17)
  at emitReadable_ (_stream_readable.js:408:10)
  at emitReadable (_stream_readable.js:404:5)
  at readableAddChunk (_stream_readable.js:165:9)
  at Socket.Readable.push (_stream_readable.js:127:10)
  at TCP.onread (net.js:526:21)

Ditto if I now put a new empty document in via HTTP. In fact, even putting in a new non-empty document with actual data doesn't fix it (with the same 'empty' key). Restarting the riak service doesn't fix it either (same behavior, all good via HTTP, but the protobuf is broken).

On the other hand, it is specific to this key 'empty'. Putting in more documents works (as long as you don't make the same mistake).

So far the only way I've been able to come back from this is to manually delete the bucket's files from var.

I innocently stumbled up this by accidentally not converting the value to a JSON string:

$ cat test-invalid-put.coffee
riakpbc = require 'riakpbc'
client = riakpbc.createClient()

options =
  bucket: 'person'
  key: 'empty'
  content:
    content_type: 'application/json'
    value:
      oops: "Should have stringified..."
client.put options, (error, reply) ->
  console.log error, reply
  client.disconnect()

Which has the surprising behaviors of not automatically converting value to a string and sending an empty string to riak.

Connection Pooling Design Problems

Wanted to start out by thanking you all for the work you've put into this library! I know it's not a trivial amount of effort to write a Riak client and our library wouldn't exist without yours.

Happy to see the Riak 2.0 support landed in the master branch. I wrote a library that uses riakpbc (riaktive) and had a connection pooling abstraction around the original approach to connections. This allowed consumers to issue commands without worrying about when connectivity was established or even what nodes were reachable. Riaktive simply rolls to a different node in the pool transparently and attempts to issue the command there. The consumer is able to control how many attempts are made on their behalf before the command will result in an error that the consumer sees.

The new approach for connection pooling in riakpbc makes this impossible. There are actually two problematic scenarios that occur with riakpbc's new approach to connection management:

Unpredictable Number of Failures When A Node Becomes Unreachable

Network hiccups happen all the time in big systems. If a client cannot reach a Riak node with riakpbc, they have to re-issue the command an unknown number of times until they receive a connection from the pool for a different node. There doesn't seem to be a consistent pattern for this behavior and if you have multiple requests firing off from different activities, this becomes even more unpredictable. As a consumer, you shouldn't have to worry about this kind of behavior - the library should handle this for you.

I have a unit test for riaktive where I have some invalid and valid nodes. The test is that I should be able to issue a ping command once and get a response despite there being unreachable nodes. I have yet to find a nice way to get this test to pass since riakpbc can issue me an unreachable node from the pool an indefinite number of times (until the inactivity timeout hits and the node and its connections appear to be removed from the pool and balancer permanently).

Nodes Get Permanently Removed

If I follow the inactivity timeout correctly, there is a dangerous side effect that can lead to a client application with an empty balancer/pool if there's enough connectivity problems. Something like a rolling restart of a Riak cluster could cause my client app to trash all the nodes and render it unable to connect to anything.

Current Work Around

I will be monkey patching the pool property with riaktive's prior approach so that we can continue to provide a referentially transparent way to talk to Riak and avoid leaking connection management edge cases/concerns into our client applications.

Possible Solution

It would be nice if the balancer would temporarily remove/mark connections in the pool which have failed due connectivity issues. It would be great if it would attempt pings to these marked nodes at some interval and restore the clients in the pool on successful ping.

If there is any interest in the possible solution outlined above, when I have time later, I'd be happy to attempt trying to contribute this kind of behavior. I'm not certain whether or not it would work with generic_pool but that's more because I'm less familiar with that library.

It's quite possible that this won't be an issue for anyone else using riakpbc, I understand that there are other ways to work around this approach to connection management in the consuming applications. We would prefer to insulate our client apps from having to handle these sorts of edge cases and I thought I'd share my concerns with you all before just monkey patching your library and hoping the property name/implementation details don't change 🐒

My apologies if I have overlooked something, misinterpreted the design or failed to read some aspect of the docs that would explain how I should be handling this.

Work on reducing code complexity

code climate shows us in a pretty poor state, and it's entirely because of code complexity. should probably work on improving that.

Trouble keeping connection with riak

This is a bit hard to explain, however it is a real problem that i can not seem to figure out.
I have a Ubuntu machine with a node.js server, getting its data from riak and sending it back. It worked fine for about a week, but now it seems that i can connect with riak but only make one request before i loose the connection.
I have tried running the server on several other computers which worked fine, I also tried the auto_connect option, which however does not seem to fix the problem.
Any ideas?

Program does not exit

Hey,

I have used below code to get the keys of a bucket 'polls'.

                    • CODE - - - - - - - - - - - - - - - - - - -
                      var riakpbc = require('riakpbc');
                      var client = riakpbc.createClient({host: 'localhost', port: 8087});

var keys = client.getKeys({ bucket: 'polls' });

keys.on('error', function (err) {
console.error('An error occurred:', err);
});

keys.on('data', function (response) {
console.log('Got some keys:', response.keys); // this could fire multiple times
});

keys.on('end', function () {
console.log('Finished listing keys');
});

                    • OUTPUT - - - - - - - - - - - - - - - -
                      Got some keys: [ 'B5gd8ToUlhPK4n6m6WWEKvESPRz' ]

Got some keys: [ 'LRgoITzVQj5dEiPcC7TebFTzAXO' ]

Got some keys: [ 'ILXh5NX5x918rxdsT89A7qTkEHI' ]

Got some keys: [ 'FNYDkyCaCfyinTlTYxpl8W5uWWQ' ]

Got some keys: [ '7lueKK1owMsAVmjScRcB6MPtJ36' ]

Got some keys: [ 'SQ8e01lOeK5yjQXBlzuVXosiltS' ]

Got some keys: [ '8erOandd8GojAEDPbayWwMTF9Ww' ]

Finished listing keys


When running this program, it lists the keys for me and properly displays the message 'Finished listing keys' but then it doesn't exit which i need. Is there any method available which should be called at end to explicitly end the program.

Thanks.
Sachin

Auto reconnect code is gone and closed sockets aren't handled cleanly

I noticed the auto reconnect code is gone from the connection manager. Is this intentional?

This causes issues when the socket is closed by the server side (either on error or intentional close). I noticed it because I happened to have my idleTimeout set to a higher value than the haproxy's client idle timeout of 16 seconds, which meant that any connection that didn't see any activity would end up getting closed by haproxy. However the connection manager code still considers this client good and fails silently, since the disconnect() method doesn't really set any flags or take further action.

Riak security part doesn't work

I couldn't get you security part to work, so I tried to run the test script security.js. It appear that the callback on client.ping never is called, even though the test passes.

var client = RiakPBC.createClient({ auth: { user: 'riak', password: 'testing' } });
client.ping(function (err) {
  expect(err).to.not.exist;
  done();
});

I have tried debugging this and found that the callback in tls.connect is never called. Why I don't know, but I assume it is a protocol error. I tried finding documentation for the Riak handshake protocol but couldn't find any.

  • Do you know what the problem is?
  • Where do I find the documentation for the Riak handshake protocol?

Thanks, hope you can help.

Documentation

Documentation needs to be written explaining how this thing actually works..

Put Link Examle

Hey,

I can't figure out how to set links with a put operation. Any ideas or examples? I set the links array in the request, but nothing is set.

Thanks for the nice and fast client.

convert vclocks to strings

It looks like HTTP vclocks are identical to base64 encoding the buffer that we currently return, might be nice to go ahead and convert the buffers to base64 strings so that they match up and make things simpler to inspect.

Proper error first callbacks

Need to check replies for an errmsg property and wrap them in an Error object for proper error first callback signatures

error processing incoming message: vclock encoding

I have this riak error at the protobuf level:

err Error processing incoming message: throw:{error,"Error decodeing type"}:[{protobuffs,
                                                                          read_field_num_and_wire_type,
                                                                          1,
                                                                          [{file,
                                                                            "src/protobuffs.erl"},
                                                                           {line,
                                                                            203}]},

I've nailed it down to the vclock value when updating a record.

As the vclock comes back as a buffer, I encode it as a base64 string for replying to clients.
When updating a record, I encode it back as a buffer, resulting in the same exact bytes as the original reply:

reply.vlock: <Buffer 6b ce 61 60 60 60 cc 60 ca 05 52 1c ca 9c ff 7e 06 26 dd 38 9b c1 94 c8 98 c7 ca 30 77 fb 8d 53 7c 59 00>
(...)
options.vclock <Buffer 6b ce 61 60 60 60 cc 60 ca 05 52 1c ca 9c ff 7e 06 26 dd 38 9b c1 94 c8 98 c7 ca 30 77 fb 8d 53 7c 59 00>

I've tried it as an utf-8 encoded string, but this time getting an error on the zlib level:

options.vclock k�a```�`�Rʜ�~&�8���Ș������)�,

rr Error processing incoming message: error:data_error:[{zlib,call,3,[]},
                                                     {zlib,inflate,2,[]},
                                                     {zlib,unzip,1,[]},
                                                     {riak_kv_pb_object,
                                                      erlify_rpbvc,1,

Any clue or hint?

TIA!

Generate message validators

We should generate validators (probably just joi since it's already there for options parsing) for each message type, this would allow us to fail early and give sane error messages in the event that the user attempts to make a call with bad input.

Make riak 2.0 branch

I started this, but it's definitely not done. Need to add all the new commands. This will get published as version 2.0.0 when it's complete.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.