riak-client 0.9.0.beta → 0.9.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +10 -7
- data/Rakefile +21 -3
- data/erl_src/riak_kv_test_backend.beam +0 -0
- data/erl_src/riak_kv_test_backend.erl +29 -13
- data/lib/riak/bucket.rb +1 -1
- data/lib/riak/cache_store.rb +1 -1
- data/lib/riak/client.rb +119 -8
- data/lib/riak/client/beefcake/messages.rb +162 -0
- data/lib/riak/client/beefcake/object_methods.rb +92 -0
- data/lib/riak/client/beefcake_protobuffs_backend.rb +186 -0
- data/lib/riak/client/curb_backend.rb +10 -16
- data/lib/riak/client/excon_backend.rb +14 -18
- data/lib/riak/client/http_backend.rb +13 -13
- data/lib/riak/client/http_backend/object_methods.rb +1 -1
- data/lib/riak/client/http_backend/transport_methods.rb +6 -2
- data/lib/riak/client/net_http_backend.rb +33 -20
- data/lib/riak/client/protobuffs_backend.rb +103 -0
- data/lib/riak/client/pump.rb +44 -0
- data/lib/riak/failed_request.rb +58 -3
- data/lib/riak/locale/en.yml +11 -3
- data/lib/riak/map_reduce.rb +15 -6
- data/lib/riak/map_reduce/filter_builder.rb +4 -4
- data/lib/riak/test_server.rb +5 -1
- data/lib/riak/util/multipart.rb +30 -16
- data/lib/riak/util/multipart/stream_parser.rb +74 -0
- data/riak-client.gemspec +14 -12
- data/spec/fixtures/server.cert.crt +15 -0
- data/spec/fixtures/server.cert.key +15 -0
- data/spec/fixtures/test.pem +1 -0
- data/spec/integration/riak/http_backends_spec.rb +45 -0
- data/spec/integration/riak/protobuffs_backends_spec.rb +45 -0
- data/spec/integration/riak/test_server_spec.rb +2 -2
- data/spec/riak/bucket_spec.rb +4 -4
- data/spec/riak/client_spec.rb +209 -3
- data/spec/riak/excon_backend_spec.rb +8 -7
- data/spec/riak/http_backend/configuration_spec.rb +64 -0
- data/spec/riak/http_backend/object_methods_spec.rb +1 -1
- data/spec/riak/http_backend/transport_methods_spec.rb +129 -0
- data/spec/riak/http_backend_spec.rb +13 -1
- data/spec/riak/map_reduce/filter_builder_spec.rb +45 -0
- data/spec/riak/map_reduce/phase_spec.rb +149 -0
- data/spec/riak/map_reduce_spec.rb +5 -5
- data/spec/riak/net_http_backend_spec.rb +1 -0
- data/spec/riak/{object_spec.rb → robject_spec.rb} +1 -1
- data/spec/riak/stream_parser_spec.rb +66 -0
- data/spec/support/drb_mock_server.rb +2 -2
- data/spec/support/http_backend_implementation_examples.rb +27 -0
- data/spec/support/mock_server.rb +22 -1
- data/spec/support/unified_backend_examples.rb +255 -0
- metadata +43 -54
@@ -54,7 +54,7 @@ module Riak
|
|
54
54
|
# Load object data from an HTTP response
|
55
55
|
# @param [Hash] response a response from {Riak::Client::HTTPBackend}
|
56
56
|
def load_object(robject, response)
|
57
|
-
extract_header(robject, response, "location", :key) {|v| URI.unescape(v.
|
57
|
+
extract_header(robject, response, "location", :key) {|v| URI.unescape(v.match(%r{.*/(.*?)(\?.*)?$})[1]) }
|
58
58
|
extract_header(robject, response, "content-type", :content_type)
|
59
59
|
extract_header(robject, response, "x-riak-vclock", :vclock)
|
60
60
|
extract_header(robject, response, "link", :links) {|v| Set.new(Link.parse(v)) }
|
@@ -138,12 +138,16 @@ module Riak
|
|
138
138
|
{
|
139
139
|
"Accept" => "multipart/mixed, application/json;q=0.7, */*;q=0.5",
|
140
140
|
"X-Riak-ClientId" => @client.client_id
|
141
|
-
}
|
141
|
+
}.merge(basic_auth_header)
|
142
|
+
end
|
143
|
+
|
144
|
+
def basic_auth_header
|
145
|
+
@client.basic_auth ? {"Authorization" => "Basic #{Base64::encode64(@client.basic_auth)}"} : {}
|
142
146
|
end
|
143
147
|
|
144
148
|
# @return [URI] The calculated root URI for the Riak HTTP endpoint
|
145
149
|
def root_uri
|
146
|
-
URI.parse("
|
150
|
+
URI.parse("#{client.protocol}://#{client.host}:#{client.port}")
|
147
151
|
end
|
148
152
|
|
149
153
|
# Calculates an absolute URI from a relative path specification
|
@@ -16,8 +16,6 @@ require 'riak'
|
|
16
16
|
module Riak
|
17
17
|
class Client
|
18
18
|
# Uses the Ruby standard library Net::HTTP to connect to Riak.
|
19
|
-
# We recommend using the CurbBackend, which will
|
20
|
-
# be preferred when the 'curb' library is available.
|
21
19
|
# Conforms to the Riak::Client::HTTPBackend interface.
|
22
20
|
class NetHTTPBackend < HTTPBackend
|
23
21
|
def self.configured?
|
@@ -31,30 +29,45 @@ module Riak
|
|
31
29
|
|
32
30
|
private
|
33
31
|
def perform(method, uri, headers, expect, data=nil) #:nodoc:
|
34
|
-
Net::HTTP.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
32
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
33
|
+
configure_ssl(http) if @client.ssl_enabled?
|
34
|
+
|
35
|
+
request = Net::HTTP.const_get(method.to_s.capitalize).new(uri.request_uri, headers)
|
36
|
+
case data
|
37
|
+
when String
|
38
|
+
request.body = data
|
39
|
+
when IO
|
40
|
+
request.body_stream = data
|
41
|
+
end
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
51
|
-
else
|
52
|
-
raise FailedRequest.new(method, expect, response.code.to_i, response.to_hash, response.body)
|
43
|
+
{}.tap do |result|
|
44
|
+
http.request(request) do |response|
|
45
|
+
if valid_response?(expect, response.code)
|
46
|
+
result.merge!({:headers => response.to_hash, :code => response.code.to_i})
|
47
|
+
response.read_body {|chunk| yield chunk } if block_given?
|
48
|
+
if return_body?(method, response.code, block_given?)
|
49
|
+
result[:body] = response.body
|
53
50
|
end
|
51
|
+
else
|
52
|
+
raise Riak::HTTPFailedRequest.new(method, expect, response.code.to_i, response.to_hash, response.body)
|
54
53
|
end
|
55
54
|
end
|
56
55
|
end
|
57
56
|
end
|
57
|
+
|
58
|
+
def configure_ssl(http)
|
59
|
+
http.use_ssl = true
|
60
|
+
http.verify_mode = OpenSSL::SSL.const_get("VERIFY_#{@client.ssl_options[:verify_mode].upcase}")
|
61
|
+
|
62
|
+
if @client.ssl_options[:pem]
|
63
|
+
http.cert = OpenSSL::X510::Certificate.new(@client.ssl_options[:pem])
|
64
|
+
http.key = OpenSSL::PKey::RSA.new(@client.ssl_options[:pem], @client.ssl_options[:pem_password])
|
65
|
+
end
|
66
|
+
|
67
|
+
http.ca_file = @client.ssl_options[:ca_file] if @client.ssl_options[:ca_file]
|
68
|
+
|
69
|
+
http.ca_path = @client.ssl_options[:ca_path] if @client.ssl_options[:ca_path]
|
70
|
+
end
|
58
71
|
end
|
59
72
|
end
|
60
73
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require 'riak'
|
15
|
+
require 'socket'
|
16
|
+
require 'base64'
|
17
|
+
require 'digest/sha1'
|
18
|
+
|
19
|
+
module Riak
|
20
|
+
class Client
|
21
|
+
class ProtobuffsBackend
|
22
|
+
include Util::Translation
|
23
|
+
|
24
|
+
# Message Codes Enum
|
25
|
+
MESSAGE_CODES = %W[
|
26
|
+
ErrorResp
|
27
|
+
PingReq
|
28
|
+
PingResp
|
29
|
+
GetClientIdReq
|
30
|
+
GetClientIdResp
|
31
|
+
SetClientIdReq
|
32
|
+
SetClientIdResp
|
33
|
+
GetServerInfoReq
|
34
|
+
GetServerInfoResp
|
35
|
+
GetReq
|
36
|
+
GetResp
|
37
|
+
PutReq
|
38
|
+
PutResp
|
39
|
+
DelReq
|
40
|
+
DelResp
|
41
|
+
ListBucketsReq
|
42
|
+
ListBucketsResp
|
43
|
+
ListKeysReq
|
44
|
+
ListKeysResp
|
45
|
+
GetBucketReq
|
46
|
+
GetBucketResp
|
47
|
+
SetBucketReq
|
48
|
+
SetBucketResp
|
49
|
+
MapRedReq
|
50
|
+
MapRedResp
|
51
|
+
].map {|s| s.intern }.freeze
|
52
|
+
|
53
|
+
def self.simple(method, code)
|
54
|
+
define_method method do
|
55
|
+
socket.write([1, MESSAGE_CODES.index(code)].pack('NC'))
|
56
|
+
decode_response
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
attr_accessor :client
|
61
|
+
def initialize(client)
|
62
|
+
@client = client
|
63
|
+
end
|
64
|
+
|
65
|
+
simple :ping, :PingReq
|
66
|
+
simple :get_client_id, :GetClientIdReq
|
67
|
+
simple :server_info, :GetServerInfoReq
|
68
|
+
simple :list_buckets, :ListBucketsReq
|
69
|
+
|
70
|
+
private
|
71
|
+
# Implemented by subclasses
|
72
|
+
def decode_response
|
73
|
+
raise NotImplementedError
|
74
|
+
end
|
75
|
+
|
76
|
+
def socket
|
77
|
+
Thread.current[:riakpbc_socket] ||= TCPSocket.new(@client.host, @client.port)
|
78
|
+
end
|
79
|
+
|
80
|
+
def reset_socket
|
81
|
+
socket.close
|
82
|
+
Thread.current[:riakpbc_socket] = nil
|
83
|
+
end
|
84
|
+
|
85
|
+
UINTMAX = 0xffffffff
|
86
|
+
QUORUMS = {
|
87
|
+
"one" => UINTMAX - 1,
|
88
|
+
"quorum" => UINTMAX - 2,
|
89
|
+
"all" => UINTMAX - 3,
|
90
|
+
"default" => UINTMAX - 4
|
91
|
+
}.freeze
|
92
|
+
|
93
|
+
def normalize_quorum_value(q)
|
94
|
+
QUORUMS[q.to_s] || q.to_i
|
95
|
+
end
|
96
|
+
|
97
|
+
# This doesn't give us exactly the keygen that Riak uses, but close.
|
98
|
+
def generate_key
|
99
|
+
Base64.encode64(Digest::SHA1.digest(Socket.gethostname + Time.now.iso8601(3))).tr("+/","-_").sub(/=+\n$/,'')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require 'riak'
|
15
|
+
begin
|
16
|
+
require 'fiber'
|
17
|
+
rescue LoadError
|
18
|
+
require 'riak/util/fiber1.8'
|
19
|
+
end
|
20
|
+
|
21
|
+
module Riak
|
22
|
+
class Client
|
23
|
+
# @private
|
24
|
+
class Pump
|
25
|
+
def initialize(block)
|
26
|
+
@fiber = Fiber.new do
|
27
|
+
loop do
|
28
|
+
block.call Fiber.yield
|
29
|
+
end
|
30
|
+
end
|
31
|
+
@fiber.resume
|
32
|
+
end
|
33
|
+
|
34
|
+
def pump(input)
|
35
|
+
@fiber.resume input
|
36
|
+
input.size if input.respond_to?(:size) # for curb
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_proc
|
40
|
+
method(:pump).to_proc
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/riak/failed_request.rb
CHANGED
@@ -14,10 +14,19 @@
|
|
14
14
|
require 'riak'
|
15
15
|
|
16
16
|
module Riak
|
17
|
-
# Exception raised when
|
18
|
-
#
|
17
|
+
# Exception raised when receiving an unexpected client response from
|
18
|
+
# Riak.
|
19
19
|
class FailedRequest < StandardError
|
20
20
|
include Util::Translation
|
21
|
+
|
22
|
+
def initialize(message)
|
23
|
+
super(message || t('failed_request'))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Exception raised when the expected HTTP response code from Riak
|
28
|
+
# fails to match the actual response code.
|
29
|
+
class HTTPFailedRequest < FailedRequest
|
21
30
|
# @return [Symbol] the HTTP method, one of :head, :get, :post, :put, :delete
|
22
31
|
attr_reader :method
|
23
32
|
# @return [Fixnum] the expected response code
|
@@ -31,7 +40,53 @@ module Riak
|
|
31
40
|
|
32
41
|
def initialize(method, expected_code, received_code, headers, body)
|
33
42
|
@method, @expected, @code, @headers, @body = method, expected_code, received_code, headers, body
|
34
|
-
super t("
|
43
|
+
super t("http_failed_request", :expected => @expected.inspect, :code => @code, :body => @body)
|
44
|
+
end
|
45
|
+
|
46
|
+
def is_json?
|
47
|
+
headers['content-type'].include?('application/json')
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [true,false] whether the error represents a "not found" response
|
51
|
+
def not_found?
|
52
|
+
@code.to_i == 404
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [true,false] whether the error represents an internal
|
56
|
+
# server error
|
57
|
+
def server_error?
|
58
|
+
@code.to_i == 500
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Exception raised when receiving an unexpected Protocol Buffers response from Riak
|
63
|
+
class ProtobuffsFailedRequest < FailedRequest
|
64
|
+
def initialize(code, message)
|
65
|
+
super t('protobuffs_failed_request', :code => code, :body => message)
|
66
|
+
@original_message = message
|
67
|
+
@not_found = code == :not_found
|
68
|
+
@server_error = code == :server_error
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [true, false] whether the error response is in JSON
|
72
|
+
def is_json?
|
73
|
+
begin
|
74
|
+
JSON.parse(original_message)
|
75
|
+
true
|
76
|
+
rescue
|
77
|
+
false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [true,false] whether the error represents a "not found" response
|
82
|
+
def not_found?
|
83
|
+
@not_found
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [true,false] whether the error represents an internal
|
87
|
+
# server error
|
88
|
+
def server_error?
|
89
|
+
@server_error
|
35
90
|
end
|
36
91
|
end
|
37
92
|
end
|
data/lib/riak/locale/en.yml
CHANGED
@@ -17,24 +17,32 @@ en:
|
|
17
17
|
client_type: "invalid argument %{client} is not a Riak::Client"
|
18
18
|
content_type_undefined: "content_type is not defined!"
|
19
19
|
empty_map_reduce_query: "Specify one or more query phases to your MapReduce."
|
20
|
-
failed_request: "
|
20
|
+
failed_request: "Client request failed."
|
21
21
|
filter_needs_block: "Filter %{filter} expects a block."
|
22
22
|
filter_arity_mismatch: "Filter %{filter} expects %{expected} arguments but %{received} were given."
|
23
23
|
hash_type: "invalid argument %{hash} is not a Hash"
|
24
24
|
http_configuration: "The %{backend} HTTP backend cannot be used. Please check its requirements."
|
25
|
+
http_failed_request: "Expected %{expected} from Riak but received %{code}. %{body}"
|
25
26
|
hostname_invalid: "host must be a valid hostname"
|
27
|
+
protocol_invalid: "'%{invalid}' is not a valid protocol, valid values are %{valid}"
|
28
|
+
invalid_basic_auth: "basic auth must be set using 'user:pass'"
|
26
29
|
invalid_client_id: "Invalid client ID, must be a string or between 0 and %{max_id}"
|
27
30
|
invalid_function_value: "invalid value for function: %{value}"
|
28
31
|
invalid_phase_type: "type must be :map, :reduce, or :link"
|
29
|
-
|
32
|
+
invalid_options: "Invalid configuration options given."
|
33
|
+
loading_bucket: "while loading bucket '%{name}'"
|
34
|
+
missing_block: "A block must be given."
|
30
35
|
missing_host_and_port: "You must specify a host and port, or use the defaults of 127.0.0.1:8098"
|
31
36
|
module_function_pair_required: "function must have two elements when an array"
|
37
|
+
not_found: "The requested object was not found."
|
32
38
|
path_and_body_required: "You must supply both a resource path and a body."
|
33
39
|
port_invalid: "port must be an integer between 0 and 65535"
|
34
|
-
|
40
|
+
protobuffs_failed_request: "Expected success from Riak but received %{code}. %{body}"
|
41
|
+
request_body_type: "Request body must be a String or IO."
|
35
42
|
resource_path_short: "Resource path too short"
|
36
43
|
search_docs_require_id: "Search index documents must include the 'id' field."
|
37
44
|
search_remove_requires_id_or_query: "Search index documents to be removed must have 'id' or 'query' keys."
|
45
|
+
stale_write_prevented: "Stale write prevented by client."
|
38
46
|
stored_function_invalid: "function must have :bucket and :key when a hash"
|
39
47
|
string_type: "invalid_argument %{string} is not a String"
|
40
48
|
too_few_arguments: "too few arguments: %{params}"
|
data/lib/riak/map_reduce.rb
CHANGED
@@ -83,7 +83,7 @@ module Riak
|
|
83
83
|
bucket = params.shift
|
84
84
|
bucket = bucket.name if Bucket === bucket
|
85
85
|
if Array === params.first
|
86
|
-
@inputs = {:bucket => escape(bucket), :
|
86
|
+
@inputs = {:bucket => escape(bucket), :key_filters => params.first }
|
87
87
|
else
|
88
88
|
key = params.shift
|
89
89
|
@inputs << params.unshift(escape(key)).unshift(escape(bucket))
|
@@ -171,15 +171,24 @@ module Riak
|
|
171
171
|
end
|
172
172
|
|
173
173
|
# Executes this map-reduce job.
|
174
|
-
# @
|
175
|
-
#
|
176
|
-
#
|
177
|
-
#
|
174
|
+
# @overload run
|
175
|
+
# Return the entire collection of results.
|
176
|
+
# @return [Array<Array>] similar to link-walking, each element is
|
177
|
+
# an array of results from a phase where "keep" is true. If there
|
178
|
+
# is only one "keep" phase, only the results from that phase will
|
179
|
+
# be returned.
|
180
|
+
# @overload run
|
181
|
+
# Stream the results through the given block without accumulating.
|
182
|
+
# @yield [phase, data] A block to stream results through
|
183
|
+
# @yieldparam [Fixnum] phase the phase from which the results were
|
184
|
+
# generated
|
185
|
+
# @yieldparam [Array] data a list of results from the phase
|
186
|
+
# @return [nil] nothing
|
178
187
|
def run(&block)
|
179
188
|
raise MapReduceError.new(t("empty_map_reduce_query")) if @query.empty?
|
180
189
|
@client.backend.mapred(self, &block)
|
181
190
|
rescue FailedRequest => fr
|
182
|
-
if fr.
|
191
|
+
if fr.server_error? && fr.is_json?
|
183
192
|
raise MapReduceError.new(fr.body)
|
184
193
|
else
|
185
194
|
raise fr
|
@@ -44,7 +44,7 @@ module Riak
|
|
44
44
|
:matches => 1,
|
45
45
|
:neq => 1,
|
46
46
|
:eq => 1,
|
47
|
-
:set_member => 1,
|
47
|
+
:set_member => -1,
|
48
48
|
:similar_to => 2,
|
49
49
|
:starts_with => 1,
|
50
50
|
:ends_with => 1
|
@@ -58,8 +58,8 @@ module Riak
|
|
58
58
|
# FilterBuilder.new do
|
59
59
|
# string_to_int
|
60
60
|
# AND do
|
61
|
-
# greater_than_eq 50
|
62
|
-
# neq 100
|
61
|
+
# seq { greater_than_eq 50 }
|
62
|
+
# seq { neq 100 }
|
63
63
|
# end
|
64
64
|
# end
|
65
65
|
LOGICAL_OPERATIONS = %w{and or not}
|
@@ -67,7 +67,7 @@ module Riak
|
|
67
67
|
FILTERS.each do |f,arity|
|
68
68
|
class_eval <<-CODE
|
69
69
|
def #{f}(*args)
|
70
|
-
raise ArgumentError.new(t("filter_arity_mismatch", :filter => :#{f}, :expected => #{arity.inspect}, :received => args.size)) unless Array(#{arity.inspect}).include?(args.size)
|
70
|
+
raise ArgumentError.new(t("filter_arity_mismatch", :filter => :#{f}, :expected => #{arity.inspect}, :received => args.size)) unless #{arity.inspect} == -1 || Array(#{arity.inspect}).include?(args.size)
|
71
71
|
@filters << ([:#{f}] + args)
|
72
72
|
end
|
73
73
|
CODE
|
data/lib/riak/test_server.rb
CHANGED
@@ -33,7 +33,10 @@ module Riak
|
|
33
33
|
:js_vm_count => 8,
|
34
34
|
:js_max_vm_mem => 8,
|
35
35
|
:js_thread_stack => 16,
|
36
|
-
:riak_kv_stat => true
|
36
|
+
:riak_kv_stat => true,
|
37
|
+
# Turn off map caching
|
38
|
+
:map_cache_size => 0, # 0.14
|
39
|
+
:vnode_cache_entries => 0 # 0.13
|
37
40
|
},
|
38
41
|
:luwak => {
|
39
42
|
:enabled => false
|
@@ -65,6 +68,7 @@ module Riak
|
|
65
68
|
@vm_args = options[:vm_args]
|
66
69
|
# For synchronizing start/stop/recycle
|
67
70
|
@mutex = Mutex.new
|
71
|
+
cleanup # Should prevent some errors related to unclean startup
|
68
72
|
end
|
69
73
|
|
70
74
|
# Sets up the proper scripts, configuration and directories for
|