riak Ruby Protocol Buffers Client

DESCRIPTION:

This is a Ruby client for Riakpb, using protocol buffers instead of REST. It offers some benefit in terms of speed and it abstracts Buckets/Keys differently than does the REST client. Different != Better.

FEATURES/PROBLEMS:

  • It can list buckets! Huzzah!

  • You can destroy a bucket, which basically lists its keys and iterates over them–deleting each.

  • It works, which surely counts for something.

  • It’s still rough around the edges, but certainly usable. I’m attempting to polish it, though suggestions welcome.

SYNOPSIS:

This is a work in progress and I am current improving the rspec and the documentation, but please have fun and give me some feedback. The below examples give you an overview on how to use this package.

Connect to riak and ping it:

>> client = Riakpb::Client.new # Riakpb::Client.new({:host => "ubuntu01", :port => 1234})
=> #<Riakpb::Client:0x0000010328a040 @host="127.0.0.1", @port=8087, @w=nil, @dw=nil, @buckets=[], @bucket_cache={}>
>> client.ping?
=> true

List Buckets within riak:

Not suggested for use in production

>> client = Riakpb::Client.new
=> #<Riakpb::Client:0x00000101439a78 @host="127.0.0.1", @port=8087, @w=nil, @dw=nil, @buckets=[], @bucket_cache={}>
>> client.buckets
=> ["hb", "goog"]

Fetch a Bucket:

>> bucket = client["goog"]
=> #<Riakpb::Bucket name=goog, props={n_val=>3, allow_mult=false}>

Destroy a Bucket:

>> bucket.destroy!
=> true

List Keys within the Bucket:

>> bucket = client["goog"]
=> #<Riakpb::Bucket name=goog, props={n_val=>3, allow_mult=false}>
>> bucket.keys
=> ["2010-05-03", "2010-03-24", "2010-03-05", "2010-02-25", <<SNIP>>, "2005-02-10", "2005-01-04"]

Fetch a Key:

>> key = bucket["2010-04-12"]
=> #<Riakpb::Key name="2010-04-12", vclock="k\xCEa```\xCC`\xCA\x05R,\xCC\xF3{*2\x98\x12\x19\xF3X\x19N\xCF\xEB8\xCA\x97\x05\x00", contents=[#<#Riakpb::Content value={"Date"=>Mon, 12 Apr 2010, "Open"=>"567.35", "High"=>"574.00", "Low"=>"566.22", "Close"=>"572.73", "Volume"=>"2352400", "Adj Close"=>"572.73"}, content_type="application/json", vtag="3pbhcnmUtPZvXBSCmo5ESs", links=[], last_mod=1276388043, last_mod_usecs=65345, usermeta={}>]>

Fetch a Key’s Content:

Differs from the REST client. Key+Content = ROjbect

>> rcon = key.content
=> #<#Riakpb::Content value={"Date"=>Mon, 12 Apr 2010, "Open"=>"567.35", "High"=>"574.00", "Low"=>"566.22", "Close"=>"572.73", "Volume"=>"2352400", "Adj Close"=>"572.73"}, content_type="application/json", vtag="3pbhcnmUtPZvXBSCmo5ESs", links=[], last_mod=1276388043, last_mod_usecs=65345, usermeta={}>

Play with the Content’s data and save it:

>> rcon.value
=> {"Date"=>Mon, 12 Apr 2010, "Open"=>"567.35", "High"=>"574.00", "Low"=>"566.22", "Close"=>"572.73", "Volume"=>"2352400", "Adj Close"=>"572.73"}
>> rcon.value.class
=> Hash
>> rcon.value["Date"]
=> Mon, 12 Apr 2010
>> rcon.value["Date"] += 1.day
=> Tue, 13 Apr 2010
>> rcon
=> #<#Riakpb::Content value={"Date"=>Tue, 13 Apr 2010, "Open"=>"567.35", "High"=>"574.00", "Low"=>"566.22", "Close"=>"572.73", "Volume"=>"2352400", "Adj Close"=>"572.73"}, content_type="application/json", vtag="3pbhcnmUtPZvXBSCmo5ESs", links=[], last_mod=1276388043, last_mod_usecs=65345, usermeta={}>
>> rcon.save
=> true
>> key = bucket["2010-04-12"]
=> #<Riakpb::Key name="2010-04-12", vclock="k\xCEa```\xCA`\xCA\x05R,\xCC\xF3{*2\x98\x12\x19\xF3X\x19N\xCF\xEB8\xCA\a\x13\xFE\x9A\xF3\x05*|x)P8\v\x00", contents=[#<#Riakpb::Content value={"Date"=>Tue, 13 Apr 2010, "Open"=>"567.35", "High"=>"574.00", "Low"=>"566.22", "Close"=>"572.73", "Volume"=>"2352400", "Adj Close"=>"572.73"}, content_type="application/json", vtag="2wCEI09OVZEUcHozcm9XCX", links=[], last_mod=1276389827, last_mod_usecs=762316, usermeta={}>]>
>> rcon = key.content
=> #<#Riakpb::Content value={"Date"=>Tue, 13 Apr 2010, "Open"=>"567.35", "High"=>"574.00", "Low"=>"566.22", "Close"=>"572.73", "Volume"=>"2352400", "Adj Close"=>"572.73"}, content_type="application/json", vtag="2wCEI09OVZEUcHozcm9XCX", links=[], last_mod=1276389827, last_mod_usecs=762316, usermeta={}>
>> rcon.value["Date"] -= 1.day
=> Mon, 12 Apr 2010
>> rcon.save
=> true
>> key = bucket["2010-04-12"]
=> #<Riakpb::Key name="2010-04-12", vclock="k\xCEa```\xCA`\xCA\x05R,\xCC\xF3{*2\x98\x12\x19\xF3X\x19N\xCF\xEB8\xCA\a\x13\xFE\x9A\xF3\x05(\xCC\x04\x14~\xBC\x14(\x9C\x05\x00", contents=[#<#Riakpb::Content value={"Date"=>Mon, 12 Apr 2010, "Open"=>"567.35", "High"=>"574.00", "Low"=>"566.22", "Close"=>"572.73", "Volume"=>"2352400", "Adj Close"=>"572.73"}, content_type="application/json", vtag="264RmLHrCK89zvhtq4n6Fj", links=[], last_mod=1276389859, last_mod_usecs=810556, usermeta={}>]>
>> rcon = key.content
=> #<#Riakpb::Content value={"Date"=>Mon, 12 Apr 2010, "Open"=>"567.35", "High"=>"574.00", "Low"=>"566.22", "Close"=>"572.73", "Volume"=>"2352400", "Adj Close"=>"572.73"}, content_type="application/json", vtag="264RmLHrCK89zvhtq4n6Fj", links=[], last_mod=1276389859, last_mod_usecs=810556, usermeta={}>
>>

