aerospike 2.21.1 → 2.23.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 +16 -1
- data/lib/aerospike/atomic/atomic.rb +1 -1
- data/lib/aerospike/cdt/context.rb +7 -7
- data/lib/aerospike/cdt/list_return_type.rb +4 -0
- data/lib/aerospike/cdt/map_operation.rb +6 -6
- data/lib/aerospike/cdt/map_return_type.rb +4 -0
- data/lib/aerospike/client.rb +34 -59
- data/lib/aerospike/cluster.rb +6 -3
- data/lib/aerospike/command/admin_command.rb +2 -2
- data/lib/aerospike/command/batch_index_node.rb +1 -1
- data/lib/aerospike/command/batch_item.rb +1 -1
- data/lib/aerospike/command/command.rb +62 -30
- data/lib/aerospike/command/field_type.rb +3 -0
- data/lib/aerospike/command/login_command.rb +7 -5
- data/lib/aerospike/command/multi_command.rb +8 -2
- data/lib/aerospike/command/read_command.rb +2 -2
- data/lib/aerospike/connection/authenticate.rb +4 -4
- data/lib/aerospike/features.rb +9 -9
- data/lib/aerospike/host/parse.rb +2 -2
- data/lib/aerospike/key.rb +10 -1
- data/lib/aerospike/node/refresh/info.rb +1 -1
- data/lib/aerospike/node/verify/name.rb +1 -1
- data/lib/aerospike/node/verify/partition_generation.rb +1 -1
- data/lib/aerospike/node/verify/peers_generation.rb +1 -1
- data/lib/aerospike/node/verify/rebalance_generation.rb +1 -1
- data/lib/aerospike/node_validator.rb +6 -1
- data/lib/aerospike/policy/policy.rb +4 -1
- data/lib/aerospike/policy/scan_policy.rb +20 -1
- data/lib/aerospike/privilege.rb +1 -1
- data/lib/aerospike/query/node_partitions.rb +39 -0
- data/lib/aerospike/query/partition_filter.rb +66 -0
- data/lib/aerospike/query/partition_status.rb +36 -0
- data/lib/aerospike/query/partition_tracker.rb +347 -0
- data/lib/aerospike/query/scan_command.rb +3 -3
- data/lib/aerospike/query/scan_executor.rb +69 -0
- data/lib/aerospike/query/scan_partition_command.rb +49 -0
- data/lib/aerospike/query/statement.rb +1 -1
- data/lib/aerospike/query/stream_command.rb +14 -1
- data/lib/aerospike/result_code.rb +79 -4
- data/lib/aerospike/role.rb +2 -2
- data/lib/aerospike/task/execute_task.rb +2 -2
- data/lib/aerospike/task/index_task.rb +1 -1
- data/lib/aerospike/user_role.rb +1 -1
- data/lib/aerospike/utils/buffer.rb +12 -0
- data/lib/aerospike/utils/pool.rb +1 -1
- data/lib/aerospike/value/value.rb +6 -6
- data/lib/aerospike/version.rb +1 -1
- data/lib/aerospike.rb +6 -0
- metadata +11 -5
@@ -98,7 +98,7 @@ module Aerospike
|
|
98
98
|
receive_size = (sz & 0xFFFFFFFFFFFF) - header_length
|
99
99
|
|
100
100
|
# Read remaining message bytes.
|
101
|
-
if compressed_sz
|
101
|
+
if compressed_sz
|
102
102
|
@data_buffer.eat!(MSG_TOTAL_HEADER_SIZE)
|
103
103
|
elsif receive_size > 0
|
104
104
|
size_buffer_sz(receive_size)
|
@@ -117,7 +117,7 @@ module Aerospike
|
|
117
117
|
@record = Record.new(@node, @key, nil, generation, expiration)
|
118
118
|
return
|
119
119
|
end
|
120
|
-
|
120
|
+
|
121
121
|
@record = parse_record(op_count, field_count, generation, expiration)
|
122
122
|
return
|
123
123
|
end
|
@@ -38,9 +38,7 @@ module Aerospike
|
|
38
38
|
|
39
39
|
def call(conn, cluster)
|
40
40
|
command = LoginCommand.new
|
41
|
-
if
|
42
|
-
command.authenticate_new(conn, cluster)
|
43
|
-
else
|
41
|
+
if cluster.session_valid?
|
44
42
|
begin
|
45
43
|
command.authenticate_via_token(conn, cluster)
|
46
44
|
rescue => ae
|
@@ -49,11 +47,13 @@ module Aerospike
|
|
49
47
|
if ae.is_a?(Exceptions::Aerospike)
|
50
48
|
if INVALID_SESSION_ERR.include?(ae.result_code)
|
51
49
|
command.authenticate_new(conn, cluster)
|
52
|
-
return
|
50
|
+
return true
|
53
51
|
end
|
54
52
|
end
|
55
53
|
raise ae
|
56
54
|
end
|
55
|
+
else
|
56
|
+
command.authenticate_new(conn, cluster)
|
57
57
|
end
|
58
58
|
|
59
59
|
true
|
data/lib/aerospike/features.rb
CHANGED
@@ -23,10 +23,10 @@ module Aerospike
|
|
23
23
|
module Features
|
24
24
|
|
25
25
|
# Server supports List Complex Data Type (CDT)
|
26
|
-
CDT_LIST = :
|
26
|
+
CDT_LIST = :'cdt-list'
|
27
27
|
|
28
28
|
# Server supports Map Complex Data Type (CDT)
|
29
|
-
CDT_MAP = :
|
29
|
+
CDT_MAP = :'cdt-map'
|
30
30
|
|
31
31
|
# Server supports Float data type
|
32
32
|
FLOAT = :float
|
@@ -34,16 +34,16 @@ module Aerospike
|
|
34
34
|
# Server supports geo-spatial data type and indexing
|
35
35
|
GEO = :geo
|
36
36
|
|
37
|
-
# Server requires
|
38
|
-
LUT_NOW = :
|
37
|
+
# Server requires 'lut=now' in truncate command (AER-5955)
|
38
|
+
LUT_NOW = :'lut-now'
|
39
39
|
|
40
|
-
# Server supports the new
|
40
|
+
# Server supports the new 'peers' protocol for automatic node discovery
|
41
41
|
PEERS = :peers
|
42
42
|
|
43
|
-
# Server supports the
|
44
|
-
TRUNCATE_NAMESPACE = :
|
43
|
+
# Server supports the 'truncate-namespace' command
|
44
|
+
TRUNCATE_NAMESPACE = :'truncate-namespace'
|
45
45
|
|
46
|
-
# Server supports the
|
47
|
-
BLOB_BITS = :
|
46
|
+
# Server supports the 'blob-bits' command
|
47
|
+
BLOB_BITS = :'blob-bits'
|
48
48
|
end
|
49
49
|
end
|
data/lib/aerospike/host/parse.rb
CHANGED
data/lib/aerospike/key.rb
CHANGED
@@ -53,15 +53,20 @@ module Aerospike
|
|
53
53
|
|
54
54
|
attr_reader :namespace, :set_name, :digest
|
55
55
|
|
56
|
-
def initialize(ns, set, val, digest=nil, v1_compatible: self.class.v1_compatible?)
|
56
|
+
def initialize(ns, set, val, digest=nil, bval: nil, v1_compatible: self.class.v1_compatible?)
|
57
57
|
@namespace = ns
|
58
58
|
@set_name = set
|
59
59
|
@user_key = Value.of(val)
|
60
60
|
check_key!(@namespace, @set_name, @user_key, !digest.nil?)
|
61
61
|
@digest = digest || compute_digest(v1_compatible)
|
62
|
+
@bval = bval
|
62
63
|
end
|
63
64
|
|
64
65
|
|
66
|
+
def bval
|
67
|
+
@bval
|
68
|
+
end
|
69
|
+
|
65
70
|
def to_s
|
66
71
|
"#{@namespace}:#{@set_name}:#{@user_key}:#{@digest.nil? ? '' : @digest.bytes}"
|
67
72
|
end
|
@@ -85,6 +90,10 @@ module Aerospike
|
|
85
90
|
@digest.hash
|
86
91
|
end
|
87
92
|
|
93
|
+
def partition_id
|
94
|
+
(@digest[0..3].unpack(Partition::UNPACK_FORMAT)[0] & 0xFFFF) % Node::PARTITIONS
|
95
|
+
end
|
96
|
+
|
88
97
|
private
|
89
98
|
|
90
99
|
def valid_key?(value, has_digest)
|
@@ -30,7 +30,7 @@ module Aerospike
|
|
30
30
|
def call(node, peers)
|
31
31
|
conn = node.tend_connection
|
32
32
|
if peers.use_peers?
|
33
|
-
cmds = node.cluster.rack_aware ? CMDS_REBALANCE : CMDS_PEERS
|
33
|
+
cmds = node.cluster.rack_aware ? CMDS_REBALANCE : CMDS_PEERS
|
34
34
|
info_map = ::Aerospike::Info.request(conn, *cmds)
|
35
35
|
Verify::PeersGeneration.(node, info_map, peers)
|
36
36
|
Verify::PartitionGeneration.(node, info_map)
|
@@ -40,6 +40,7 @@ module Aerospike
|
|
40
40
|
|
41
41
|
def get_hosts(address)
|
42
42
|
aliases = [get_alias(address, host.port)]
|
43
|
+
res = []
|
43
44
|
|
44
45
|
begin
|
45
46
|
conn = Cluster::CreateConnection.(@cluster, Host.new(address, host.port, host.tls_name))
|
@@ -61,11 +62,15 @@ module Aerospike
|
|
61
62
|
unless is_loopback?(address)
|
62
63
|
aliases = info_map[address_command].split(',').map { |addr| get_alias(*addr.split(':')) }
|
63
64
|
end
|
65
|
+
|
66
|
+
res = aliases.map { |al| Host.new(al[:address], al[:port], host.tls_name) }
|
67
|
+
rescue
|
68
|
+
# we don't care about the actual connection error; Just need to continue
|
64
69
|
ensure
|
65
70
|
conn.close if conn
|
66
71
|
end
|
67
72
|
|
68
|
-
|
73
|
+
res
|
69
74
|
end
|
70
75
|
|
71
76
|
def get_alias(address, port)
|
@@ -26,6 +26,9 @@ module Aerospike
|
|
26
26
|
attr_accessor :priority, :timeout, :max_retries, :sleep_between_retries, :consistency_level,
|
27
27
|
:predexp, :fail_on_filtered_out, :replica, :use_compression
|
28
28
|
|
29
|
+
alias total_timeout timeout
|
30
|
+
alias total_timeout= timeout=
|
31
|
+
|
29
32
|
def initialize(opt={})
|
30
33
|
# Container object for transaction policy attributes used in all database
|
31
34
|
# operation calls.
|
@@ -85,7 +88,7 @@ module Aerospike
|
|
85
88
|
|
86
89
|
|
87
90
|
# Send read commands to the node containing the key's partition replica type.
|
88
|
-
# Write commands are not affected by this setting, because all writes are directed
|
91
|
+
# Write commands are not affected by this setting, because all writes are directed
|
89
92
|
# to the node containing the key's master partition.
|
90
93
|
#
|
91
94
|
# Default to sending read commands to the node containing the key's master partition.
|
@@ -22,6 +22,7 @@ module Aerospike
|
|
22
22
|
# Container object for scan policy command.
|
23
23
|
class ScanPolicy < Policy
|
24
24
|
|
25
|
+
attr_accessor :max_records
|
25
26
|
attr_accessor :scan_percent
|
26
27
|
attr_accessor :concurrent_nodes
|
27
28
|
attr_accessor :include_bin_data
|
@@ -35,6 +36,16 @@ module Aerospike
|
|
35
36
|
|
36
37
|
@max_retries = 0
|
37
38
|
|
39
|
+
# Approximates the number of records to return to the client. This number is divided by the
|
40
|
+
# number of nodes involved in the query. The actual number of records returned
|
41
|
+
# may be less than MaxRecords if node record counts are small and unbalanced across
|
42
|
+
# nodes.
|
43
|
+
#
|
44
|
+
# This field is supported on server versions >= 4.9.
|
45
|
+
#
|
46
|
+
# Default: 0 (do not limit record count)
|
47
|
+
@max_records = opt.fetch(:max_records) { 0 }
|
48
|
+
|
38
49
|
# Percent of data to scan. Valid integer range is 1 to 100.
|
39
50
|
# Default is 100.
|
40
51
|
@scan_percent = opt[:scan_percent] || 100
|
@@ -51,7 +62,15 @@ module Aerospike
|
|
51
62
|
# Default is true.
|
52
63
|
@fail_on_cluster_change = opt.fetch(:fail_on_cluster_change) { true }
|
53
64
|
|
54
|
-
|
65
|
+
# Determines network timeout for each attempt.
|
66
|
+
#
|
67
|
+
# If socket_timeout is not zero and socket_timeout is reached before an attempt completes,
|
68
|
+
# the Timeout above is checked. If Timeout is not exceeded, the transaction
|
69
|
+
# is retried. If both socket_timeout and Timeout are non-zero, socket_timeout must be less
|
70
|
+
# than or equal to Timeout, otherwise Timeout will also be used for socket_timeout.
|
71
|
+
#
|
72
|
+
# Default: 30s
|
73
|
+
@socket_timeout = opt[:socket_timeout] || 30000
|
55
74
|
|
56
75
|
# Number of records to place in queue before blocking. Records received
|
57
76
|
# from multiple server nodes will be placed in a queue. A separate thread
|
data/lib/aerospike/privilege.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2014-2020 Aerospike, Inc.
|
4
|
+
#
|
5
|
+
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
6
|
+
# license agreements.
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
9
|
+
# use this file except in compliance with the License. You may obtain a copy of
|
10
|
+
# the License at http:#www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
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.
|
17
|
+
|
18
|
+
module Aerospike
|
19
|
+
class NodePartitions
|
20
|
+
attr_accessor :node, :parts_full, :parts_partial, :record_count, :record_max, :parts_unavailable
|
21
|
+
|
22
|
+
def initialize(node)
|
23
|
+
@node= node
|
24
|
+
@parts_full= []
|
25
|
+
@parts_partial= []
|
26
|
+
@record_count= 0
|
27
|
+
@parts_unavailable= 0
|
28
|
+
@record_max= 0
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
"Node #{@node.inspect}: full: #{@parts_full.length}, partial: #{@parts_partial.length}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_partition(partition_status)
|
36
|
+
partition_status.digest.nil? ? @parts_full << partition_status : @parts_partial << partition_status
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2014-2020 Aerospike, Inc.
|
4
|
+
#
|
5
|
+
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
6
|
+
# license agreements.
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
9
|
+
# use this file except in compliance with the License. You may obtain a copy of
|
10
|
+
# the License at http:#www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
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.
|
17
|
+
|
18
|
+
module Aerospike
|
19
|
+
class PartitionFilter
|
20
|
+
attr_reader :partition_begin, :count, :digest
|
21
|
+
attr_accessor :partitions, :done
|
22
|
+
|
23
|
+
alias done? done
|
24
|
+
|
25
|
+
# Creates a partition filter that
|
26
|
+
# reads all the partitions.
|
27
|
+
def self.all
|
28
|
+
PartitionFilter.new(0, Aerospike::Node::PARTITIONS)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Creates a partition filter by partition id.
|
32
|
+
# Partition id is between 0 - 4095
|
33
|
+
def self.by_id(partition_id)
|
34
|
+
PartitionFilter.new(partition_id, 1)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Creates a partition filter by partition range.
|
38
|
+
# begin partition id is between 0 - 4095
|
39
|
+
# count is the number of partitions, in the range of 1 - 4096 inclusive.
|
40
|
+
def self.by_range(partition_begin, count)
|
41
|
+
PartitionFilter.new(partition_begin, count)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Creates a partition filter that will return
|
45
|
+
# records after key's digest in the partition containing the digest.
|
46
|
+
# Note that digest order is not the same as userKey order. This method
|
47
|
+
# only works for scan or query with nil filter.
|
48
|
+
def self.by_key(key)
|
49
|
+
PartitionFilter.new(key.partition_id, 1, key.digest)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
"PartitionFilter<begin: #{@partition_begin}, count: #{@count}, digest: #{@digest}, done: #{@done}>"
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def initialize(partition_begin, count, digest = nil, partitions = nil, done = false)
|
59
|
+
@partition_begin = partition_begin
|
60
|
+
@count = count
|
61
|
+
@digest = digest
|
62
|
+
@partitions = partitions
|
63
|
+
@done = done
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2014-2020 Aerospike, Inc.
|
4
|
+
#
|
5
|
+
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
6
|
+
# license agreements.
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
9
|
+
# use this file except in compliance with the License. You may obtain a copy of
|
10
|
+
# the License at http:#www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
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.
|
17
|
+
|
18
|
+
module Aerospike
|
19
|
+
|
20
|
+
class PartitionStatus #:nodoc:
|
21
|
+
attr_accessor :bval, :id, :digest, :retry
|
22
|
+
|
23
|
+
def initialize(id)
|
24
|
+
@id = id
|
25
|
+
@retry = true
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Show the PartitionStatus as String.
|
30
|
+
#
|
31
|
+
def to_s
|
32
|
+
"PartitionStatus<bval: #{@bval}, id: #{@id}, retry: #{@retry}, digest: #{@digest}>"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|