Skip to content

Commit be0be7f

Browse files
authored
Merge pull request #298 from basho/features/lrb/riak-client-2.6.0
Riak Ruby Client 2.6.0
2 parents f605d63 + c545e37 commit be0be7f

14 files changed

Lines changed: 309 additions & 192 deletions

.rubocop_todo.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ Lint/AssignmentInCondition:
3737
- 'lib/riak/client/beefcake/object_methods.rb'
3838
- 'lib/riak/client/beefcake/time_series_list_operator.rb'
3939
- 'lib/riak/client/beefcake_protobuffs_backend.rb'
40-
- 'lib/riak/multiget.rb'
4140

4241
# Offense count: 4
4342
# Cop supports --auto-correct.

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ help:
3232
@echo ' test - Run unit & integration tests '
3333
@echo ' unit-test - Run unit tests '
3434
@echo ' integration-test - Run integration tests '
35+
@echo ' timeseries-test - Run timeseries tests '
3536
@echo ' security-test - Run security tests '
3637
@echo '-------------------------------------------------'
3738
@echo ''
@@ -56,6 +57,10 @@ integration-test:
5657
@cp -f $(TCY).example $(TCY)
5758
@bundle exec rake spec:integration
5859

60+
timeseries-test:
61+
@cp -f $(TCY).example $(TCY)
62+
@bundle exec rake spec:time_series
63+
5964
security-test:
6065
@cp -f $(TCY).example $(TCY) && \
6166
echo 'authentication:' >> $(TCY) && \
@@ -64,7 +69,7 @@ security-test:
6469
echo " ca_file: $(CA_CERT)" >> $(TCY)
6570
@bundle exec rake spec:security
6671

67-
test: lint integration-test
72+
test: lint unit-test integration-test
6873

6974
gemspec_validate:
7075
@bundle exec rake gemspec

lib/riak/bucket.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def get(key, options = {})
114114
# @return [Hash<String, Riak::RObject>] hash of keys to objects
115115
def get_many(keys)
116116
pairs = keys.map{|k| [self, k]}
117-
results = Multiget.get_all @client, pairs
117+
results = Multiget.perform @client, pairs
118118
results.keys.inject(Hash.new) do |mem, var|
119119
mem[var[1]] = results[var]
120120
mem

lib/riak/client.rb

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
require 'riak/bucket_properties'
1919
require 'riak/bucket_type'
2020
require 'riak/multiget'
21+
require 'riak/multiexist'
2122
require 'riak/secondary_index'
2223
require 'riak/search'
2324
require 'riak/stamp'
@@ -69,7 +70,10 @@ class Client
6970
attr_reader :protobuffs_pool
7071

7172
# @return [Integer] The number of threads for multiget requests
72-
attr_reader :multiget_threads
73+
attr_reader :multi_threads
74+
75+
# @deprecated use multi_threads
76+
alias_method :multiget_threads, :multi_threads
7377

7478
# @return [Hash] The authentication information this client will use.
7579
attr_reader :authentication
@@ -123,7 +127,7 @@ def initialize(options = {})
123127

124128
self.protobuffs_backend = options[:protobuffs_backend] || :Beefcake
125129
self.client_id = options[:client_id] if options[:client_id]
126-
self.multiget_threads = options[:multiget_threads]
130+
self.multi_threads = options[:multi_threads] || options[:multiget_threads]
127131
@authentication = options[:authentication] && options[:authentication].symbolize_keys
128132
self.max_retries = options[:max_retries] || 2
129133
@connect_timeout = options[:connect_timeout]
@@ -195,20 +199,23 @@ def choose_node(nodes = self.nodes)
195199
# If set to nil, defaults to twice the number of nodes.
196200
# @param [Integer] count The number of threads to use.
197201
# @raise [ArgumentError] when a non-nil, non-positive-Integer count is given
198-
def multiget_threads=(count)
202+
def multi_threads=(count)
199203
if count.nil?
200-
@multiget_threads = nodes.length * 2
204+
@multi_threads = nodes.length * 2
201205
return
202206
end
203207

204208
if count.is_a?(Integer) && count > 0
205-
@multiget_threads = count
209+
@multi_threads = count
206210
return
207211
end
208212

209-
raise ArgumentError, t("invalid_multiget_thread_count")
213+
raise ArgumentError, t("invalid_multiget_thread_count") # TODO: rename to invalid_multi_thread_count
210214
end
211215

216+
# @deprecated use multi_threads=
217+
alias_method :multiget_threads=, :multi_threads=
218+
212219
# Set the client ID for this client. Must be a string or Fixnum value 0 =<
213220
# value < MAX_CLIENT_ID.
214221
# @param [String, Fixnum] value The internal client ID used by Riak to route responses
@@ -275,7 +282,7 @@ def get_preflist(bucket, key, type = nil, options = { })
275282

