riakpb 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ === 0.0.1 2010-05-21
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,30 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib/riak.rb
6
+ lib/riak/client.rb
7
+ lib/riak/client/rpc.rb
8
+ lib/riak/client_pb.rb
9
+ lib/riak/bucket.rb
10
+ lib/riak/key.rb
11
+ lib/riak/riak_content.rb
12
+ lib/riak/i18n.rb
13
+ lib/riak/locale/en.yml
14
+ lib/riak/util/decode.rb
15
+ lib/riak/util/encode.rb
16
+ lib/riak/util/message_code.rb
17
+ lib/riak/util/translation.rb
18
+ lib/riak/failed_exchange.rb
19
+ lib/riak/failed_request.rb
20
+ lib/riak/sibling_error.rb
21
+ script/console
22
+ script/destroy
23
+ script/generate
24
+ spec/spec_helper.rb
25
+ spec/riak/client_spec.rb
26
+ spec/riak/rpc_spec.rb
27
+ spec/riak/bucket_spec.rb
28
+ spec/riak/key_spec.rb
29
+ spec/riak/riak_content_spec.rb
30
+ spec/riak/map_reduce_spec.rb
data/README.rdoc ADDED
@@ -0,0 +1,156 @@
1
+ = riak Ruby Protocol Buffers Client
2
+
3
+ * http://github.com/aitrus/riak-pbclient
4
+
5
+ == DESCRIPTION:
6
+
7
+ This is a Ruby client for Riak, 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.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * It can list buckets! Huzzah!
12
+ * You can destroy a bucket, which basically lists its keys and iterates over them--deleting each.
13
+ * It works, which surely counts for something.
14
+ * It's still rough around the edges, but certainly usable. I'm attempting to polish it, though <b>suggestions welcome</b>.
15
+
16
+ == SYNOPSIS:
17
+
18
+ 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.
19
+
20
+ === Connect to riak and ping it:
21
+
22
+ >> client = Riak::Client.new # Riak::Client.new({:host => "ubuntu01", :port => 1234})
23
+ => #<Riak::Client:0x0000010328a040 @host="127.0.0.1", @port=8087, @w=nil, @dw=nil, @buckets=[], @bucket_cache={}>
24
+ >> client.ping?
25
+ => true
26
+
27
+ === List Buckets within riak:
28
+ <i>Not suggested for use in production</i>
29
+
30
+ >> client = Riak::Client.new
31
+ => #<Riak::Client:0x00000101439a78 @host="127.0.0.1", @port=8087, @w=nil, @dw=nil, @buckets=[], @bucket_cache={}>
32
+ >> client.buckets
33
+ => ["hb", "goog"]
34
+
35
+ === Fetch a Bucket:
36
+
37
+ >> bucket = client["goog"]
38
+ => #<Riak::Bucket name=goog, props={n_val=>3, allow_mult=false}>
39
+
40
+ === Destroy a Bucket:
41
+
42
+ >> bucket.destroy!
43
+ => true
44
+
45
+ === List Keys within the Bucket:
46
+
47
+ >> bucket = client["goog"]
48
+ => #<Riak::Bucket name=goog, props={n_val=>3, allow_mult=false}>
49
+ >> bucket.keys
50
+ => ["2010-05-03", "2010-03-24", "2010-03-05", "2010-02-25", <b>SNIP 80~ Lines</b>, "2005-02-10", "2005-01-04"]
51
+
52
+ === Fetch a Key:
53
+
54
+ >> key = bucket["2010-04-12"]
55
+ => #<Riak::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=[#<#Riak::RiakContent 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={}>]>
56
+
57
+ === Fetch a Key's Content:
58
+ <i>Differs from the REST client. Key+RiakContent = ROjbect</i>
59
+
60
+ >> rcon = key.content
61
+ => #<#Riak::RiakContent 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={}>
62
+
63
+ === Play with the RiakContent's data and save it:
64
+
65
+ >> rcon.value
66
+ => {"Date"=>Mon, 12 Apr 2010, "Open"=>"567.35", "High"=>"574.00", "Low"=>"566.22", "Close"=>"572.73", "Volume"=>"2352400", "Adj Close"=>"572.73"}
67
+ >> rcon.value.class
68
+ => Hash
69
+ >> rcon.value["Date"]
70
+ => Mon, 12 Apr 2010
71
+ >> rcon.value["Date"] += 1.day
72
+ => Tue, 13 Apr 2010
73
+ >> rcon
74
+ => #<#Riak::RiakContent 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={}>
75
+ >> rcon.save
76
+ => true
77
+ >> key = bucket["2010-04-12"]
78
+ => #<Riak::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=[#<#Riak::RiakContent 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={}>]>
79
+ >> rcon = key.content
80
+ => #<#Riak::RiakContent 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={}>
81
+ >> rcon.value["Date"] -= 1.day
82
+ => Mon, 12 Apr 2010
83
+ >> rcon.save
84
+ => true
85
+ >> key = bucket["2010-04-12"]
86
+ => #<Riak::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=[#<#Riak::RiakContent 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={}>]>
87
+ >> rcon = key.content
88
+ => #<#Riak::RiakContent 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={}>
89
+ >>
90
+
91
+ === MapReduce:
92
+
93
+ 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).
94
+
95
+ === Load the GOOG stocks from the riak Fast Track:
96
+
97
+ require 'riak'
98
+ require 'csv'
99
+
100
+ client = Riak::Client.new
101
+ bucket = client["goog"]
102
+
103
+ CSV.foreach('goog.csv', :headers => true) do |row|
104
+ puts row.first[1].to_s
105
+ key = bucket[row.first[1].to_s]
106
+ key.content.value = Hash[row.to_a]
107
+ key.save
108
+ end
109
+
110
+ == REQUIREMENTS:
111
+
112
+ * Rspec >= 2.0.0.beta.9
113
+ * ActiveSupport >= 3.0.0.beta3
114
+ * [Rakefile] hoe >= 2.1.0
115
+ * [Rakefile] newgem
116
+
117
+ == INSTALL:
118
+
119
+ git clone git://github.com/aitrus/riak-pbclient.git
120
+ cd riak-pbclient
121
+ rake gem
122
+ [sudo] gem install -l riak-X.Y.Z.gem
123
+
124
+ == LINKS:
125
+
126
+ * Riak Fast Track: https://wiki.basho.com/display/RIAK/The+Riak+Fast+Track
127
+ * Riak Fast Track GOOG data: https://wiki.basho.com/display/RIAK/Loading+Data+and+Running+MapReduce+Queries
128
+ * Ruby Client for Riak's REST Interface: http://github.com/seancribbs/ripple
129
+
130
+ == THANKS:
131
+
132
+ This is my first public open source whatever, and I appreciate the people in #riak who tolerated me.
133
+
134
+ == LICENSE:
135
+
136
+ Copyright 2010:
137
+ Scott Gonyea
138
+ Sean Cribbs, Sonian Inc.
139
+ Basho Technologies, Inc.
140
+
141
+ The riak-pbclient was pieced together by Scott Gonyea. Big chunks
142
+ of code were lifted / refactored from the riak-client project, by
143
+ Sean Cribbs. Lots of pieces are my own work, but it doesn't really
144
+ matter to me.
145
+
146
+ Licensed under the Apache License, Version 2.0 (the "License");
147
+ you may not use this file except in compliance with the License.
148
+ You may obtain a copy of the License at
149
+
150
+ http://www.apache.org/licenses/LICENSE-2.0
151
+
152
+ Unless required by applicable law or agreed to in writing, software
153
+ distributed under the License is distributed on an "AS IS" BASIS,
154
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
155
+ See the License for the specific language governing permissions and
156
+ limitations under the License.
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require './lib/riak'
6
+
7
+ Hoe.plugin :newgem
8
+ # Hoe.plugin :website
9
+ # Hoe.plugin :cucumberfeatures
10
+
11
+ # Generate all the Rake tasks
12
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
+ $hoe = Hoe.spec 'riakpb' do
14
+ self.developer 'Scott Gonyea', 'me@sgonyea.com'
15
+ self.rubyforge_name = self.name
16
+ self.summary = 'riak-pbclient is a protocol buffer client for Riak--the distributed database by Basho.'
17
+ self.url = 'http://github.com/aitrus/riak-pbclient'
18
+ end
19
+
20
+ require 'rspec/core'
21
+ require 'rspec/core/rake_task'
22
+
23
+ desc "Run Unit Specs Only"
24
+ Rspec::Core::RakeTask.new(:spec) do |spec|
25
+ spec.pattern = "spec/riak/**/*_spec.rb"
26
+ end
27
+
28
+ namespace :spec do
29
+ desc "Run Integration Specs Only"
30
+ Rspec::Core::RakeTask.new(:integration) do |spec|
31
+ spec.pattern = "spec/integration/**/*_spec.rb"
32
+ end
33
+
34
+ desc "Run All Specs"
35
+ Rspec::Core::RakeTask.new(:all) do |spec|
36
+ spec.pattern = Rake::FileList["spec/**/*_spec.rb"]
37
+ end
38
+ end
39
+
40
+ # TODO - want other tests/tasks run by default? Add them to the list
41
+ # remove_task :default
42
+ # task :default => [:spec, :features]
43
+
@@ -0,0 +1,177 @@
1
+ require 'riak'
2
+
3
+ module Riak
4
+ # Represents and encapsulates operations on a Riak bucket. You may retrieve a bucket
5
+ # using {Client#bucket}, or create it manually and retrieve its meta-information later.
6
+ class Bucket
7
+ include Util::Translation
8
+ include Util::MessageCode
9
+
10
+ # @return [Riak::Client] the associated client
11
+ attr_reader :client
12
+
13
+ # @return [String] the bucket name
14
+ attr_reader :name
15
+
16
+ # @return [Fixnum] the number of replicas for objects in this bucket
17
+ attr_reader :n_val
18
+
19
+ # @return [TrueClass/FalseClass] whether or not a key's siblings are to be retrieved
20
+ attr_reader :allow_mult
21
+
22
+ attr_reader :key_cache
23
+
24
+ # Create a Riak bucket manually.
25
+ # @param [Client] client the {Riak::Client} for this bucket
26
+ # @param [String] name the name of the bucket
27
+ def initialize(client, name, options={})
28
+ options.assert_valid_keys(:n_val, :allow_mult)
29
+ raise ArgumentError, t("client_type", :client => client.inspect) unless client.is_a?(Client)
30
+ raise ArgumentError, t("string_type", :string => name.inspect) unless name.is_a?(String)
31
+
32
+ @client = client
33
+ @name = name
34
+ @n_val = options[:n_val] || nil
35
+ @allow_mult = options[:allow_mult] || nil
36
+ @key_cache = Hash.new{|k,v| k[v] = Riak::Key.new(self, v)}
37
+ end
38
+
39
+ # Load information for the bucket from a response given by the {Riak::Client::HTTPBackend}.
40
+ # Used mostly internally - use {Riak::Client#bucket} to get a {Bucket} instance.
41
+ # @param [RpbHash] response a response from {Riak::Client::HTTPBackend}
42
+ # @return [Bucket] self
43
+ # @see Client#bucket
44
+ def load(response)
45
+ raise ArgumentError, t("response_type") unless response.is_a?(Riak::RpbGetBucketResp)
46
+
47
+ self.n_val = response.props.n_val
48
+ self.allow_mult = response.props.allow_mult
49
+
50
+ return(self)
51
+ end
52
+
53
+ # Accesses or retrieves a list of keys in this bucket. Needs to have expiration / cacheing, though not now.
54
+ # @return [Array<String>] Keys in this bucket
55
+ def keys
56
+ @keys ||= @client.keys_in @name
57
+ end
58
+
59
+ # Accesses or retrieves a list of keys in this bucket. Needs to have expiration / cacheing, though not now.
60
+ # @return [Array<String>] Keys in this bucket
61
+ def keys!
62
+ @keys = @client.keys_in @name
63
+ end
64
+
65
+ # Retrieve an object from within the bucket.
66
+ # @param [String] key the key of the object to retrieve
67
+ # @param [Fixnum] r - the read quorum for the request - how many nodes should concur on the read
68
+ # @return [Riak::Key] the object
69
+ def key(key, options={})
70
+ raise ArgumentError, t("fixnum_invalid", :num => options[:r]) unless options[:r].is_a?(NilClass) or options[:r].is_a?(Fixnum)
71
+ raise ArgumentError, t("string_invalid", :string => key) unless key.is_a?(String)
72
+
73
+ if options[:safely] == true and not @key_cache[key].empty?
74
+ return(@key_cache[key])
75
+ end
76
+
77
+ response = @client.get_request @name, key, options[:r]
78
+
79
+ @key_cache[key].load(response)
80
+ end
81
+ alias :[] :key
82
+
83
+ # Retrieve an object from within the bucket. Will raise an error message if key does not exist.
84
+ # @param [String] key the key of the object to retrieve
85
+ # @param [Fixnum] quorum - the read quorum for the request - how many nodes should concur on the read
86
+ # @return [Riak::Key] the object
87
+ def key!(key, r=nil)
88
+ raise ArgumentError, t("string_invalid", :string => key) unless key.is_a?(String)
89
+ raise ArgumentError, t("fixnum_invalid", :num => r) unless r.is_a?(Fixnum)
90
+
91
+ response = @client.get_request @name, key, r
92
+
93
+ Riak::Key.new(self, key).load!(response)
94
+ end
95
+
96
+ # Retrieves a Key from the given Bucket. Originally written for link retrieval.
97
+ # @param [String] bucket the name of the bucket, in which the Key is contained
98
+ # @param [String] key the name of the key to retrieve
99
+ # @option options [Fixnum] :quorum read quorum- num of replicas need to agree when retrieving the object
100
+ # @return [Riak::Key] the object
101
+ def get_linked(bucket, key, options=nil)
102
+ @client[bucket].key(key, options)
103
+ end
104
+
105
+ # Retrieves a Key from the given Bucket. Originally written for link retrieval.
106
+ # Inserts a key in this bucket's namespace, into riak.
107
+ # @option options [Fixnum] :w (write quorum) how many replicas to write to before returning a successful response.
108
+ # @option options [Fixnum :dw how many replicas to commit to durable storage before returning a successful response.
109
+ # @option options [Boolean] :return_body whether to return the contents of the stored object.
110
+ # @return [RpbPutResp] the response confirming Key storage and (optionally) the Key's updated/new data.
111
+ def store(options)
112
+ options[:bucket] = @name
113
+ @client.put_request(options)
114
+ end
115
+
116
+ # Deletes a key from the bucket
117
+ # @param [String] key the key to delete
118
+ # @param [Hash] options quorum options
119
+ # @option options [Fixnum] :rw - the read/write quorum for the delete
120
+ def delete(key, rw=nil)
121
+ key = key.name if key.is_a?(Riak::Key)
122
+
123
+ @client.del_request(@name, key, rw)
124
+ end
125
+
126
+ # Wipes out all keys stored in the bucket, as of execution
127
+ # @param [String] key the key to delete
128
+ # @param [Hash] options quorum options
129
+ # @option options [Fixnum] :rw - the read/write quorum for the delete
130
+ def destroy!(rw=nil)
131
+ keys!
132
+
133
+ @keys.each do |key|
134
+ @client.del_request(@name, key, rw)
135
+ end
136
+ # super.destroy
137
+ end
138
+
139
+ # @return [true, false] whether the bucket allows divergent siblings
140
+ def allow_mult
141
+ @allow_mult
142
+ end
143
+
144
+ # Set the allow_mult property. *NOTE* This will result in a PUT request to Riak.
145
+ # @param [true, false] value whether the bucket should allow siblings
146
+ def allow_mult=(value)
147
+ return(@allow_mult = value) if value.is_a?(TrueClass) or value.is_a?(FalseClass)
148
+
149
+ raise ArgumentError, t("boolean_type")
150
+ end
151
+
152
+ # @return [Fixnum] the N value, or number of replicas for this bucket
153
+ def n_val
154
+ @n_val
155
+ end
156
+
157
+ # Set the N value (number of replicas).
158
+ # Saving this value after the bucket has objects stored in it may have unpredictable results.
159
+ # @param [Fixnum] value the number of replicas the bucket should keep of each object
160
+ def n_val=(value)
161
+ raise ArgumentError, t("fixnum_type", :value => value) unless value.is_a?(Fixnum)
162
+
163
+ @n_val = value
164
+ end
165
+
166
+ # @return [String] a representation suitable for IRB and debugging output
167
+ def inspect
168
+ "#<Riak::Bucket name=#{@name}, props={n_val=>#{@n_val}, allow_mult=#{@allow_mult}}>"
169
+ end
170
+
171
+ # @return [String] a representation suitable for IRB and debugging output, including keys within this bucket
172
+ def inspect!
173
+ "#<Riak::Bucket name=#{@name}, props={n_val=>#{@n_val}, allow_mult=#{@allow_mult}}, keys=#{keys.inspect}>"
174
+ end
175
+
176
+ end
177
+ end
@@ -0,0 +1,127 @@
1
+ # Special thanks to:
2
+ #
3
+ # - Radar in #ruby-lang
4
+ # - xnotdotorg / arilerner[at]gmail.com -
5
+ # http://blog.xnot.org/2008/11/16/communicating-from-ruby-to-erlang/
6
+ #
7
+ require 'socket'
8
+
9
+ module Riak
10
+ class Client
11
+ class Rpc
12
+ include Riak::Util::MessageCode
13
+ include Riak::Util::Translation
14
+ include Riak::Util::Encode
15
+ include Riak::Util::Decode
16
+
17
+ RECV_LIMIT=1638400
18
+
19
+ attr_reader :req_message, :response, :resp_message_codes, :resp_message, :status
20
+
21
+ # Establishes a Client ID with the Riak node, for the life of the RPC connection.
22
+ # @param [Client] the Riak::Client object in which this Rpc instance lives
23
+ def initialize(client)
24
+ @status = false
25
+ @client = client
26
+ @client_id = request(Util::MessageCode::GET_CLIENT_ID_REQUEST).client_id
27
+ @set_client_id = Riak::RpbSetClientIdReq.new(:client_id => @client_id)
28
+
29
+ # Request / Response Data
30
+ @resp_message_codes = -1
31
+ @resp_message = ''
32
+ @req_message_code = -1
33
+ @req_message = ''
34
+ @response = ''
35
+ end
36
+
37
+ # Clears the request / response data, in preparation for a new request
38
+ def clear
39
+ @resp_message_codes = -1
40
+ @resp_message = ''
41
+ @req_message_code = -1
42
+ @req_message = ''
43
+ @response = ''
44
+ @status = false
45
+ end
46
+
47
+ # Opens a TCPSocket connection with the riak host/node
48
+ # @yield [TCPSocket] hands off the socket connection
49
+ # @return [TCPSocket] data that was exchanged with the host/node
50
+ def with_socket(&block)
51
+ socket = TCPSocket.open(@client.host, @client.port)
52
+ set_client_id(socket) if @set_client_id
53
+
54
+ out = yield(socket)
55
+ socket.close
56
+
57
+ return(out)
58
+ end
59
+
60
+ # Sets the Client ID for the TCPSocket session
61
+ # @param [TCPSocket] socket connection for which the Client ID will be set
62
+ # @return [True/False] whether or not the set client id request succeeded
63
+ def set_client_id(socket)
64
+ @set_c_id_req ||= assemble_request( Util::MessageCode::SET_CLIENT_ID_REQUEST,
65
+ @set_client_id.serialize_to_string)
66
+
67
+ socket.send(@set_c_id_req, 0)
68
+ set_c_id_resp = socket.recv(RECV_LIMIT)
69
+
70
+ resp_code, resp_msg = decode_message(set_c_id_resp)
71
+
72
+ return(resp_code == Util::MessageCode::SET_CLIENT_ID_RESPONSE)
73
+ end
74
+
75
+ # Sends the request to the riak node
76
+ # @param [Fixnum] mc The message code that identifies the request
77
+ # @param [Protobuf::Message] pb_msg The protobuf message, if applicable, for the message code
78
+ # @return [True/False] whether or not the set client id request succeeded
79
+ def request(mc, pb_msg=nil)
80
+ clear
81
+
82
+ @req_message_code = mc
83
+ @response = RESPONSE_CLASS_FOR[mc].new unless RESPONSE_CLASS_FOR[mc].nil?
84
+
85
+ with_socket do |socket|
86
+ begin
87
+ @req_message = assemble_request mc, (pb_msg.serialize_to_string rescue '')
88
+
89
+ socket.send(@req_message, 0)
90
+ self.response = socket.recv(RECV_LIMIT)
91
+
92
+ end while(false == (@response.done rescue true))
93
+ end # with_socket
94
+
95
+ return(@response)
96
+ end # stream_request
97
+
98
+ # Handles the response from the Riak node
99
+ # @param [String] value The message returned from the Riak node over the TCP Socket
100
+ # @return [Protobuf::Message] @response the processed response (if any) from the Riak node
101
+ def response=(value)
102
+ @resp_message = value
103
+
104
+ response_chunk, @resp_message_codes = decode_message(value)
105
+
106
+ @resp_message_codes.each do |resp_mc|
107
+ if resp_mc.equal?(ERROR_RESPONSE)
108
+ raise FailedRequest.new(MC_RESPONSE_FOR[@req_message_code], @resp_message_codes, response_chunk)
109
+ end
110
+
111
+ # The below should never really happen
112
+ if resp_mc != MC_RESPONSE_FOR[@req_message_code]
113
+ raise FailedExchange.new(MC_RESPONSE_FOR[@req_message_code], @resp_message_codes, response_chunk, "failed_request")
114
+ end
115
+ end
116
+
117
+ if response_chunk.size > 0
118
+ @response.parse_from_string response_chunk
119
+ end
120
+
121
+ @status = true
122
+ return(@response)
123
+ end
124
+
125
+ end # class Client
126
+ end # module Rpc
127
+ end # module RiakPbclient