aerospike 2.9.1 → 2.14.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 +50 -4
- data/README.md +1 -1
- data/lib/aerospike.rb +17 -4
- data/lib/aerospike/aerospike_exception.rb +7 -1
- data/lib/aerospike/atomic/atomic.rb +1 -1
- data/lib/aerospike/bin.rb +1 -1
- data/lib/aerospike/cdt/list_operation.rb +1 -1
- data/lib/aerospike/cdt/map_operation.rb +1 -1
- data/lib/aerospike/cdt/map_order.rb +1 -1
- data/lib/aerospike/cdt/map_policy.rb +1 -1
- data/lib/aerospike/cdt/map_return_type.rb +1 -1
- data/lib/aerospike/cdt/map_write_mode.rb +1 -1
- data/lib/aerospike/client.rb +31 -17
- data/lib/aerospike/cluster.rb +139 -17
- data/lib/aerospike/cluster/partition.rb +1 -1
- data/lib/aerospike/cluster/partition_parser.rb +169 -0
- data/lib/aerospike/cluster/rack_parser.rb +117 -0
- data/lib/aerospike/command/admin_command.rb +1 -1
- data/lib/aerospike/command/batch_direct_command.rb +2 -1
- data/lib/aerospike/command/batch_direct_exists_command.rb +1 -1
- data/lib/aerospike/command/batch_direct_node.rb +3 -3
- data/lib/aerospike/command/batch_index_command.rb +11 -2
- data/lib/aerospike/command/batch_index_node.rb +2 -2
- data/lib/aerospike/command/batch_item.rb +1 -1
- data/lib/aerospike/command/command.rb +157 -11
- data/lib/aerospike/command/delete_command.rb +21 -5
- data/lib/aerospike/command/execute_command.rb +1 -1
- data/lib/aerospike/command/exists_command.rb +21 -5
- data/lib/aerospike/command/field_type.rb +3 -1
- data/lib/aerospike/command/multi_command.rb +55 -5
- data/lib/aerospike/command/operate_command.rb +6 -1
- data/lib/aerospike/command/read_command.rb +63 -20
- data/lib/aerospike/command/read_header_command.rb +18 -6
- data/lib/aerospike/command/roles.rb +1 -1
- data/lib/aerospike/command/single_command.rb +9 -3
- data/lib/aerospike/command/touch_command.rb +48 -4
- data/lib/aerospike/command/unsupported_particle_type_validator.rb +1 -1
- data/lib/aerospike/command/write_command.rb +13 -4
- data/lib/aerospike/connection/create.rb +1 -1
- data/lib/aerospike/features.rb +3 -1
- data/lib/aerospike/geo_json.rb +70 -1
- data/lib/aerospike/host.rb +1 -1
- data/lib/aerospike/info.rb +1 -1
- data/lib/aerospike/key.rb +1 -1
- data/lib/aerospike/language.rb +1 -1
- data/lib/aerospike/node.rb +21 -7
- data/lib/aerospike/node/rebalance.rb +50 -0
- data/lib/aerospike/node/refresh/info.rb +4 -1
- data/lib/aerospike/node/refresh/partitions.rb +6 -15
- data/lib/aerospike/node/refresh/racks.rb +47 -0
- data/lib/aerospike/node/refresh/reset.rb +1 -0
- data/lib/aerospike/node/verify/rebalance_generation.rb +43 -0
- data/lib/aerospike/node_validator.rb +45 -40
- data/lib/aerospike/operation.rb +6 -1
- data/lib/aerospike/policy/admin_policy.rb +1 -1
- data/lib/aerospike/policy/batch_policy.rb +1 -1
- data/lib/aerospike/policy/client_policy.rb +16 -1
- data/lib/aerospike/policy/commit_level.rb +1 -1
- data/lib/aerospike/policy/consistency_level.rb +1 -1
- data/lib/aerospike/policy/generation_policy.rb +1 -1
- data/lib/aerospike/policy/operate_policy.rb +1 -1
- data/lib/aerospike/policy/policy.rb +64 -2
- data/lib/aerospike/policy/priority.rb +1 -1
- data/lib/aerospike/policy/query_policy.rb +8 -1
- data/lib/aerospike/policy/record_bin_multiplicity.rb +1 -1
- data/lib/aerospike/policy/record_exists_action.rb +1 -1
- data/lib/aerospike/policy/replica.rb +45 -0
- data/lib/aerospike/policy/scan_policy.rb +8 -1
- data/lib/aerospike/policy/write_policy.rb +1 -1
- data/lib/aerospike/query/filter.rb +1 -1
- data/lib/aerospike/query/pred_exp.rb +192 -0
- data/lib/aerospike/query/pred_exp/and_or.rb +32 -0
- data/lib/aerospike/query/pred_exp/geo_json_value.rb +41 -0
- data/lib/aerospike/query/pred_exp/integer_value.rb +32 -0
- data/lib/aerospike/query/pred_exp/op.rb +27 -0
- data/lib/aerospike/query/pred_exp/regex.rb +32 -0
- data/lib/aerospike/query/pred_exp/regex_flags.rb +23 -0
- data/lib/aerospike/query/pred_exp/string_value.rb +29 -0
- data/lib/aerospike/query/query_command.rb +27 -1
- data/lib/aerospike/query/recordset.rb +5 -5
- data/lib/aerospike/query/scan_command.rb +1 -1
- data/lib/aerospike/query/statement.rb +12 -3
- data/lib/aerospike/query/stream_command.rb +1 -1
- data/lib/aerospike/record.rb +1 -1
- data/lib/aerospike/result_code.rb +13 -7
- data/lib/aerospike/socket/base.rb +4 -3
- data/lib/aerospike/task/execute_task.rb +1 -1
- data/lib/aerospike/task/index_task.rb +1 -1
- data/lib/aerospike/task/task.rb +1 -1
- data/lib/aerospike/task/udf_register_task.rb +1 -1
- data/lib/aerospike/task/udf_remove_task.rb +1 -1
- data/lib/aerospike/ttl.rb +1 -1
- data/lib/aerospike/udf.rb +1 -1
- data/lib/aerospike/user_role.rb +1 -1
- data/lib/aerospike/utils/buffer.rb +14 -4
- data/lib/aerospike/utils/packer.rb +1 -1
- data/lib/aerospike/utils/pool.rb +1 -1
- data/lib/aerospike/utils/unpacker.rb +7 -2
- data/lib/aerospike/value/particle_type.rb +1 -1
- data/lib/aerospike/value/value.rb +59 -29
- data/lib/aerospike/version.rb +1 -1
- metadata +19 -8
- data/lib/aerospike/cluster/partition_tokenizer_new.rb +0 -130
- data/lib/aerospike/cluster/partition_tokenizer_old.rb +0 -135
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0452d4d35ee6d5ce56586cc99b3a68c7e1b4a6c4f6334c6794414a483e2ef01
|
4
|
+
data.tar.gz: 328a5672510bb68e044a92c39fc1f04059daa53b4332eaa5a64dda04f5b3de78
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44c883336f3993d532c7989e1c6bf737deca2773cb444a4cfa6021bca35311c9d4fe5c74ddb73fa1274661435a127892f9a368bd1d94120e6965bee38b870216
|
7
|
+
data.tar.gz: ebac442b5b2ddc345b7d7713b0e8d7f0aaaba9da24aabe811e1a10a26555c2a85ba1d2bad0a0266674fdcc1c3deb573ed1839ffe98294dc979ccc69e42eab187
|
data/CHANGELOG.md
CHANGED
@@ -2,12 +2,58 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
-
## [
|
5
|
+
## [2.14.0] - 2019-08-06
|
6
|
+
|
7
|
+
* **New Features**
|
8
|
+
* Adds support for rake-aware reads.
|
9
|
+
* Adds support for client-server compression.
|
10
|
+
|
11
|
+
* **Improvements**
|
12
|
+
* Adds support for `truncate-namespace` command.
|
13
|
+
|
14
|
+
## [2.13.0] - 2019-07-17
|
15
|
+
|
16
|
+
* **New Features**
|
17
|
+
* Adds support for replica policies.
|
18
|
+
|
19
|
+
* **Improvements**
|
20
|
+
* Remove support for "old" partition tokenizer.
|
21
|
+
* Refactor how partition parser is initialized and called.
|
22
|
+
* Adds support for 'replicas' and remove the old partition table queries from the server.
|
23
|
+
|
24
|
+
## [2.12.0] - 2019-04-21
|
25
|
+
|
26
|
+
* **New Features**
|
27
|
+
* Support for predicate expressions in all transaction.
|
28
|
+
* Support for `operation.delete` in `client#operate`.
|
29
|
+
|
30
|
+
* **Improvements**
|
31
|
+
* Optimize serialization for nested structures. Thanks to [@Kacper Madej](https://github.com/madejejej)! [[#94](https://github.com/aerospike/aerospike-client-ruby/pull/94)]
|
32
|
+
* Remove `Thread#abort_on_exception` from `batch_index_command`. Thanks to [@Kacper Madej](https://github.com/madejejej)! [[#94](https://github.com/aerospike/aerospike-client-ruby/pull/92)]
|
33
|
+
* Does not allow values other than Integer, Float, String, Symbol and nil to be used as keys in Maps.
|
34
|
+
|
35
|
+
* **Bug Fixes**
|
36
|
+
* Fixes tests that weren't using ENV variables for connections. This will allow the tests to be run on any server.
|
37
|
+
|
38
|
+
|
39
|
+
## [2.11.0] - 2019-05-17
|
40
|
+
|
41
|
+
* **New Features**
|
42
|
+
* Support for predicate expressions in queries. Thanks to [@Minus10Degrees](https://github.com/Minus10Degrees)! [[#78](https://github.com/aerospike/aerospike-client-ruby/issues/78)]
|
43
|
+
|
44
|
+
* **Bug Fixes**
|
45
|
+
* Client#execute\_udf\_on\_query should not modify the statement argument. [[#79](https://github.com/aerospike/aerospike-client-ruby/issues/79)]
|
46
|
+
* Encoding::UndefinedConversionError when reading blob data from CDT list/map bin. [[#84](https://github.com/aerospike/aerospike-client-ruby/issues/84)]
|
47
|
+
|
48
|
+
## [2.10.0] - 2019-05-10
|
49
|
+
|
50
|
+
* **New Features**
|
51
|
+
* Add support for LB discovery / seeding. Thanks to [@filiptepper](https://github.com/filiptepper)! [[#80](https://github.com/aerospike/aerospike-client-ruby/issues/80)]
|
6
52
|
|
7
53
|
## [2.9.1] - 2019-04-03
|
8
54
|
|
9
55
|
* **Bug Fixes**
|
10
|
-
* Query fails if one or more cluster nodes do not have records in the set [[#77](https://github.com/aerospike/aerospike-client-ruby/
|
56
|
+
* Query fails if one or more cluster nodes do not have records in the set [[#77](https://github.com/aerospike/aerospike-client-ruby/issues/77)]
|
11
57
|
|
12
58
|
* **Updates**
|
13
59
|
* Change admin message version to 2 (from 0)
|
@@ -20,10 +66,10 @@ All notable changes to this project will be documented in this file.
|
|
20
66
|
* Add INFINITY and WILDCARD values for use in CDT map/list comparators. [AER-5945]
|
21
67
|
|
22
68
|
* **Bug Fixes**
|
23
|
-
* Default policies set on Client instance do not get applied [[#74](https://github.com/aerospike/aerospike-client-ruby/
|
69
|
+
* Default policies set on Client instance do not get applied [[#74](https://github.com/aerospike/aerospike-client-ruby/issues/74)]
|
24
70
|
|
25
71
|
* **Updates**
|
26
|
-
* *BREAKING CHANGE*: Change default for send_key write policy to false [[#73](https://github.com/aerospike/aerospike-client-ruby/
|
72
|
+
* *BREAKING CHANGE*: Change default for send_key write policy to false [[#73](https://github.com/aerospike/aerospike-client-ruby/issues/73)]
|
27
73
|
* Support truncate info command argument "lut=now" for servers that require it. [AER-5955]
|
28
74
|
|
29
75
|
## [2.8.0] - 2018-08-06
|
data/README.md
CHANGED
@@ -97,7 +97,7 @@ This library is packaged with a number of tests.
|
|
97
97
|
|
98
98
|
To run all the test cases:
|
99
99
|
|
100
|
-
$ bundle exec rspec
|
100
|
+
$ AEROSPIKE_HOSTS="<host:port>[,<hoist:port>]" AEROSPIKE_USER="<user>" AEROSPIKE_PASSWORD="<pass>" bundle exec rspec
|
101
101
|
|
102
102
|
<a name="Examples"></a>
|
103
103
|
## Examples
|
data/lib/aerospike.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2014-
|
1
|
+
# Copyright 2014-2020 Aerospike, Inc.
|
2
2
|
#
|
3
3
|
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
4
4
|
# license agreements.
|
@@ -22,6 +22,7 @@ require "timeout"
|
|
22
22
|
require 'resolv'
|
23
23
|
require 'msgpack'
|
24
24
|
require 'bcrypt'
|
25
|
+
require 'zlib'
|
25
26
|
|
26
27
|
require 'aerospike/atomic/atomic'
|
27
28
|
|
@@ -101,22 +102,25 @@ require 'aerospike/connection/create'
|
|
101
102
|
|
102
103
|
require 'aerospike/cluster'
|
103
104
|
require 'aerospike/cluster/create_connection'
|
104
|
-
require 'aerospike/cluster/partition'
|
105
105
|
require 'aerospike/cluster/find_nodes_to_remove'
|
106
106
|
require 'aerospike/cluster/find_node'
|
107
|
-
require 'aerospike/cluster/
|
108
|
-
require 'aerospike/cluster/
|
107
|
+
require 'aerospike/cluster/partition'
|
108
|
+
require 'aerospike/cluster/partition_parser'
|
109
|
+
require 'aerospike/cluster/rack_parser'
|
109
110
|
require 'aerospike/node'
|
110
111
|
require 'aerospike/node/generation'
|
112
|
+
require 'aerospike/node/rebalance'
|
111
113
|
require 'aerospike/node/refresh/failed'
|
112
114
|
require 'aerospike/node/refresh/friends'
|
113
115
|
require 'aerospike/node/refresh/info'
|
114
116
|
require 'aerospike/node/refresh/partitions'
|
117
|
+
require 'aerospike/node/refresh/racks'
|
115
118
|
require 'aerospike/node/refresh/peers'
|
116
119
|
require 'aerospike/node/refresh/reset'
|
117
120
|
require 'aerospike/node/verify/cluster_name'
|
118
121
|
require 'aerospike/node/verify/name'
|
119
122
|
require 'aerospike/node/verify/partition_generation'
|
123
|
+
require 'aerospike/node/verify/rebalance_generation'
|
120
124
|
require 'aerospike/node/verify/peers_generation'
|
121
125
|
require 'aerospike/node_validator'
|
122
126
|
require 'aerospike/peer'
|
@@ -142,6 +146,15 @@ require 'aerospike/query/stream_command'
|
|
142
146
|
require 'aerospike/query/query_command'
|
143
147
|
require 'aerospike/query/scan_command'
|
144
148
|
require 'aerospike/query/statement'
|
149
|
+
require 'aerospike/query/pred_exp'
|
150
|
+
|
151
|
+
require 'aerospike/query/pred_exp/and_or'
|
152
|
+
require 'aerospike/query/pred_exp/geo_json_value'
|
153
|
+
require 'aerospike/query/pred_exp/integer_value'
|
154
|
+
require 'aerospike/query/pred_exp/op'
|
155
|
+
require 'aerospike/query/pred_exp/regex'
|
156
|
+
require 'aerospike/query/pred_exp/regex_flags'
|
157
|
+
require 'aerospike/query/pred_exp/string_value'
|
145
158
|
|
146
159
|
module Aerospike
|
147
160
|
extend Loggable
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
# Copyright 2014-
|
2
|
+
# Copyright 2014-2020 Aerospike, Inc.
|
3
3
|
#
|
4
4
|
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
5
5
|
# license agreements.
|
@@ -90,5 +90,11 @@ module Aerospike
|
|
90
90
|
super(ResultCode::COMMAND_REJECTED, msg)
|
91
91
|
end
|
92
92
|
end
|
93
|
+
|
94
|
+
class InvalidNamespace < Aerospike
|
95
|
+
def initialize(msg=nil)
|
96
|
+
super(ResultCode::INVALID_NAMESPACE, msg)
|
97
|
+
end
|
98
|
+
end
|
93
99
|
end
|
94
100
|
end
|
data/lib/aerospike/bin.rb
CHANGED
data/lib/aerospike/client.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2014-
|
1
|
+
# Copyright 2014-2020 Aerospike, Inc.
|
2
2
|
#
|
3
3
|
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
4
4
|
# license agreements.
|
@@ -44,6 +44,7 @@ module Aerospike
|
|
44
44
|
attr_accessor :default_read_policy
|
45
45
|
attr_accessor :default_scan_policy
|
46
46
|
attr_accessor :default_write_policy
|
47
|
+
attr_accessor :cluster
|
47
48
|
|
48
49
|
def initialize(hosts = nil, policy: ClientPolicy.new, connect: true)
|
49
50
|
|
@@ -224,8 +225,19 @@ module Aerospike
|
|
224
225
|
def truncate(namespace, set_name = nil, before_last_update = nil, options = {})
|
225
226
|
policy = create_policy(options, Policy, default_info_policy)
|
226
227
|
|
227
|
-
|
228
|
-
|
228
|
+
node = @cluster.random_node
|
229
|
+
conn = node.get_connection(policy.timeout)
|
230
|
+
|
231
|
+
if set_name && !set_name.to_s.strip.empty?
|
232
|
+
str_cmd = "truncate:namespace=#{namespace}"
|
233
|
+
str_cmd << ";set=#{set_name}" unless set_name.to_s.strip.empty?
|
234
|
+
else
|
235
|
+
if node.supports_feature(Aerospike::Features::TRUNCATE_NAMESPACE)
|
236
|
+
str_cmd = "truncate-namespace:namespace=#{namespace}"
|
237
|
+
else
|
238
|
+
str_cmd = "truncate:namespace=#{namespace}"
|
239
|
+
end
|
240
|
+
end
|
229
241
|
|
230
242
|
if before_last_update
|
231
243
|
lut_nanos = (before_last_update.to_f * 1_000_000_000.0).round
|
@@ -235,8 +247,7 @@ module Aerospike
|
|
235
247
|
str_cmd << ";lut=now"
|
236
248
|
end
|
237
249
|
|
238
|
-
|
239
|
-
response = send_info_command(policy, str_cmd).upcase
|
250
|
+
response = send_info_command(policy, str_cmd, node).upcase
|
240
251
|
return if response == 'OK'
|
241
252
|
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_ERROR, "Truncate failed: #{response}")
|
242
253
|
end
|
@@ -322,11 +333,11 @@ module Aerospike
|
|
322
333
|
|
323
334
|
if policy.use_batch_direct
|
324
335
|
key_map = BatchItem.generate_map(keys)
|
325
|
-
execute_batch_direct_commands(keys) do |node, batch|
|
336
|
+
execute_batch_direct_commands(policy, keys) do |node, batch|
|
326
337
|
BatchDirectCommand.new(node, batch, policy, key_map, bin_names, results, info_flags)
|
327
338
|
end
|
328
339
|
else
|
329
|
-
execute_batch_index_commands(keys) do |node, batch|
|
340
|
+
execute_batch_index_commands(policy, keys) do |node, batch|
|
330
341
|
BatchIndexCommand.new(node, batch, policy, bin_names, results, info_flags)
|
331
342
|
end
|
332
343
|
end
|
@@ -351,11 +362,11 @@ module Aerospike
|
|
351
362
|
|
352
363
|
if policy.use_batch_direct
|
353
364
|
key_map = BatchItem.generate_map(keys)
|
354
|
-
execute_batch_direct_commands(keys) do |node, batch|
|
365
|
+
execute_batch_direct_commands(policy, keys) do |node, batch|
|
355
366
|
BatchDirectExistsCommand.new(node, batch, policy, key_map, results)
|
356
367
|
end
|
357
368
|
else
|
358
|
-
execute_batch_index_commands(keys) do |node, batch|
|
369
|
+
execute_batch_index_commands(policy, keys) do |node, batch|
|
359
370
|
BatchIndexExistsCommand.new(node, batch, policy, results)
|
360
371
|
end
|
361
372
|
end
|
@@ -526,7 +537,7 @@ module Aerospike
|
|
526
537
|
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_NOT_AVAILABLE, "Executing UDF failed because cluster is empty.")
|
527
538
|
end
|
528
539
|
|
529
|
-
|
540
|
+
statement = statement.clone
|
530
541
|
statement.set_aggregate_function(package_name, function_name, function_args, false)
|
531
542
|
|
532
543
|
# Use a thread per node
|
@@ -818,9 +829,13 @@ module Aerospike
|
|
818
829
|
self.default_write_policy = create_policy(policies[:write], WritePolicy)
|
819
830
|
end
|
820
831
|
|
821
|
-
def send_info_command(policy, command)
|
832
|
+
def send_info_command(policy, command, node = nil)
|
822
833
|
Aerospike.logger.debug { "Sending info command: #{command}" }
|
823
|
-
|
834
|
+
if node
|
835
|
+
_, response = @cluster.request_node_info(node, policy, command).first
|
836
|
+
else
|
837
|
+
_, response = @cluster.request_info(policy, command).first
|
838
|
+
end
|
824
839
|
response.to_s
|
825
840
|
end
|
826
841
|
|
@@ -884,17 +899,16 @@ module Aerospike
|
|
884
899
|
command.execute
|
885
900
|
end
|
886
901
|
|
887
|
-
def execute_batch_index_commands(keys)
|
902
|
+
def execute_batch_index_commands(policy, keys)
|
888
903
|
if @cluster.nodes.empty?
|
889
904
|
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_NOT_AVAILABLE, "Executing Batch Index command failed because cluster is empty.")
|
890
905
|
end
|
891
906
|
|
892
|
-
batch_nodes = BatchIndexNode.generate_list(@cluster, keys)
|
907
|
+
batch_nodes = BatchIndexNode.generate_list(@cluster, policy.replica, keys)
|
893
908
|
threads = []
|
894
909
|
|
895
910
|
batch_nodes.each do |batch|
|
896
911
|
threads << Thread.new do
|
897
|
-
Thread.current.abort_on_exception = true
|
898
912
|
command = yield batch.node, batch
|
899
913
|
execute_command(command)
|
900
914
|
end
|
@@ -903,12 +917,12 @@ module Aerospike
|
|
903
917
|
threads.each(&:join)
|
904
918
|
end
|
905
919
|
|
906
|
-
def execute_batch_direct_commands(keys)
|
920
|
+
def execute_batch_direct_commands(policy, keys)
|
907
921
|
if @cluster.nodes.empty?
|
908
922
|
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_NOT_AVAILABLE, "Executing Batch Direct command failed because cluster is empty.")
|
909
923
|
end
|
910
924
|
|
911
|
-
batch_nodes = BatchDirectNode.generate_list(@cluster, keys)
|
925
|
+
batch_nodes = BatchDirectNode.generate_list(@cluster, policy.replica, keys)
|
912
926
|
threads = []
|
913
927
|
|
914
928
|
# Use a thread per namespace per node
|
data/lib/aerospike/cluster.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright 2014-
|
3
|
+
# Copyright 2014-2020 Aerospike, Inc.
|
4
4
|
#
|
5
5
|
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
6
6
|
# license agreements.
|
@@ -28,6 +28,7 @@ module Aerospike
|
|
28
28
|
attr_reader :features, :tls_options
|
29
29
|
attr_reader :cluster_id, :aliases
|
30
30
|
attr_reader :cluster_name
|
31
|
+
attr_accessor :rack_aware, :rack_id
|
31
32
|
|
32
33
|
def initialize(policy, hosts)
|
33
34
|
@cluster_seeds = hosts
|
@@ -37,6 +38,10 @@ module Aerospike
|
|
37
38
|
@tend_interval = policy.tend_interval
|
38
39
|
@cluster_name = policy.cluster_name
|
39
40
|
@tls_options = policy.tls
|
41
|
+
@rack_aware = policy.rack_aware
|
42
|
+
@rack_id = policy.rack_id
|
43
|
+
|
44
|
+
@replica_index = Atomic.new(0)
|
40
45
|
|
41
46
|
@aliases = {}
|
42
47
|
@cluster_nodes = []
|
@@ -102,18 +107,128 @@ module Aerospike
|
|
102
107
|
(node_array.length > 0) && !@closed.value
|
103
108
|
end
|
104
109
|
|
105
|
-
|
106
|
-
|
110
|
+
# Returns a node on the cluster for read operations
|
111
|
+
def batch_read_node(partition, replica_policy)
|
112
|
+
case replica_policy
|
113
|
+
when Aerospike::Replica::MASTER, Aerospike::Replica::SEQUENCE
|
114
|
+
return master_node(partition)
|
115
|
+
when Aerospike::Replica::MASTER_PROLES
|
116
|
+
return master_proles_node(partition)
|
117
|
+
when Aerospike::Replica::PREFER_RACK
|
118
|
+
return rack_node(partition, seq)
|
119
|
+
when Aerospike::Replica::RANDOM
|
120
|
+
return random_node
|
121
|
+
else
|
122
|
+
raise Aerospike::Exceptions::InvalidNode("invalid policy.replica value")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns a node on the cluster for read operations
|
127
|
+
def read_node(partition, replica_policy, seq)
|
128
|
+
case replica_policy
|
129
|
+
when Aerospike::Replica::MASTER
|
130
|
+
return master_node(partition)
|
131
|
+
when Aerospike::Replica::MASTER_PROLES
|
132
|
+
return master_proles_node(partition)
|
133
|
+
when Aerospike::Replica::PREFER_RACK
|
134
|
+
return rack_node(partition, seq)
|
135
|
+
when Aerospike::Replica::SEQUENCE
|
136
|
+
return sequence_node(partition, seq)
|
137
|
+
when Aerospike::Replica::RANDOM
|
138
|
+
return random_node
|
139
|
+
else
|
140
|
+
raise Aerospike::Exceptions::InvalidNode("invalid policy.replica value")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Returns a node on the cluster for read operations
|
145
|
+
def master_node(partition)
|
146
|
+
partition_map = partitions
|
147
|
+
replica_array = partition_map[partition.namespace]
|
148
|
+
raise Aerospike::Exceptions::InvalidNamespace("namespace not found in the partition map") if !replica_array
|
149
|
+
|
150
|
+
node_array = (replica_array.get)[0]
|
151
|
+
raise Aerospike::Exceptions::InvalidNamespace("namespace not found in the partition map") if !node_array
|
152
|
+
|
153
|
+
node = (node_array.get)[partition.partition_id]
|
154
|
+
raise Aerospike::Exceptions::InvalidNode if !node || !node.active?
|
155
|
+
|
156
|
+
node
|
157
|
+
end
|
158
|
+
|
159
|
+
# Returns a node on the cluster
|
160
|
+
def rack_node(partition, seq)
|
161
|
+
partition_map = partitions
|
162
|
+
replica_array = partition_map[partition.namespace]
|
163
|
+
raise Aerospike::Exceptions::InvalidNamespace("namespace not found in the partition map") if !replica_array
|
164
|
+
|
165
|
+
replica_array = replica_array.get
|
166
|
+
|
167
|
+
is_retry = seq.value > -1
|
168
|
+
|
169
|
+
node = nil
|
170
|
+
fallback = nil
|
171
|
+
for i in 1..replica_array.length
|
172
|
+
idx = (seq.update{|v| v.succ} % replica_array.size).abs
|
173
|
+
node = (replica_array[idx].get)[partition.partition_id]
|
174
|
+
|
175
|
+
next if !node
|
176
|
+
|
177
|
+
fallback = node
|
178
|
+
|
179
|
+
# If fallback exists, do not retry on node where command failed,
|
180
|
+
# even if fallback is not on the same rack.
|
181
|
+
return fallback if is_retry && fallback && i == replica_array.length
|
182
|
+
|
183
|
+
return node if node && node.active? && node.has_rack(partition.namespace, @rack_id)
|
184
|
+
end
|
185
|
+
|
186
|
+
return fallback if fallback
|
187
|
+
|
188
|
+
raise Aerospike::Exceptions::InvalidNode
|
189
|
+
end
|
107
190
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
191
|
+
# Returns a node on the cluster for read operations
|
192
|
+
def master_proles_node(partition)
|
193
|
+
partition_map = partitions
|
194
|
+
replica_array = partition_map[partition.namespace]
|
195
|
+
raise Aerospike::Exceptions::InvalidNamespace("namespace not found in the partition map") if !replica_array
|
196
|
+
|
197
|
+
replica_array = replica_array.get
|
198
|
+
|
199
|
+
node = nil
|
200
|
+
for replica in replica_array
|
201
|
+
idx = (@replica_index.update{|v| v.succ} % replica_array.size).abs
|
202
|
+
node = (replica_array[idx].get)[partition.partition_id]
|
203
|
+
|
204
|
+
return node if node && node.active?
|
205
|
+
end
|
206
|
+
|
207
|
+
raise Aerospike::Exceptions::InvalidNode
|
208
|
+
end
|
209
|
+
|
210
|
+
# Returns a random node on the cluster
|
211
|
+
def sequence_node(partition, seq)
|
212
|
+
partition_map = partitions
|
213
|
+
replica_array = partition_map[partition.namespace]
|
214
|
+
raise Aerospike::Exceptions::InvalidNamespace("namespace not found in the partition map") if !replica_array
|
215
|
+
|
216
|
+
replica_array = replica_array.get
|
217
|
+
|
218
|
+
node = nil
|
219
|
+
for replica in replica_array
|
220
|
+
idx = (seq.update{|v| v.succ} % replica_array.size).abs
|
221
|
+
node = (replica_array[idx].get)[partition.partition_id]
|
112
222
|
|
113
223
|
return node if node && node.active?
|
114
224
|
end
|
115
225
|
|
116
|
-
|
226
|
+
raise Aerospike::Exceptions::InvalidNode
|
227
|
+
end
|
228
|
+
|
229
|
+
def get_node_for_key(replica_policy, key)
|
230
|
+
partition = Partition.new_by_key(key)
|
231
|
+
batch_read_node(partition, replica_policy)
|
117
232
|
end
|
118
233
|
|
119
234
|
# Returns a random node on the cluster
|
@@ -124,8 +239,8 @@ module Aerospike
|
|
124
239
|
i = 0
|
125
240
|
while i < length
|
126
241
|
# Must handle concurrency with other non-tending threads, so node_index is consistent.
|
127
|
-
|
128
|
-
node = node_array[
|
242
|
+
idx = (@node_index.update{ |v| v.succ } % node_array.length).abs
|
243
|
+
node = node_array[idx]
|
129
244
|
|
130
245
|
return node if node.active?
|
131
246
|
|
@@ -167,12 +282,9 @@ module Aerospike
|
|
167
282
|
end
|
168
283
|
end
|
169
284
|
|
170
|
-
def update_partitions(
|
171
|
-
nmap =
|
172
|
-
# update partition write map
|
285
|
+
def update_partitions(parser)
|
286
|
+
nmap = parser.update_partitions(partitions)
|
173
287
|
set_partitions(nmap) if nmap
|
174
|
-
|
175
|
-
Aerospike.logger.info("Partitions for node #{node.name} updated")
|
176
288
|
end
|
177
289
|
|
178
290
|
def request_info(policy, *commands)
|
@@ -183,6 +295,13 @@ module Aerospike
|
|
183
295
|
end
|
184
296
|
end
|
185
297
|
|
298
|
+
def request_node_info(node, policy, *commands)
|
299
|
+
conn = node.get_connection(policy.timeout)
|
300
|
+
Info.request(conn, *commands).tap do
|
301
|
+
node.put_connection(conn)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
186
305
|
def supports_feature?(feature)
|
187
306
|
@features.get.include?(feature.to_s)
|
188
307
|
end
|
@@ -279,6 +398,7 @@ module Aerospike
|
|
279
398
|
|
280
399
|
nodes.each do |node|
|
281
400
|
node.refresh_partitions(peers) if node.partition_generation.changed?
|
401
|
+
node.refresh_racks if node.rebalance_generation.changed?
|
282
402
|
end
|
283
403
|
|
284
404
|
if peers.generation_changed? || !peers.use_peers?
|
@@ -441,8 +561,10 @@ module Aerospike
|
|
441
561
|
def find_node_in_partition_map(filter)
|
442
562
|
partitions_list = partitions
|
443
563
|
|
444
|
-
partitions_list.values.each do |
|
445
|
-
|
564
|
+
partitions_list.values.each do |replica_array|
|
565
|
+
replica_array.get.each do |node_array|
|
566
|
+
return true if node_array.value.any? { |node| node == filter }
|
567
|
+
end
|
446
568
|
end
|
447
569
|
false
|
448
570
|
end
|