276283
# Get multiple objects in parallel.
277284
def get_many(pairs)
278-
Multiget.get_all self, pairs
285+
Multiget.perform self, pairs
279286
end
280287

281288
# Get an object. See Bucket#get

lib/riak/multi.rb

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
require 'riak/client'
2+
require 'riak/bucket'
3+
4+
module Riak
5+
# Coordinates a parallel operation for multiple keys.
6+
class Multi
7+
include Util::Translation
8+
9+
# @return [Riak::Client] the associated client
10+
attr_reader :client
11+
12+
# @return [Array<Bucket, String>] fetch_list an {Array} of {Bucket} and {String} keys
13+
attr_reader :keys
14+
15+
# @return [Hash<fetch_list_entry, RObject] result_hash a {Hash} of {Bucket} and {String} key pairs to {RObject} instances
16+
attr_accessor :result_hash
17+
18+
# @return [Integer] The number of threads to use
19+
attr_accessor :thread_count
20+
21+
# Perform a Riak Multi operation.
22+
# @param [Client] client the {Riak::Client} that will perform the operation
23+
# @param [Array<Bucket, String>] keys an {Array} of {Bucket} and {String} keys to work with
24+
# @return [Hash<key, RObject] result_hash a {Hash} of {Bucket} and {String} key pairs to {RObject} instances
25+
def self.perform(client, keys)
26+
multi = new client, keys
27+
multi.perform
28+
multi.results
29+
end
30+
31+
# Create a Riak Multi operation.
32+
# @param [Client] client the {Riak::Client} that will perform the multiget
33+
# @param [Array<Bucket, String>] keys an {Array} of {Bucket} and {String} keys to work on
34+
# @raise [ArgumentError] when a non-positive-Integer count is given for threads
35+
def initialize(client, keys)
36+
raise ArgumentError, t('client_type', :client => client.inspect) unless client.is_a? Riak::Client
37+
raise ArgumentError, t('array_type', :array => keys.inspect) unless keys.is_a? Array
38+
39+
self.thread_count = client.multi_threads
40+
validate_keys keys
41+
@client = client
42+
@keys = keys.uniq
43+
self.result_hash = {}
44+
@finished = false
45+
end
46+
47+
# Starts the parallelized operation
48+
def perform
49+
queue = keys.dup
50+
queue_mutex = Mutex.new
51+
result_mutex = Mutex.new
52+
53+
@threads = 1.upto(thread_count).map do |_node|
54+
Thread.new do
55+
loop do
56+
pair = queue_mutex.synchronize do
57+
queue.shift
58+
end
59+
60+
break if pair.nil?
61+
62+
found = work(*pair)
63+
result_mutex.synchronize do
64+
result_hash[pair] = found
65+
end
66+
end
67+
end
68+
end
69+
end
70+
71+
def results
72+
wait_for_finish
73+
result_hash
74+
end
75+
76+
def finished?
77+
@finished ||= @threads && @threads.none?(&:alive?)
78+
end
79+
alias :finished :finished? # deprecated
80+
81+
def wait_for_finish
82+
return if finished?
83+
@threads.each(&:join)
84+
@finished = true
85+
end
86+
87+
private
88+
89+
def work(_bucket, _key)
90+
raise NotImplementedError
91+
end
92+
93+
def validate_keys(keys)
94+
erroneous = keys.detect do |bucket, key|
95+
!bucket.is_a?(Bucket) || !key.is_a?(String)
96+
end
97+
return unless erroneous
98+
raise ArgumentError, t('fetch_list_type', problem: erroneous) # TODO: should be keys_type
99+
end
100+
end
101+
end

lib/riak/multiexist.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
require 'riak/client'
2+
require 'riak/bucket'
3+
require 'riak/multi'
4+
5+
module Riak
6+
# Coordinates a parallel exist? operation for multiple keys.
7+
class Multiexist < Multi
8+
private
9+
10+
def work(bucket, key)
11+
bucket.exists?(key)
12+
end
13+
end
14+
end

lib/riak/multiget.rb

Lines changed: 7 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,122 +1,22 @@
11
require 'riak/client'
22
require 'riak/bucket'
3+
require 'riak/multi'
34

