aerospike 2.6.0 → 2.7.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.
- 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
|