riak-client 2.3.2 → 2.4.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{README.markdown → README.md} +72 -0
- data/Rakefile +9 -10
- data/lib/riak/bucket.rb +2 -2
- data/lib/riak/client.rb +51 -19
- data/lib/riak/client/beefcake/messages.rb +10 -10
- data/lib/riak/client/beefcake/object_methods.rb +5 -3
- data/lib/riak/client/beefcake/protocol.rb +30 -3
- data/lib/riak/client/beefcake/socket.rb +10 -13
- data/lib/riak/client/beefcake/time_series_get_operator.rb +8 -3
- data/lib/riak/client/beefcake/time_series_list_operator.rb +8 -3
- data/lib/riak/client/beefcake/time_series_query_operator.rb +8 -3
- data/lib/riak/client/beefcake/ts_cell_codec.rb +11 -1
- data/lib/riak/client/beefcake_protobuffs_backend.rb +23 -14
- data/lib/riak/client/protobuffs_backend.rb +1 -0
- data/lib/riak/counter.rb +2 -2
- data/lib/riak/rcontent.rb +30 -7
- data/lib/riak/robject.rb +9 -3
- data/lib/riak/time_series/list.rb +2 -3
- data/lib/riak/time_series/query.rb +2 -1
- data/lib/riak/time_series/read.rb +2 -1
- data/lib/riak/util/gzip.rb +44 -0
- data/lib/riak/version.rb +1 -1
- data/riak-client.gemspec +11 -11
- data/spec/integration/riak/encodings/kv_spec.rb +6 -0
- data/spec/integration/riak/protobuffs/timeouts_spec.rb +174 -0
- data/spec/integration/riak/time_series_spec.rb +8 -6
- data/spec/riak/beefcake_protobuffs_backend/object_methods_spec.rb +1 -0
- data/spec/riak/beefcake_protobuffs_backend/ts_cell_codec_spec.rb +9 -1
- data/spec/riak/client_spec.rb +49 -2
- data/spec/riak/robject_spec.rb +2 -1
- data/spec/riak/stamp_spec.rb +54 -54
- data/spec/riak/time_series/listing_spec.rb +1 -0
- data/spec/riak/util/gzip_spec.rb +37 -0
- data/spec/support/unified_backend_examples.rb +22 -0
- metadata +28 -23
@@ -2,11 +2,16 @@ require_relative './ts_cell_codec'
|
|
2
2
|
require_relative './operator'
|
3
3
|
|
4
4
|
class Riak::Client::BeefcakeProtobuffsBackend
|
5
|
-
def time_series_list_operator
|
6
|
-
TimeSeriesListOperator.new(self)
|
5
|
+
def time_series_list_operator(convert_timestamp)
|
6
|
+
TimeSeriesListOperator.new(self, convert_timestamp)
|
7
7
|
end
|
8
8
|
|
9
9
|
class TimeSeriesListOperator < Operator
|
10
|
+
def initialize(backend, convert_timestamp)
|
11
|
+
super(backend)
|
12
|
+
@convert_timestamp = convert_timestamp
|
13
|
+
end
|
14
|
+
|
10
15
|
def list(table_name, block, options = { })
|
11
16
|
request = TsListKeysReq.new options.merge(table: table_name)
|
12
17
|
|
@@ -25,7 +30,7 @@ class Riak::Client::BeefcakeProtobuffsBackend
|
|
25
30
|
backend.protocol do |p|
|
26
31
|
p.write :TsListKeysReq, request
|
27
32
|
|
28
|
-
codec = TsCellCodec.new
|
33
|
+
codec = TsCellCodec.new(@convert_timestamp)
|
29
34
|
|
30
35
|
while resp = p.expect(:TsListKeysResp, TsListKeysResp)
|
31
36
|
break if resp.done
|
@@ -2,11 +2,16 @@ require_relative './ts_cell_codec'
|
|
2
2
|
require_relative './operator'
|
3
3
|
|
4
4
|
class Riak::Client::BeefcakeProtobuffsBackend
|
5
|
-
def time_series_query_operator
|
6
|
-
TimeSeriesQueryOperator.new(self)
|
5
|
+
def time_series_query_operator(convert_timestamp)
|
6
|
+
TimeSeriesQueryOperator.new(self, convert_timestamp)
|
7
7
|
end
|
8
8
|
|
9
9
|
class TimeSeriesQueryOperator < Operator
|
10
|
+
def initialize(backend, convert_timestamp)
|
11
|
+
super(backend)
|
12
|
+
@convert_timestamp = convert_timestamp
|
13
|
+
end
|
14
|
+
|
10
15
|
def query(base, interpolations = { })
|
11
16
|
interpolator = TsInterpolation.new base: base
|
12
17
|
interpolator.interpolations = pairs_for interpolations
|
@@ -20,7 +25,7 @@ class Riak::Client::BeefcakeProtobuffsBackend
|
|
20
25
|
|
21
26
|
return [] if :empty == result
|
22
27
|
|
23
|
-
codec = TsCellCodec.new
|
28
|
+
codec = TsCellCodec.new(@convert_timestamp)
|
24
29
|
|
25
30
|
collection = Riak::TimeSeries::Collection.
|
26
31
|
new(result.rows.map do |row|
|
@@ -2,6 +2,12 @@ require 'bigdecimal'
|
|
2
2
|
|
3
3
|
class Riak::Client::BeefcakeProtobuffsBackend
|
4
4
|
class TsCellCodec
|
5
|
+
attr_accessor :convert_timestamp
|
6
|
+
|
7
|
+
def initialize(convert_timestamp = false)
|
8
|
+
@convert_timestamp = convert_timestamp
|
9
|
+
end
|
10
|
+
|
5
11
|
def cells_for(measures)
|
6
12
|
measures.map{ |m| cell_for m }
|
7
13
|
end
|
@@ -57,7 +63,11 @@ class Riak::Client::BeefcakeProtobuffsBackend
|
|
57
63
|
|
58
64
|
def timestamp(cell)
|
59
65
|
return false unless cell.timestamp_value.is_a? Integer
|
60
|
-
|
66
|
+
return cell.timestamp_value unless @convert_timestamp
|
67
|
+
tsv = cell.timestamp_value
|
68
|
+
secs = tsv / 1000
|
69
|
+
msec = tsv % 1000
|
70
|
+
Time.at(secs, msec * 1000)
|
61
71
|
end
|
62
72
|
end
|
63
73
|
end
|
@@ -31,7 +31,11 @@ module Riak
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def protocol
|
34
|
-
p = Protocol.new
|
34
|
+
p = Protocol.new(
|
35
|
+
socket,
|
36
|
+
read_timeout: client.read_timeout,
|
37
|
+
write_timeout: client.write_timeout
|
38
|
+
)
|
35
39
|
in_request = false
|
36
40
|
result = nil
|
37
41
|
begin
|
@@ -45,7 +49,12 @@ module Riak
|
|
45
49
|
end
|
46
50
|
|
47
51
|
def new_socket
|
48
|
-
BeefcakeSocket.new
|
52
|
+
BeefcakeSocket.new(
|
53
|
+
@node.host,
|
54
|
+
@node.pb_port,
|
55
|
+
authentication: client.authentication,
|
56
|
+
connect_timeout: client.connect_timeout
|
57
|
+
)
|
49
58
|
end
|
50
59
|
|
51
60
|
def ping
|
@@ -333,18 +342,18 @@ module Riak
|
|
333
342
|
def get_index(bucket, index, query, query_options = {}, &block)
|
334
343
|
return super unless pb_indexes?
|
335
344
|
bucket = bucket.name if Bucket === bucket
|
336
|
-
if Range === query
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
345
|
+
options = if Range === query
|
346
|
+
{
|
347
|
+
:qtype => RpbIndexReq::IndexQueryType::RANGE,
|
348
|
+
:range_min => query.begin.to_s,
|
349
|
+
:range_max => query.end.to_s
|
350
|
+
}
|
351
|
+
else
|
352
|
+
{
|
353
|
+
:qtype => RpbIndexReq::IndexQueryType::EQ,
|
354
|
+
:key => query.to_s
|
355
|
+
}
|
356
|
+
end
|
348
357
|
|
349
358
|
options.merge!(:bucket => bucket, :index => index.to_s)
|
350
359
|
options.merge!(query_options)
|
data/lib/riak/counter.rb
CHANGED
@@ -14,8 +14,8 @@ module Riak
|
|
14
14
|
# @param [Bucket] bucket the {Riak::Bucket} for this counter
|
15
15
|
# @param [String] key the name of the counter
|
16
16
|
def initialize(bucket, key)
|
17
|
-
raise ArgumentError, t(
|
18
|
-
raise ArgumentError, t(
|
17
|
+
raise ArgumentError, t('bucket_type', bucket: bucket.inspect) unless bucket.is_a? Bucket
|
18
|
+
raise ArgumentError, t('string_type', string: key.inspect) unless key.is_a? String
|
19
19
|
@bucket, @key = bucket, key
|
20
20
|
@client = bucket.client
|
21
21
|
|
data/lib/riak/rcontent.rb
CHANGED
@@ -2,6 +2,7 @@ require 'set'
|
|
2
2
|
require 'time'
|
3
3
|
require 'yaml'
|
4
4
|
require 'forwardable'
|
5
|
+
require 'riak/util/gzip'
|
5
6
|
require 'riak/util/translation'
|
6
7
|
require 'riak/serializers'
|
7
8
|
|
@@ -17,6 +18,9 @@ module Riak
|
|
17
18
|
# @return [String] the MIME content type of the value
|
18
19
|
attr_accessor :content_type
|
19
20
|
|
21
|
+
# @return [String] the content encoding of the object, e.g. "gzip"
|
22
|
+
attr_accessor :content_encoding
|
23
|
+
|
20
24
|
# @return [Set<Link>] a Set of {Riak::Link} objects for relationships between this object and other resources
|
21
25
|
attr_accessor :links
|
22
26
|
|
@@ -63,7 +67,7 @@ module Riak
|
|
63
67
|
def data
|
64
68
|
if @raw_data && !@data
|
65
69
|
raw = @raw_data.respond_to?(:read) ? @raw_data.read : @raw_data
|
66
|
-
@data = deserialize(raw)
|
70
|
+
@data = deserialize(decompress(raw))
|
67
71
|
@raw_data = nil
|
68
72
|
end
|
69
73
|
@data
|
@@ -86,7 +90,7 @@ module Riak
|
|
86
90
|
# @return [String] raw data stored in riak for this object's key
|
87
91
|
def raw_data
|
88
92
|
if @data && !@raw_data
|
89
|
-
@raw_data = serialize(@data)
|
93
|
+
@raw_data = compress(serialize(@data))
|
90
94
|
@data = nil
|
91
95
|
end
|
92
96
|
@raw_data
|
@@ -125,6 +129,26 @@ module Riak
|
|
125
129
|
Serializers.deserialize(@content_type, body)
|
126
130
|
end
|
127
131
|
|
132
|
+
# Compresses the given string using gzip if {#content_encoding} is set to "gzip".
|
133
|
+
# Otherwise the given string is returned as-is.
|
134
|
+
# This method is called internally when storing the object.
|
135
|
+
# @param [String] data
|
136
|
+
# @return [String]
|
137
|
+
def compress(data)
|
138
|
+
return data unless content_encoding == "gzip"
|
139
|
+
Util::Gzip.compress(data)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Decompresses the given string using gzip if {#content_encoding} is set to "gzip".
|
143
|
+
# Otherwise the given string is returned as-is.
|
144
|
+
# This method is called internally when loading the object.
|
145
|
+
# @param [String] data
|
146
|
+
# @return [String]
|
147
|
+
def decompress(data)
|
148
|
+
return data unless content_encoding == "gzip"
|
149
|
+
Util::Gzip.decompress(data)
|
150
|
+
end
|
151
|
+
|
128
152
|
# @return [String] A representation suitable for IRB and debugging output
|
129
153
|
def inspect
|
130
154
|
body = if @data || Serializers[content_type]
|
@@ -159,11 +183,10 @@ module Riak
|
|
159
183
|
|
160
184
|
private
|
161
185
|
def extract_if_present(hash, key, attribute = nil)
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
end
|
186
|
+
return unless hash[key].present?
|
187
|
+
attribute ||= key
|
188
|
+
value = block_given? ? yield(hash[key]) : hash[key]
|
189
|
+
send("#{attribute}=", value)
|
167
190
|
end
|
168
191
|
|
169
192
|
def new_index_hash
|
data/lib/riak/robject.rb
CHANGED
@@ -56,6 +56,7 @@ module Riak
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def_delegators :content, :content_type, :content_type=,
|
59
|
+
:content_encoding, :content_encoding=,
|
59
60
|
:links, :links=,
|
60
61
|
:etag, :etag=,
|
61
62
|
:last_modified, :last_modified=,
|
@@ -63,7 +64,8 @@ module Riak
|
|
63
64
|
:indexes, :indexes=,
|
64
65
|
:data, :data=,
|
65
66
|
:raw_data, :raw_data=,
|
66
|
-
:deserialize, :serialize
|
67
|
+
:deserialize, :serialize,
|
68
|
+
:decompress, :compress
|
67
69
|
|
68
70
|
# Attempts to resolve conflict using the registered conflict callbacks.
|
69
71
|
#
|
@@ -139,8 +141,12 @@ module Riak
|
|
139
141
|
# @raise [Conflict] if the object has siblings
|
140
142
|
def store(options = {})
|
141
143
|
fail Conflict, self if conflict?
|
142
|
-
|
143
|
-
|
144
|
+
raise ArgumentError, t('content_type_undefined') unless content_type.present?
|
145
|
+
raise ArgumentError, t('zero_length_key') if key == ''
|
146
|
+
# NB: key can be nil to indicate that Riak should generate one
|
147
|
+
unless key.nil? || key.is_a?(String)
|
148
|
+
raise ArgumentError, t('string_type', :string => key)
|
149
|
+
end
|
144
150
|
@bucket.client.store_object(self, default(options))
|
145
151
|
self
|
146
152
|
end
|
@@ -44,9 +44,8 @@ module Riak::TimeSeries
|
|
44
44
|
potential_results = nil
|
45
45
|
|
46
46
|
client.backend do |be|
|
47
|
-
|
48
|
-
|
49
|
-
options)
|
47
|
+
op = be.time_series_list_operator(client.convert_timestamp)
|
48
|
+
potential_results = op.list(table_name, block, options)
|
50
49
|
end
|
51
50
|
|
52
51
|
return @results = potential_results unless block_given?
|
@@ -36,7 +36,8 @@ module Riak::TimeSeries
|
|
36
36
|
# attribute
|
37
37
|
def issue!
|
38
38
|
@results = client.backend do |be|
|
39
|
-
be.time_series_query_operator.
|
39
|
+
op = be.time_series_query_operator(client.convert_timestamp)
|
40
|
+
op.query(query_text, interpolations)
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Riak
|
5
|
+
module Util
|
6
|
+
# Borrowed from ActiveSupport
|
7
|
+
# https://github.com/rails/rails/blob/master/activesupport/lib/active_support/gzip.rb
|
8
|
+
#
|
9
|
+
# A convenient wrapper for the zlib standard library that allows
|
10
|
+
# compression/decompression of strings with gzip.
|
11
|
+
#
|
12
|
+
# gzip = Riak::Util::Gzip.compress('compress me!')
|
13
|
+
# # => "\x1F\x8B\b\x00o\x8D\xCDO\x00\x03K\xCE\xCF-(J-.V\xC8MU\x04\x00R>n\x83\f\x00\x00\x00"
|
14
|
+
#
|
15
|
+
# Riak::Util::Gzip.decompress(gzip)
|
16
|
+
# # => "compress me!"
|
17
|
+
module Gzip
|
18
|
+
class Stream < StringIO
|
19
|
+
def initialize(*)
|
20
|
+
super
|
21
|
+
set_encoding "BINARY"
|
22
|
+
end
|
23
|
+
|
24
|
+
def close
|
25
|
+
rewind
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Decompresses a gzipped string.
|
30
|
+
def self.decompress(source)
|
31
|
+
Zlib::GzipReader.new(StringIO.new(source)).read
|
32
|
+
end
|
33
|
+
|
34
|
+
# Compresses a string using gzip.
|
35
|
+
def self.compress(source, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY)
|
36
|
+
output = Stream.new
|
37
|
+
gz = Zlib::GzipWriter.new(output, level, strategy)
|
38
|
+
gz.write(source)
|
39
|
+
gz.close
|
40
|
+
output.string
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/riak/version.rb
CHANGED
data/riak-client.gemspec
CHANGED
@@ -10,23 +10,23 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.email = ['bryce@basho.com']
|
11
11
|
gem.homepage = "http://github.com/basho/riak-ruby-client"
|
12
12
|
gem.authors = ['Bryce Kerley']
|
13
|
-
gem.license = 'Apache
|
13
|
+
gem.license = 'Apache-2.0'
|
14
14
|
|
15
15
|
gem.required_ruby_version = '>= 1.9.3'
|
16
16
|
|
17
17
|
# Deps
|
18
|
-
gem.add_development_dependency
|
19
|
-
gem.add_development_dependency 'rake', '~> 10.1
|
20
|
-
gem.add_development_dependency 'yard', '~> 0.8
|
18
|
+
gem.add_development_dependency 'rspec', '~> 3.0'
|
19
|
+
gem.add_development_dependency 'rake', '~> 10.1'
|
20
|
+
gem.add_development_dependency 'yard', '~> 0.8'
|
21
21
|
gem.add_development_dependency 'kramdown', '~> 1.4'
|
22
|
-
gem.add_development_dependency 'simplecov', '~> 0.10
|
23
|
-
gem.add_development_dependency
|
24
|
-
gem.add_development_dependency
|
22
|
+
gem.add_development_dependency 'simplecov', '~> 0.10'
|
23
|
+
gem.add_development_dependency 'instrumentable', '~> 1.1'
|
24
|
+
gem.add_development_dependency 'rubocop', '~> 0.40'
|
25
25
|
|
26
|
-
gem.add_runtime_dependency
|
27
|
-
gem.add_runtime_dependency
|
28
|
-
gem.add_runtime_dependency
|
29
|
-
gem.add_runtime_dependency
|
26
|
+
gem.add_runtime_dependency 'i18n', '~> 0.6'
|
27
|
+
gem.add_runtime_dependency 'beefcake', '~> 1.1'
|
28
|
+
gem.add_runtime_dependency 'multi_json', '~> 1.0'
|
29
|
+
gem.add_runtime_dependency 'innertube', '~> 1.0'
|
30
30
|
gem.add_runtime_dependency 'cert_validator', '~> 0.0.1'
|
31
31
|
|
32
32
|
# Files
|
@@ -77,5 +77,11 @@ describe 'Encoding and Riak KV', integration: true, test_client: true do
|
|
77
77
|
|
78
78
|
expect(binary_bucket.keys).to include random_binary_string
|
79
79
|
end
|
80
|
+
|
81
|
+
it 'throws an exception when non-string used as key' do
|
82
|
+
expect do
|
83
|
+
binary_bucket.get(1234)
|
84
|
+
end.to raise_error ArgumentError, /is not a String/
|
85
|
+
end
|
80
86
|
end
|
81
87
|
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
require 'riak/client/beefcake/messages'
|
5
|
+
require 'riak/client/beefcake/protocol'
|
6
|
+
|
7
|
+
describe 'Protocol Buffers', test_client: true, integration: true do
|
8
|
+
describe 'timeouts' do
|
9
|
+
it 'raises error on connect timeout' do
|
10
|
+
# unroutable TEST-NET (https://tools.ietf.org/html/rfc5737)
|
11
|
+
config = {}
|
12
|
+
config[:host] = '192.0.2.0'
|
13
|
+
config[:pb_port] = 65535
|
14
|
+
|
15
|
+
config[:connect_timeout] = 0.0001
|
16
|
+
client = Riak::Client.new(config)
|
17
|
+
|
18
|
+
expect do
|
19
|
+
client.ping
|
20
|
+
end.to raise_error RuntimeError, /timed out/
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'raises error on read timeout' do
|
24
|
+
ok_to_continue = false
|
25
|
+
quitting = false
|
26
|
+
port = 0
|
27
|
+
|
28
|
+
server = nil
|
29
|
+
thr = Thread.new do
|
30
|
+
server = TCPServer.new port
|
31
|
+
port = server.addr[1]
|
32
|
+
ok_to_continue = true
|
33
|
+
loop do
|
34
|
+
begin
|
35
|
+
Thread.start(server.accept) do |s|
|
36
|
+
loop do
|
37
|
+
p = Riak::Client::BeefcakeProtobuffsBackend::Protocol.new s
|
38
|
+
begin
|
39
|
+
msgname, _body = p.receive
|
40
|
+
rescue IOError
|
41
|
+
break if quitting
|
42
|
+
raise
|
43
|
+
end
|
44
|
+
case msgname
|
45
|
+
when :PingReq
|
46
|
+
sleep 0.5
|
47
|
+
p.write :PingResp
|
48
|
+
else
|
49
|
+
$stderr.puts("unknown msgname: #{msgname}")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
rescue IOError
|
54
|
+
break if quitting
|
55
|
+
raise
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
loop do
|
61
|
+
break if ok_to_continue
|
62
|
+
sleep 0.1
|
63
|
+
end
|
64
|
+
ok_to_continue = false
|
65
|
+
|
66
|
+
config = {}
|
67
|
+
config[:pb_port] = port
|
68
|
+
config[:client_id] = port
|
69
|
+
config[:read_timeout] = 0.0001
|
70
|
+
client = Riak::Client.new(config)
|
71
|
+
|
72
|
+
max_ping_attempts = 16
|
73
|
+
ping_count = 0
|
74
|
+
loop do
|
75
|
+
begin
|
76
|
+
client.ping
|
77
|
+
ping_count += 1
|
78
|
+
break if ping_count > max_ping_attempts
|
79
|
+
rescue RuntimeError => e
|
80
|
+
break if e.message =~ /timed out/
|
81
|
+
end
|
82
|
+
sleep 0.5
|
83
|
+
end
|
84
|
+
|
85
|
+
quitting = true
|
86
|
+
server.close
|
87
|
+
thr.join
|
88
|
+
|
89
|
+
expect(ping_count).to be < max_ping_attempts
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'raises error on write timeout' do
|
93
|
+
ok_to_continue = false
|
94
|
+
quitting = false
|
95
|
+
port = 0
|
96
|
+
|
97
|
+
server = nil
|
98
|
+
thr = Thread.new do
|
99
|
+
server = TCPServer.new port
|
100
|
+
port = server.addr[1]
|
101
|
+
ok_to_continue = true
|
102
|
+
loop do
|
103
|
+
begin
|
104
|
+
Thread.start(server.accept) do |s|
|
105
|
+
loop do
|
106
|
+
p = Riak::Client::BeefcakeProtobuffsBackend::Protocol.new s
|
107
|
+
begin
|
108
|
+
msgname, _body = p.receive
|
109
|
+
rescue IOError
|
110
|
+
break if quitting
|
111
|
+
raise
|
112
|
+
end
|
113
|
+
case msgname
|
114
|
+
when :PingReq
|
115
|
+
p.write :PingResp
|
116
|
+
when :GetServerInfoReq
|
117
|
+
r = Riak::Client::BeefcakeProtobuffsBackend::RpbGetServerInfoResp.new
|
118
|
+
r.node = 'dev1@127.0.0.1'.force_encoding('BINARY')
|
119
|
+
r.server_version = '2.1.4'.force_encoding('BINARY')
|
120
|
+
p.write :GetServerInfoResp, r
|
121
|
+
when :PutReq
|
122
|
+
r = Riak::Client::BeefcakeProtobuffsBackend::RpbPutResp.new
|
123
|
+
p.write :PutResp, r
|
124
|
+
else
|
125
|
+
$stderr.puts("unknown msgname: #{msgname}")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
rescue IOError
|
130
|
+
break if quitting
|
131
|
+
raise
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
loop do
|
137
|
+
break if ok_to_continue
|
138
|
+
sleep 0.1
|
139
|
+
end
|
140
|
+
ok_to_continue = false
|
141
|
+
|
142
|
+
config = {}
|
143
|
+
config[:pb_port] = port
|
144
|
+
config[:client_id] = port
|
145
|
+
config[:write_timeout] = 0.0001
|
146
|
+
client = Riak::Client.new(config)
|
147
|
+
|
148
|
+
bucket = client.bucket('timeouts')
|
149
|
+
|
150
|
+
max_store_attempts = 16
|
151
|
+
store_count = 0
|
152
|
+
loop do
|
153
|
+
begin
|
154
|
+
obj = bucket.new "obj-#{store_count}"
|
155
|
+
# write enough data to grow beyond socket buffer capacity
|
156
|
+
obj.data = SecureRandom.urlsafe_base64(10_000_000)
|
157
|
+
obj.content_type = 'text/plain'
|
158
|
+
obj.store
|
159
|
+
store_count += 1
|
160
|
+
break if store_count > max_store_attempts
|
161
|
+
rescue RuntimeError => e
|
162
|
+
break if e.message =~ /timed out/
|
163
|
+
end
|
164
|
+
sleep 0.5
|
165
|
+
end
|
166
|
+
|
167
|
+
quitting = true
|
168
|
+
server.close
|
169
|
+
thr.join
|
170
|
+
|
171
|
+
expect(store_count).to be < max_store_attempts
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|