Junkshot: (Siblings)

>> client = Riakpb::Client.new
=> #<Riakpb::Client:0x00000100d2b998 @host="127.0.0.1", @port=8087, @w=nil, @dw=nil, @buckets=[], @bucket_cache={}>
>> bucket = client["goog2"]
=> #<Riakpb::Bucket name=goog2, props={n_val=>3, allow_mult=false}>
>> bucket.allow_mult = true
=> true
>> client.junkshot "goog2", "2010-04-12", {:links => {"tomorrow" => ["goog2", "2010-04-13"]}}
=> content {
  value: ""
  vtag: "3jfZii80dgtSPYbZ6CL1PU"
  links {
    bucket: "goog2"
    key: "2010-04-13"
    tag: "tomorrow"
  }
  last_mod: 1276715503
  last_mod_usecs: 980712
}
content {
  value: "{\"Date\":\"2010-04-12\",\"Open\":\"567.35\",\"High\":\"574.00\",\"Low\":\"566.22\",\"Close\":\"572.73\",\"Volume\":\"2352400\",\"Adj Close\":\"572.73\"}"
  content_type: "application/json"
  vtag: "2UplDRmlJaxS1rhn0GNgqN"
  last_mod: 1276651742
  last_mod_usecs: 417836
}
vclock: "k\xCEa``\xE0\xCA`\xCA\x05R,\xCC_s\xBEd0%2\xE5\xB12<^\xDAq\x94\x0F&|`\xF6n\xA00#P\xF8\xDE\x92\x1E\x980[s\x12S\x1F\xCBU\xA8\xC4\xA4\xC9\xBDp\xF5\xEC<\x8B\x0F`\n\x03\xD5\xB3\xE9x\x9C\x85Jh\xCE@\xA8g\xCE\xB00\xC3\x14\x06\xAAg\xBF\xB9\xE5\x14TBq\x0EB=\xD3u\xE7r,\xC2\x8C\xAB\xDC\xEFA\x85\xDF\xCFE6\x865.'\bY\"\v\x00"

>>

MapReduce:

I’m working on ways to simplify M/R requests. It works the same as in ripple. Largely because it’s ripped off from it, with very few changes (so far).

Load the GOOG stocks from the riak Fast Track:

require 'riakpb'
require 'csv'

client = Riakpb::Client.new
bucket = client["goog"]

CSV.foreach('goog.csv', :headers => true) do |row|
  puts row.first[1].to_s
  key = bucket[row.first[1].to_s]
  key.content.value = Hash[row.to_a]
  key.save
end

REQUIREMENTS:

  • Rspec >= 2.0.0.beta.9

  • ActiveSupport >= 3.0.0.beta3

  • Protobuf >= 0.4.4

INSTALL:

Rubygems:

gem install riakpb

From Github:

git clone git://github.com/aitrus/riak-pbclient.git
cd riak-pbclient
rake gem
gem install -l riakpb-X.Y.Z.gem

THANKS:

This is my first public open source whatever, and I appreciate the people in #riak who tolerated me.

LICENSE:

Copyright 2010:

Scott Gonyea
Sean Cribbs, Sonian Inc.
Basho Technologies, Inc.

The riak-pbclient was pieced together by Scott Gonyea. Big chunks of code were lifted / refactored from the riak-client project, by Sean Cribbs. Lots of pieces are my own work, but it doesn’t really matter to me.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.