aerospike 2.6.0 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +3 -1
- data/lib/aerospike.rb +9 -5
- data/lib/aerospike/client.rb +101 -83
- data/lib/aerospike/cluster.rb +11 -50
- data/lib/aerospike/cluster/create_connection.rb +1 -1
- data/lib/aerospike/cluster/find_nodes_to_remove.rb +66 -0
- data/lib/aerospike/cluster/partition.rb +5 -2
- data/lib/aerospike/command/batch_direct_command.rb +104 -0
- data/lib/aerospike/command/batch_direct_exists_command.rb +51 -0
- data/lib/aerospike/command/batch_direct_node.rb +40 -0
- data/lib/aerospike/command/batch_index_command.rb +119 -0
- data/lib/aerospike/command/batch_index_exists_command.rb +45 -0
- data/lib/aerospike/command/batch_index_node.rb +52 -0
- data/lib/aerospike/command/batch_item.rb +18 -47
- data/lib/aerospike/command/command.rb +6 -65
- data/lib/aerospike/command/field_type.rb +13 -10
- data/lib/aerospike/command/{batch_command.rb → multi_command.rb} +29 -9
- data/lib/aerospike/command/read_command.rb +4 -2
- data/lib/aerospike/command/single_command.rb +6 -9
- data/lib/aerospike/connection/create.rb +3 -3
- data/lib/aerospike/host/parse.rb +28 -2
- data/lib/aerospike/node.rb +6 -2
- data/lib/aerospike/node/refresh/friends.rb +1 -1
- data/lib/aerospike/node/refresh/peers.rb +1 -1
- data/lib/aerospike/node_validator.rb +3 -3
- data/lib/aerospike/peers.rb +4 -0
- data/lib/aerospike/peers/parse.rb +26 -6
- data/lib/aerospike/policy/batch_policy.rb +25 -15
- data/lib/aerospike/policy/client_policy.rb +2 -2
- data/lib/aerospike/policy/query_policy.rb +25 -12
- data/lib/aerospike/policy/scan_policy.rb +39 -16
- data/lib/aerospike/query/stream_command.rb +6 -5
- data/lib/aerospike/record.rb +4 -3
- data/lib/aerospike/socket/ssl.rb +13 -13
- data/lib/aerospike/socket/tcp.rb +8 -1
- data/lib/aerospike/utils/string_parser.rb +7 -3
- data/lib/aerospike/version.rb +1 -1
- metadata +11 -7
- data/lib/aerospike/command/batch_command_exists.rb +0 -93
- data/lib/aerospike/command/batch_command_get.rb +0 -84
- data/lib/aerospike/command/batch_node.rb +0 -82
@@ -21,10 +21,10 @@ module Aerospike
|
|
21
21
|
module Connection # :nodoc:
|
22
22
|
module Create
|
23
23
|
class << self
|
24
|
-
def call(host, port, timeout: 30, tls_name: nil,
|
25
|
-
if !
|
24
|
+
def call(host, port, timeout: 30, tls_name: nil, tls_options: nil)
|
25
|
+
if !tls_options.nil? && tls_options[:enable] != false
|
26
26
|
::Aerospike::Socket::SSL.connect(
|
27
|
-
host, port, timeout, tls_name,
|
27
|
+
host, port, timeout, tls_name, tls_options
|
28
28
|
)
|
29
29
|
else
|
30
30
|
::Aerospike::Socket::TCP.connect(host, port, timeout)
|
data/lib/aerospike/host/parse.rb
CHANGED
@@ -23,7 +23,14 @@ module Aerospike
|
|
23
23
|
INTEGER_REGEX = /\A\d+\z/
|
24
24
|
|
25
25
|
class << self
|
26
|
-
|
26
|
+
##
|
27
|
+
# Parse hosts from string format: hostname1[:tlsname1][:port1],...
|
28
|
+
#
|
29
|
+
# Hostname may also be an IP address in the following formats:
|
30
|
+
# - xxx.xxx.xxx.xxx
|
31
|
+
# - [xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]
|
32
|
+
# - [xxxx::xxxx]
|
33
|
+
#
|
27
34
|
def call(hosts, default_port = 3000)
|
28
35
|
case hosts
|
29
36
|
when Host
|
@@ -32,7 +39,7 @@ module Aerospike
|
|
32
39
|
hosts
|
33
40
|
when String
|
34
41
|
hosts.split(?,).map { |host|
|
35
|
-
addr, tls_name, port = host
|
42
|
+
addr, tls_name, port = components(host)
|
36
43
|
if port.nil? && tls_name && tls_name.match(INTEGER_REGEX)
|
37
44
|
port = tls_name
|
38
45
|
tls_name = nil
|
@@ -44,6 +51,25 @@ module Aerospike
|
|
44
51
|
fail TypeError, "hosts should be a Host object, an Array of Host objects, or a String"
|
45
52
|
end
|
46
53
|
end
|
54
|
+
|
55
|
+
# Extract addr, tls_name and port components from a host strin
|
56
|
+
def components(host_string)
|
57
|
+
host_string = host_string.strip
|
58
|
+
|
59
|
+
# IPv6
|
60
|
+
if host_string.start_with?('[')
|
61
|
+
end_idx = host_string.index(']')
|
62
|
+
raise ::Aerospike::Exceptions::Parse, 'Invalid IPv6 host' if end_idx.nil?
|
63
|
+
|
64
|
+
# Slice away brackets and what's inside them, then split on : and
|
65
|
+
# replace first entry with string inside brackets
|
66
|
+
host_string.slice(end_idx+1..-1).split(':').tap do |result|
|
67
|
+
result[0] = host_string[1...end_idx]
|
68
|
+
end
|
69
|
+
else
|
70
|
+
host_string.split(?:)
|
71
|
+
end
|
72
|
+
end
|
47
73
|
end
|
48
74
|
end
|
49
75
|
end
|
data/lib/aerospike/node.rb
CHANGED
@@ -139,6 +139,10 @@ module Aerospike
|
|
139
139
|
@reference_count.value = 0
|
140
140
|
end
|
141
141
|
|
142
|
+
def referenced?
|
143
|
+
@reference_count.value > 0
|
144
|
+
end
|
145
|
+
|
142
146
|
def responded!
|
143
147
|
@responded.value = true
|
144
148
|
end
|
@@ -155,8 +159,8 @@ module Aerospike
|
|
155
159
|
@peers_count.value > 0
|
156
160
|
end
|
157
161
|
|
158
|
-
def failed?
|
159
|
-
@failures.value
|
162
|
+
def failed?(threshold = 1)
|
163
|
+
@failures.value >= threshold
|
160
164
|
end
|
161
165
|
|
162
166
|
def failed!
|
@@ -41,7 +41,7 @@ module Aerospike
|
|
41
41
|
|
42
42
|
peer.hosts.each do |host|
|
43
43
|
begin
|
44
|
-
nv = NodeValidator.new(cluster, host, cluster.connection_timeout, cluster.cluster_name, cluster.
|
44
|
+
nv = NodeValidator.new(cluster, host, cluster.connection_timeout, cluster.cluster_name, cluster.tls_options)
|
45
45
|
|
46
46
|
if nv.name != peer.node_name
|
47
47
|
::Aerospike.logger.warn("Peer node #{peer.node_name} is different than actual node #{nv.name} for host #{host}");
|
@@ -21,15 +21,15 @@ module Aerospike
|
|
21
21
|
class NodeValidator # :nodoc:
|
22
22
|
VERSION_REGEXP = /(?<v1>\d+)\.(?<v2>\d+)\.(?<v3>\d+).*/.freeze
|
23
23
|
|
24
|
-
attr_reader :host, :aliases, :name, :use_new_info, :features, :cluster_name, :
|
24
|
+
attr_reader :host, :aliases, :name, :use_new_info, :features, :cluster_name, :tls_options, :conn
|
25
25
|
|
26
|
-
def initialize(cluster, host, timeout, cluster_name,
|
26
|
+
def initialize(cluster, host, timeout, cluster_name, tls_options = {})
|
27
27
|
@cluster = cluster
|
28
28
|
@use_new_info = true
|
29
29
|
@features = Set.new
|
30
30
|
@host = host
|
31
31
|
@cluster_name = cluster_name
|
32
|
-
@
|
32
|
+
@tls_options = tls_options
|
33
33
|
|
34
34
|
set_aliases(host)
|
35
35
|
set_address(timeout)
|
data/lib/aerospike/peers.rb
CHANGED
@@ -72,15 +72,35 @@ module Aerospike
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def parse_hosts(parser, peer)
|
75
|
+
result = []
|
75
76
|
parser.expect('[')
|
76
|
-
return
|
77
|
+
return result if parser.current == ']'
|
77
78
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
hostname, port = host.split(':')
|
82
|
-
::Aerospike::Host.new(hostname, port, peer.tls_name)
|
79
|
+
loop do
|
80
|
+
result << parse_host(parser, peer)
|
81
|
+
break if parser.current == ']'
|
83
82
|
end
|
83
|
+
|
84
|
+
result
|
85
|
+
end
|
86
|
+
|
87
|
+
def parse_host(parser, peer)
|
88
|
+
if parser.current == '[' # IPv6
|
89
|
+
parser.step
|
90
|
+
host = parser.read_until(']')
|
91
|
+
# skip one extra if port is detected, to match read behavior below
|
92
|
+
parser.step if parser.current == ':'
|
93
|
+
else
|
94
|
+
host = parser.read_until(',', ':', ']')
|
95
|
+
end
|
96
|
+
|
97
|
+
port = parser.prev == ':' ? parser.read_until(',', ']').to_i : nil
|
98
|
+
|
99
|
+
if parser.prev == ',' || parser.prev == ']'
|
100
|
+
return ::Aerospike::Host.new(host, port, peer.tls_name)
|
101
|
+
end
|
102
|
+
|
103
|
+
raise ::Aerospike::Exceptions::Parse, "Unterminated host in response"
|
84
104
|
end
|
85
105
|
end
|
86
106
|
end
|
@@ -1,17 +1,19 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Aerospike, Inc.
|
1
|
+
# Copyright 2014-2018 Aerospike, Inc.
|
3
2
|
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# You may obtain a copy of the License at
|
3
|
+
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
4
|
+
# license agreements.
|
7
5
|
#
|
8
|
-
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
7
|
+
# use this file except in compliance with the License. You may obtain a copy of
|
8
|
+
# the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
11
|
#
|
10
12
|
# Unless required by applicable law or agreed to in writing, software
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
14
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
15
|
+
# License for the specific language governing permissions and limitations under
|
16
|
+
# the License.
|
15
17
|
|
16
18
|
require 'aerospike/policy/policy'
|
17
19
|
|
@@ -20,15 +22,23 @@ module Aerospike
|
|
20
22
|
# Container object for batch policy command.
|
21
23
|
class BatchPolicy < Policy
|
22
24
|
|
23
|
-
attr_accessor :
|
24
|
-
:wait_until_migrations_are_over
|
25
|
+
attr_accessor :use_batch_direct
|
25
26
|
|
26
27
|
def initialize(opt={})
|
27
28
|
super(opt)
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
# Use old batch direct protocol where batch reads are handled by direct
|
31
|
+
# low-level batch server database routines. The batch direct protocol can
|
32
|
+
# be faster when there is a single namespace. But there is one important
|
33
|
+
# drawback: The batch direct protocol will not proxy to a different
|
34
|
+
# server node when the mapped node has migrated a record to another node
|
35
|
+
# (resulting in not found record). This can happen after a node has been
|
36
|
+
# added/removed from the cluster and there is a lag between records being
|
37
|
+
# migrated and client partition map update (once per second). The batch
|
38
|
+
# index protocol will perform this record proxy when necessary.
|
39
|
+
#
|
40
|
+
# Default: false (use new batch index protocol if server supports it)
|
41
|
+
@use_batch_direct = opt.fetch(:use_batch_direct) { false }
|
32
42
|
|
33
43
|
self
|
34
44
|
end
|
@@ -25,7 +25,7 @@ module Aerospike
|
|
25
25
|
attr_accessor :user, :password
|
26
26
|
attr_accessor :timeout, :connection_queue_size, :fail_if_not_connected, :tend_interval
|
27
27
|
attr_accessor :cluster_name
|
28
|
-
attr_accessor :
|
28
|
+
attr_accessor :tls
|
29
29
|
|
30
30
|
def initialize(opt={})
|
31
31
|
# Initial host connection timeout in seconds. The timeout when opening a connection
|
@@ -51,7 +51,7 @@ module Aerospike
|
|
51
51
|
# Cluster Name
|
52
52
|
@cluster_name = opt[:cluster_name]
|
53
53
|
|
54
|
-
@
|
54
|
+
@tls = opt[:tls] || opt[:ssl_options]
|
55
55
|
end
|
56
56
|
|
57
57
|
def requires_authentication
|
@@ -1,34 +1,47 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Aerospike, Inc.
|
1
|
+
# Copyright 2014-2018 Aerospike, Inc.
|
3
2
|
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# You may obtain a copy of the License at
|
3
|
+
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
4
|
+
# license agreements.
|
7
5
|
#
|
8
|
-
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
7
|
+
# use this file except in compliance with the License. You may obtain a copy of
|
8
|
+
# the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
11
|
#
|
10
12
|
# Unless required by applicable law or agreed to in writing, software
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
14
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
15
|
+
# License for the specific language governing permissions and limitations under
|
16
|
+
# the License.
|
15
17
|
|
16
|
-
require 'aerospike/policy/
|
18
|
+
require 'aerospike/policy/policy'
|
17
19
|
|
18
20
|
module Aerospike
|
19
21
|
|
20
22
|
# Container object for query policy command.
|
21
|
-
class QueryPolicy <
|
23
|
+
class QueryPolicy < Policy
|
22
24
|
|
23
25
|
attr_accessor :include_bin_data
|
26
|
+
attr_accessor :record_queue_size
|
24
27
|
|
25
28
|
def initialize(opt={})
|
26
29
|
super(opt)
|
27
30
|
|
28
31
|
@max_retries = 0
|
29
32
|
|
33
|
+
# Indicates if bin data is retrieved. If false, only record digests (and
|
34
|
+
# user keys if stored on the server) are retrieved.
|
35
|
+
# Default is true.
|
30
36
|
@include_bin_data = opt.fetch(:include_bin_data, true)
|
31
37
|
|
38
|
+
# Number of records to place in queue before blocking. Records received
|
39
|
+
# from multiple server nodes will be placed in a queue. A separate thread
|
40
|
+
# consumes these records in parallel. If the queue is full, the producer
|
41
|
+
# threads will block until records are consumed.
|
42
|
+
# Default is 5000.
|
43
|
+
@record_queue_size = opt[:record_queue_size] || 5000
|
44
|
+
|
32
45
|
self
|
33
46
|
end
|
34
47
|
|
@@ -1,40 +1,63 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Aerospike, Inc.
|
1
|
+
# Copyright 2014-2018 Aerospike, Inc.
|
3
2
|
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# You may obtain a copy of the License at
|
3
|
+
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
4
|
+
# license agreements.
|
7
5
|
#
|
8
|
-
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
7
|
+
# use this file except in compliance with the License. You may obtain a copy of
|
8
|
+
# the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
11
|
#
|
10
12
|
# Unless required by applicable law or agreed to in writing, software
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
14
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
15
|
+
# License for the specific language governing permissions and limitations under
|
16
|
+
# the License.
|
15
17
|
|
16
|
-
require 'aerospike/policy/
|
18
|
+
require 'aerospike/policy/policy'
|
17
19
|
|
18
20
|
module Aerospike
|
19
21
|
|
20
22
|
# Container object for scan policy command.
|
21
|
-
class ScanPolicy <
|
23
|
+
class ScanPolicy < Policy
|
22
24
|
|
23
25
|
attr_accessor :scan_percent
|
24
26
|
attr_accessor :concurrent_nodes
|
25
27
|
attr_accessor :include_bin_data
|
26
28
|
attr_accessor :fail_on_cluster_change
|
27
29
|
attr_accessor :socket_timeout
|
30
|
+
attr_accessor :record_queue_size
|
28
31
|
|
29
32
|
def initialize(opt={})
|
30
33
|
super(opt)
|
31
34
|
|
35
|
+
@max_retries = 0
|
36
|
+
|
37
|
+
# Percent of data to scan. Valid integer range is 1 to 100.
|
38
|
+
# Default is 100.
|
32
39
|
@scan_percent = opt[:scan_percent] || 100
|
33
|
-
|
34
|
-
|
35
|
-
@
|
40
|
+
|
41
|
+
# Issue scan requests in parallel or serially.
|
42
|
+
@concurrent_nodes = opt.fetch(:concurrent_nodes) { true }
|
43
|
+
|
44
|
+
# Indicates if bin data is retrieved. If false, only record digests (and
|
45
|
+
# user keys if stored on the server) are retrieved.
|
46
|
+
# Default is true.
|
47
|
+
@include_bin_data = opt.fetch(:include_bin_data) { true }
|
48
|
+
|
49
|
+
# Terminate scan if cluster in fluctuating state.
|
50
|
+
# Default is true.
|
51
|
+
@fail_on_cluster_change = opt.fetch(:fail_on_cluster_change) { true }
|
52
|
+
|
36
53
|
@socket_timeout = opt[:socket_timeout] || 10000
|
37
|
-
|
54
|
+
|
55
|
+
# Number of records to place in queue before blocking. Records received
|
56
|
+
# from multiple server nodes will be placed in a queue. A separate thread
|
57
|
+
# consumes these records in parallel. If the queue is full, the producer
|
58
|
+
# threads will block until records are consumed.
|
59
|
+
# Default is 5000.
|
60
|
+
@record_queue_size = opt[:record_queue_size] || 5000
|
38
61
|
|
39
62
|
self
|
40
63
|
end
|
@@ -1,12 +1,13 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Aerospike, Inc.
|
1
|
+
# Copyright 2014-2018 Aerospike, Inc.
|
3
2
|
#
|
4
3
|
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
5
4
|
# license agreements.
|
6
5
|
#
|
7
6
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
8
7
|
# use this file except in compliance with the License. You may obtain a copy of
|
9
|
-
# the License at
|
8
|
+
# the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
11
|
#
|
11
12
|
# Unless required by applicable law or agreed to in writing, software
|
12
13
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
@@ -24,9 +25,9 @@ module Aerospike
|
|
24
25
|
|
25
26
|
private
|
26
27
|
|
27
|
-
class StreamCommand <
|
28
|
+
class StreamCommand < MultiCommand #:nodoc:
|
28
29
|
|
29
|
-
def
|
30
|
+
def parse_group(receive_size)
|
30
31
|
@data_offset = 0
|
31
32
|
|
32
33
|
while @data_offset < receive_size
|
data/lib/aerospike/record.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Aerospike, Inc.
|
1
|
+
# Copyright 2014-2018 Aerospike, Inc.
|
3
2
|
#
|
4
3
|
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
5
4
|
# license agreements.
|
6
5
|
#
|
7
6
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
8
7
|
# use this file except in compliance with the License. You may obtain a copy of
|
9
|
-
# the License at
|
8
|
+
# the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
11
|
#
|
11
12
|
# Unless required by applicable law or agreed to in writing, software
|
12
13
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|