45
module Riak
5-
# Coordinates a parallel fetch operation for multiple values.
6-
class Multiget
7-
include Util::Translation
8-
9-
# @return [Riak::Client] the associated client
10-
attr_reader :client
11-
12-
# @return [Array<Bucket, String>] fetch_list an {Array} of {Bucket} and {String} keys to fetch
13-
attr_reader :fetch_list
14-
15-
# @return [Hash<fetch_list_entry, RObject] result_hash a {Hash} of {Bucket} and {String} key pairs to {RObject} instances
16-
attr_accessor :result_hash
17-
18-
# @return [Boolean] finished if the fetch operation has completed
19-
attr_reader :finished
20-
21-
# @return [Integer] The number of threads to use
22-
attr_accessor :thread_count
23-
24-
# Perform a Riak Multiget operation.
25-
# @param [Client] client the {Riak::Client} that will perform the multiget
26-
# @param [Array<Bucket, String>] fetch_list an {Array} of {Bucket} and {String} keys to fetch
27-
# @return [Hash<fetch_list_entry, RObject] result_hash a {Hash} of {Bucket} and {String} key pairs to {RObject} instances
28-
def self.get_all(client, fetch_list)
29-
multi = new client, fetch_list
30-
multi.fetch
31-
multi.results
32-
end
33-
34-
# Create a Riak Multiget operation.
35-
# @param [Client] client the {Riak::Client} that will perform the multiget
36-
# @param [Array<Bucket, String>] fetch_list an {Array} of {Bucket} and {String} keys to fetch
37-
def initialize(client, fetch_list)
38-
raise ArgumentError, t('client_type', :client => client.inspect) unless client.is_a? Riak::Client
39-
raise ArgumentError, t('array_type', :array => fetch_list.inspect) unless fetch_list.is_a? Array
40-
41-
validate_fetch_list fetch_list
42-
@client, @fetch_list = client, fetch_list.uniq
43-
self.result_hash = Hash.new
44-
@finished = false
45-
self.thread_count = client.multiget_threads
46-
end
47-
48-
# Starts the parallelized fetch operation
49-
# @raise [ArgumentError] when a non-positive-Integer count is given
50-
def fetch
51-
queue = fetch_list.dup
52-
queue_mutex = Mutex.new
53-
result_mutex = Mutex.new
54-
55-
unless thread_count.is_a?(Integer) && thread_count > 0
56-
raise ArgumentError, t("invalid_multiget_thread_count")
57-
end
58-
59-
@threads = 1.upto(thread_count).map do |_node|
60-
Thread.new do
61-
loop do
62-
pair = queue_mutex.synchronize do
63-
queue.shift
64-
end
65-
66-
break if pair.nil?
67-
68-
found = attempt_fetch(*pair)
69-
result_mutex.synchronize do
70-
result_hash[pair] = found
71-
end
72-
end
73-
end
74-
end
75-
end
76-
77-
def results
78-
wait_for_finish
79-
result_hash
80-
end
81-
82-
def finished?
83-
set_finished_for_thread_liveness
84-
finished
85-
end
86-
87-
def wait_for_finish
88-
return if finished?
89-
@threads.each {|t| t.join }
90-
@finished = true
6+
# Coordinates a parallel fetch operation for multiple keys.
7+
class Multiget < Multi
8+
# @deprecated use perform
9+
class << self
10+
alias_method :get_all, :perform
9111
end
9212

9313
private
9414

95-
def attempt_fetch(bucket, key)
15+
def work(bucket, key)
9616
bucket[key]
9717
rescue Riak::FailedRequest => e
9818
raise e unless e.not_found?
9919
nil
10020
end
101-
102-
def set_finished_for_thread_liveness
103-
return if @finished # already done
104-
105-
all_dead = @threads.none? {|t| t.alive? }
106-
return unless all_dead # still working
107-
108-
@finished = true
109-
return
110-
end
111-
112-
def validate_fetch_list(fetch_list)
113-
return unless erroneous = fetch_list.detect do |e|
114-
bucket, key = e
115-
next true unless bucket.is_a? Bucket
116-
next true unless key.is_a? String
117-
end
118-
119-
raise ArgumentError, t('fetch_list_type', :problem => erroneous)
120-
end
12121
end
12222
end

riak-client.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
1818
gem.add_development_dependency 'rake', '~> 10.1'
1919
gem.add_development_dependency 'rspec', '~> 3.0'
2020
gem.add_development_dependency 'rubocop', '~> 0.40.0'
21-
gem.add_development_dependency 'simplecov', '~> 0.10'
21+
gem.add_development_dependency 'single_cov', '0.5.7'
2222
gem.add_development_dependency 'yard', '~> 0.8'
2323

2424
gem.add_runtime_dependency 'beefcake', '~> 1.1'

spec/integration/riak/bucket_types_spec.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
require 'riak'
33

44
describe 'Bucket Types', test_client: true, integration: true do
5-
65
describe 'nested bucket types API' do
76
let(:bucket_type){ test_client.bucket_type 'yokozuna' }
87

0 commit comments

Comments
 (0)