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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -1
  3. data/lib/aerospike/atomic/atomic.rb +1 -1
  4. data/lib/aerospike/cdt/context.rb +7 -7
  5. data/lib/aerospike/cdt/list_return_type.rb +4 -0
  6. data/lib/aerospike/cdt/map_operation.rb +6 -6
  7. data/lib/aerospike/cdt/map_return_type.rb +4 -0
  8. data/lib/aerospike/client.rb +34 -59
  9. data/lib/aerospike/cluster.rb +6 -3
  10. data/lib/aerospike/command/admin_command.rb +2 -2
  11. data/lib/aerospike/command/batch_index_node.rb +1 -1
  12. data/lib/aerospike/command/batch_item.rb +1 -1
  13. data/lib/aerospike/command/command.rb +62 -30
  14. data/lib/aerospike/command/field_type.rb +3 -0
  15. data/lib/aerospike/command/login_command.rb +7 -5
  16. data/lib/aerospike/command/multi_command.rb +8 -2
  17. data/lib/aerospike/command/read_command.rb +2 -2
  18. data/lib/aerospike/connection/authenticate.rb +4 -4
  19. data/lib/aerospike/features.rb +9 -9
  20. data/lib/aerospike/host/parse.rb +2 -2
  21. data/lib/aerospike/key.rb +10 -1
  22. data/lib/aerospike/node/refresh/info.rb +1 -1
  23. data/lib/aerospike/node/verify/name.rb +1 -1
  24. data/lib/aerospike/node/verify/partition_generation.rb +1 -1
  25. data/lib/aerospike/node/verify/peers_generation.rb +1 -1
  26. data/lib/aerospike/node/verify/rebalance_generation.rb +1 -1
  27. data/lib/aerospike/node_validator.rb +6 -1
  28. data/lib/aerospike/policy/policy.rb +4 -1
  29. data/lib/aerospike/policy/scan_policy.rb +20 -1
  30. data/lib/aerospike/privilege.rb +1 -1
  31. data/lib/aerospike/query/node_partitions.rb +39 -0
  32. data/lib/aerospike/query/partition_filter.rb +66 -0
  33. data/lib/aerospike/query/partition_status.rb +36 -0
  34. data/lib/aerospike/query/partition_tracker.rb +347 -0
  35. data/lib/aerospike/query/scan_command.rb +3 -3
  36. data/lib/aerospike/query/scan_executor.rb +69 -0
  37. data/lib/aerospike/query/scan_partition_command.rb +49 -0
  38. data/lib/aerospike/query/statement.rb +1 -1
  39. data/lib/aerospike/query/stream_command.rb +14 -1
  40. data/lib/aerospike/result_code.rb +79 -4
  41. data/lib/aerospike/role.rb +2 -2
  42. data/lib/aerospike/task/execute_task.rb +2 -2
  43. data/lib/aerospike/task/index_task.rb +1 -1
  44. data/lib/aerospike/user_role.rb +1 -1
  45. data/lib/aerospike/utils/buffer.rb +12 -0
  46. data/lib/aerospike/utils/pool.rb +1 -1
  47. data/lib/aerospike/value/value.rb +6 -6
  48. data/lib/aerospike/version.rb +1 -1
  49. data/lib/aerospike.rb +6 -0
  50. metadata +11 -5
@@ -0,0 +1,347 @@
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 PartitionTracker
20
+ attr_reader :partitions, :partitions_capacity, :partition_begin, :node_capacity,
21
+ :node_filter, :partition_filter, :node_partitions_list, :max_records,
22
+ :sleep_between_retries, :socket_timeout, :total_timeout, :iteration, :deadline
23
+
24
+ def initialize(policy, nodes, partition_filter = nil)
25
+ if partition_filter.nil?
26
+ return init_for_node(policy, nodes[0]) if nodes.length == 1
27
+ return init_for_nodes(policy, nodes)
28
+ end
29
+
30
+ # Validate here instead of initial PartitionFilter constructor because total number of
31
+ # cluster partitions may change on the server and PartitionFilter will never have access
32
+ # to Cluster instance. Use fixed number of partitions for now.
33
+ unless partition_filter.partition_begin.between?(0, Node::PARTITIONS - 1)
34
+ raise Aerospike::Exceptions::Aerospike.new(
35
+ Aerospike::ResultCode::PARAMETER_ERROR,
36
+ "Invalid partition begin #{partition_filter.partition_begin}. Valid range: 0-#{Aerospike::Node::PARTITIONS - 1}"
37
+ )
38
+ end
39
+
40
+ if partition_filter.count <= 0
41
+ raise Aerospike::Exceptions::Aerospike.new(
42
+ Aerospike::ResultCode::PARAMETER_ERROR,
43
+ "Invalid partition count #{partition_filter.count}"
44
+ )
45
+ end
46
+
47
+ if partition_filter.partition_begin + partition_filter.count > Node::PARTITIONS
48
+ raise Aerospike::Exceptions::Aerospike.new(
49
+ Aerospike::ResultCode::PARAMETER_ERROR,
50
+ "Invalid partition range (#{partition_filter.partition_begin}, #{partition_filter.partition_begin + partition_filter.count}"
51
+ )
52
+ end
53
+
54
+ @partition_begin = partition_filter.partition_begin
55
+ @node_capacity = nodes.length
56
+ @node_filter = nil
57
+ @partitions_capacity = partition_filter.count
58
+ @max_records = policy.max_records
59
+ @iteration = 1
60
+
61
+ if partition_filter.partitions.nil? then
62
+ partition_filter.partitions = init_partitions(policy, partition_filter.count, partition_filter.digest)
63
+ elsif policy.max_records <= 0
64
+ # Retry all partitions when max_records not specified.
65
+ partition_filter.partitions.each do |ps|
66
+ ps.retry = true
67
+ end
68
+ end
69
+
70
+ @partitions = partition_filter.partitions
71
+ @partition_filter = partition_filter
72
+ init_timeout(policy)
73
+ end
74
+
75
+ def assign_partitions_to_nodes(cluster, namespace)
76
+ list = []
77
+
78
+ pmap = cluster.partitions
79
+ replica_array = pmap[namespace]
80
+ raise Aerospike::Exceptions::InvalidNamespace("namespace not found in the partition map") if !replica_array
81
+
82
+ master = (replica_array.get)[0]
83
+ master = master.get
84
+
85
+ @partitions.each do |part|
86
+ if part&.retry
87
+ node = master[part.id]
88
+
89
+ unless node
90
+ raise Exceptions::Aerospike.new(Aerospike::ResultCode::INVALID_NAMESPACE, "Invalid Partition Id #{part.id} for namespace `#{namespace}` in Partition Scan")
91
+ end
92
+
93
+ part.retry = false
94
+
95
+
96
+ # Use node name to check for single node equality because
97
+ # partition map may be in transitional state between
98
+ # the old and new node with the same name.
99
+ next if @node_filter && @node_filter.name != node.name
100
+
101
+ np = find_node(list, node)
102
+
103
+ unless np
104
+ # If the partition map is in a transitional state, multiple
105
+ # node_partitions instances (each with different partitions)
106
+ # may be created for a single node.
107
+ np = NodePartitions.new(node)
108
+ list << np
109
+ end
110
+ np.add_partition(part)
111
+ end
112
+ end
113
+
114
+ if @max_records.positive?
115
+ # Distribute max_records across nodes.
116
+ node_size = list.length
117
+
118
+ if @max_records < node_size
119
+ # Only include nodes that have at least 1 record requested.
120
+ node_size = @max_records
121
+ list = list[0...node_size]
122
+ end
123
+
124
+ max = 0
125
+ max = @max_records / node_size if node_size.positive?
126
+ rem = @max_records - (max * node_size)
127
+
128
+ list[0...node_size].each_with_index do |np, i|
129
+ np.record_max = (i < rem ? max + 1 : max)
130
+ end
131
+ end
132
+
133
+ @node_partitions_list = list
134
+ list
135
+ end
136
+
137
+ def init_timeout(policy)
138
+ @sleep_between_retries = policy.sleep_between_retries
139
+ @socket_timeout = policy.socket_timeout
140
+ @total_timeout = policy.timeout
141
+ if @total_timeout.positive?
142
+ @deadline = Time.now + @total_timeout
143
+ if !@socket_timeout || @socket_timeout > @total_timeout
144
+ @socket_timeout = @total_timeout
145
+ end
146
+ end
147
+ end
148
+
149
+ def init_partitions(policy, partition_count, digest)
150
+ parts_all = Array.new(partition_count)
151
+
152
+ (0...partition_count).each do |i|
153
+ parts_all[i] = Aerospike::PartitionStatus.new(@partition_begin + i)
154
+ end
155
+
156
+ parts_all[0].digest = digest if digest
157
+
158
+ @sleep_between_retries = policy.sleep_between_retries
159
+ @socket_timeout = policy.socket_timeout
160
+ @total_timeout = policy.timeout
161
+
162
+ if @total_timeout.positive?
163
+ @deadline = Time.now + @total_timeout
164
+
165
+ if @socket_timeout == 0 || @socket_timeout > @total_timeout
166
+ @socket_timeout = @total_timeout
167
+ end
168
+ end
169
+
170
+ parts_all
171
+ end
172
+
173
+ attr_writer :sleep_between_retries
174
+
175
+
176
+ def find_node(list, node)
177
+ list.each do |node_partition|
178
+ # Use pointer equality for performance.
179
+ return node_partition if node_partition.node == node
180
+ end
181
+ nil
182
+ end
183
+
184
+ def partition_unavailable(node_partitions, partition_id)
185
+ @partitions[partition_id-@partition_begin].retry = true
186
+ node_partitions.parts_unavailable+=1
187
+ end
188
+
189
+ def set_digest(node_partitions, key)
190
+ partition_id = key.partition_id
191
+ @partitions[partition_id-@partition_begin].digest = key.digest
192
+ node_partitions.record_count+=1
193
+ end
194
+
195
+ def set_last(node_partitions, key, bval)
196
+ partition_id = key.partition_id()
197
+ if partition_id-@partition_begin < 0
198
+ raise "key.partition_id: #{@partition_id}, partition_begin: #{@partition_begin}"
199
+ end
200
+ ps = @partitions[partition_id-@partition_begin]
201
+ ps.digest = key.digest
202
+ ps.bval = bval
203
+ node_partitions.record_count+=1
204
+ end
205
+
206
+ def complete?(cluster, policy)
207
+ record_count = 0
208
+ parts_unavailable = 0
209
+
210
+ @node_partitions_list.each do |np|
211
+ record_count += np.record_count
212
+ parts_unavailable += np.parts_unavailable
213
+ end
214
+
215
+ if parts_unavailable == 0
216
+ if @max_records <= 0
217
+ @partition_filter&.done = true
218
+ else
219
+ if cluster.supports_partition_query.get()
220
+ done = true
221
+
222
+ @node_partitions_list.each do |np|
223
+ if np.record_count >= np.record_max
224
+ mark_retry(np)
225
+ done = false
226
+ end
227
+ end
228
+
229
+ @partition_filter&.done = done
230
+ else
231
+ # Server version >= 6.0 will return all records for each node up to
232
+ # that node's max. If node's record count reached max, there stilthen
233
+ # may be records available for that node.
234
+ @node_partitions_list.each do |np|
235
+ mark_retry(np) if np.record_count > 0
236
+ end
237
+ # Servers version < 6.0 can return less records than max and still
238
+ # have more records for each node, so the node is only done if nthen
239
+ # records were retrieved for that node.
240
+
241
+ @partition_filter&.done = (record_count == 0)
242
+ end
243
+ end
244
+ return true
245
+ end
246
+
247
+ return true if @max_records&.positive? && record_count >= @max_records
248
+
249
+ # Check if limits have been reached
250
+ if policy.max_retries.positive? && @iteration > policy.max_retries
251
+ raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::MAX_RETRIES_EXCEEDED, "Max retries exceeded: #{policy.max_retries}")
252
+ end
253
+
254
+ if policy.total_timeout > 0
255
+ # Check for total timeout.
256
+ remaining = @deadline - Time.now - @sleep_between_retries
257
+
258
+ raise Aerospike::Exceptions::Timeout.new(policy.totle_timeout, @iteration) if remaining <= 0
259
+
260
+ if remaining < @total_timeout
261
+ @total_timeout = remaining
262
+
263
+ if @socket_timeout > @total_timeout
264
+ @socket_timeout = @total_timeout
265
+ end
266
+ end
267
+ end
268
+
269
+ # Prepare for next iteration.
270
+ if @max_records > 0
271
+ @max_records -= record_count
272
+ end
273
+ @iteration+=1
274
+ false
275
+ end
276
+
277
+ def should_retry(node_partitions, err)
278
+ case err
279
+ when Aerospike::Exceptions::Aerospike
280
+ case err.result_code
281
+ when Aerospike::ResultCode::TIMEOUT,
282
+ Aerospike::ResultCode::NETWORK_ERROR,
283
+ Aerospike::ResultCode::SERVER_NOT_AVAILABLE,
284
+ Aerospike::ResultCode::INDEX_NOTFOUND
285
+ mark_retry(node_partitions)
286
+ node_partitions.parts_unavailable = node_partitions.parts_full.length + node_partitions.parts_partial.length
287
+ true
288
+ end
289
+ else
290
+ false
291
+ end
292
+ end
293
+
294
+ def mark_retry(node_partitions)
295
+ node_partitions.parts_full.each do |ps|
296
+ ps.retry = true
297
+ end
298
+
299
+ node_partitions.parts_partial.each do |ps|
300
+ ps.retry = true
301
+ end
302
+ end
303
+
304
+ def to_s
305
+ sb = StringIO.new
306
+ @partitions.each_with_index do |ps, i|
307
+ sb << ps.to_s
308
+ sb << if (i+1)%16 == 0
309
+ "\n"
310
+ else
311
+ "\t"
312
+ end
313
+ end
314
+ sb.string
315
+ end
316
+
317
+ private
318
+
319
+ def init_for_nodes(policy, nodes)
320
+ ppn = Aerospike::Node::PARTITIONS / nodes.length
321
+ ppn += ppn / 4
322
+
323
+ @partition_begin = 0
324
+ @node_capacity = nodes.length
325
+ @node_filter = nil
326
+ @partitions_capacity = ppn
327
+ @max_records = policy.max_records
328
+ @iteration = 1
329
+
330
+ @partitions = init_partitions(policy, Aerospike::Node::PARTITIONS, nil)
331
+ init_timeout(policy)
332
+ end
333
+
334
+ def init_for_node(policy, node)
335
+ @partition_begin = 0
336
+ @node_capacity = 1
337
+ @node_filter = node
338
+ @partitions_capacity = Aerospike::Node::PARTITIONS
339
+ @max_records = policy.max_records
340
+ @iteration = 1
341
+
342
+ @partitions = init_partitions(policy, Aerospike::Node::PARTITIONS, nil)
343
+ init_timeout(policy)
344
+ end
345
+
346
+ end
347
+ end
@@ -23,7 +23,7 @@ module Aerospike
23
23
 
24
24
  class ScanCommand < StreamCommand #:nodoc:
25
25
 
26
- def initialize(node, policy, namespace, set_name, bin_names, recordset, partitions)
26
+ def initialize(node, policy, namespace, set_name, bin_names, recordset, node_partitions)
27
27
  super(node)
28
28
 
29
29
  @policy = policy
@@ -31,11 +31,11 @@ module Aerospike
31
31
  @set_name = set_name
32
32
  @bin_names = bin_names
33
33
  @recordset = recordset
34
- @partitions = partitions
34
+ @node_partitions = node_partitions
35
35
  end
36
36
 
37
37
  def write_buffer
38
- set_scan(@policy, @namespace, @set_name, @bin_names, @partitions)
38
+ set_scan(@policy, @namespace, @set_name, @bin_names, @node_partitions)
39
39
  end
40
40
 
41
41
  end # class
@@ -0,0 +1,69 @@
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 ScanExecutor # :nodoc:
20
+
21
+ def self.scan_partitions(policy, cluster, tracker, namespace, set_name, recordset, bin_names = nil)
22
+ interval = policy.sleep_between_retries
23
+
24
+ should_retry = false
25
+
26
+ loop do
27
+ list = tracker.assign_partitions_to_nodes(cluster, namespace)
28
+
29
+ if policy.concurrent_nodes
30
+ threads = []
31
+ # Use a thread per node
32
+ list.each do |node_partition|
33
+
34
+ threads << Thread.new do
35
+ Thread.current.abort_on_exception = true
36
+ command = ScanPartitionCommand.new(policy, tracker, node_partition, namespace, set_name, bin_names, recordset)
37
+ begin
38
+ command.execute
39
+ rescue => e
40
+ should_retry ||= command.should_retry(e)
41
+ Aerospike.logger.error(e.backtrace.join("\n")) unless e == SCAN_TERMINATED_EXCEPTION
42
+ end
43
+ end
44
+ end
45
+ threads.each(&:join)
46
+ else
47
+ # Use a single thread for all nodes for all node
48
+ list.each do |node_partition|
49
+ command = ScanPartitionCommand.new(policy, tracker, node_partition, namespace, set_name, bin_names, recordset)
50
+ begin
51
+ command.execute
52
+ rescue => e
53
+ should_retry ||= command.should_retry(e)
54
+ Aerospike.logger.error(e.backtrace.join("\n")) unless e == SCAN_TERMINATED_EXCEPTION
55
+ end
56
+ end
57
+ end
58
+
59
+ if tracker.complete?(@cluster, policy) || !should_retry
60
+ recordset.thread_finished
61
+ return
62
+ end
63
+ sleep(interval) if policy.sleep_between_retries > 0
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
+ #
4
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
+ # license agreements.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
8
+ # use this file except in compliance with the License. You may obtain a copy of
9
+ # the License at http:#www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations under
15
+ # the License.
16
+
17
+ require 'aerospike/query/stream_command'
18
+ require 'aerospike/query/recordset'
19
+
20
+ module Aerospike
21
+
22
+ private
23
+
24
+ class ScanPartitionCommand < StreamCommand #:nodoc:
25
+
26
+ def initialize(policy, tracker, node_partitions, namespace, set_name, bin_names, recordset)
27
+ super(node_partitions.node)
28
+
29
+ @policy = policy
30
+ @namespace = namespace
31
+ @set_name = set_name
32
+ @bin_names = bin_names
33
+ @recordset = recordset
34
+ @node_partitions = node_partitions
35
+ @tracker = tracker
36
+ end
37
+
38
+ def write_buffer
39
+ set_scan(@policy, @namespace, @set_name, @bin_names, @node_partitions)
40
+ end
41
+
42
+ def should_retry(e)
43
+ # !! converts nil to false
44
+ !!@tracker&.should_retry(@node_partitions, e)
45
+ end
46
+
47
+ end # class
48
+
49
+ end # module
@@ -49,7 +49,7 @@ module Aerospike
49
49
  # This method is redundant because PredExp can now be set in the base Policy for
50
50
  # any transaction (including queries).
51
51
  #
52
- # NOTE : Policy.predexp takes precedence to this value. This value will be
52
+ # NOTE : Policy.predexp takes precedence to this value. This value will be
53
53
  # deprecated in the future.
54
54
  @predexp = nil
55
55
 
@@ -39,6 +39,8 @@ module Aerospike
39
39
  case result_code
40
40
  when Aerospike::ResultCode::OK
41
41
  # noop
42
+ when Aerospike::ResultCode::PARTITION_UNAVAILABLE
43
+ # noop
42
44
  when Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
43
45
  # consume the rest of the input buffer from the socket
44
46
  read_bytes(receive_size - @data_offset) if @data_offset < receive_size
@@ -59,7 +61,16 @@ module Aerospike
59
61
  key = parse_key(field_count)
60
62
 
61
63
  # If cmd is the end marker of the response, do not proceed further
62
- return true if (info3 & INFO3_PARTITION_DONE) != 0
64
+ if (info3 & INFO3_PARTITION_DONE) != 0
65
+ # When an error code is received, mark partition as unavailable
66
+ # for the current round. Unavailable partitions will be retried
67
+ # in the next round. Generation is overloaded as partitionId.
68
+ if result_code != 0
69
+ @tracker&.partition_unavailable(@node_partitions, generation)
70
+ end
71
+
72
+ next
73
+ end
63
74
 
64
75
  if result_code == 0
65
76
  if @recordset.active?
@@ -68,6 +79,8 @@ module Aerospike
68
79
  expn = @recordset.is_scan? ? SCAN_TERMINATED_EXCEPTION : QUERY_TERMINATED_EXCEPTION
69
80
  raise expn
70
81
  end
82
+
83
+ @tracker&.set_last(@node_partitions, key, key.bval)
71
84
  end
72
85
  end # while
73
86
 
@@ -20,6 +20,42 @@ module Aerospike
20
20
 
21
21
  attr_reader :code
22
22
 
23
+ # One or more keys failed in a batch.
24
+ BATCH_FAILED = -20
25
+
26
+ # No response was received from the server.
27
+ NO_RESPONSE = -19
28
+
29
+ # A network error. Checked the wrapped error for detail.
30
+ NETWORK_ERROR = -18
31
+
32
+ # A common, none-aerospike error. Checked the wrapped error for detail.
33
+ COMMON_ERROR = -17
34
+
35
+ # Max retries limit reached.
36
+ MAX_RETRIES_EXCEEDED = -16
37
+
38
+ # Max errors limit reached.
39
+ MAX_ERROR_RATE = -15
40
+
41
+ # Requested Rack for node/namespace was not defined in the cluster.
42
+ RACK_NOT_DEFINED = -13
43
+
44
+ # Cluster has an invalid partition map, usually due to bad configuration.
45
+ INVALID_CLUSTER_PARTITION_MAP = -12
46
+
47
+ # Server is not accepting requests.
48
+ SERVER_NOT_AVAILABLE = -11
49
+
50
+ # Cluster Name does not match the ClientPolicy.ClusterName value.
51
+ CLUSTER_NAME_MISMATCH_ERROR = -10
52
+
53
+ # Recordset has already been closed or cancelled
54
+ RECORDSET_CLOSED = -9
55
+
56
+ # There were no connections available to the node in the pool, and the pool was limited
57
+ NO_AVAILABLE_CONNECTIONS_TO_NODE = -8
58
+
23
59
  # Value type not supported by Aerospike server
24
60
  TYPE_NOT_SUPPORTED = -7
25
61
 
@@ -76,8 +112,8 @@ module Aerospike
76
112
  # XDS product is not available.
77
113
  NO_XDS = 10
78
114
 
79
- # Server is not accepting requests.
80
- SERVER_NOT_AVAILABLE = 11
115
+ # Partition is unavailable.
116
+ PARTITION_UNAVAILABLE = 11
81
117
 
82
118
  # Operation is not supported with configured bin type (single-bin or
83
119
  # multi-bin).
@@ -265,6 +301,45 @@ module Aerospike
265
301
 
266
302
  def self.message(code)
267
303
  case code
304
+ when BATCH_FAILED
305
+ "one or more keys failed in a batch"
306
+
307
+ when NO_RESPONSE
308
+ "no response was received from the server"
309
+
310
+ when NETWORK_ERROR
311
+ "network error. Checked the wrapped error for detail"
312
+
313
+ when COMMON_ERROR
314
+ "common, none-aerospike error. Checked the wrapped error for detail"
315
+
316
+ when MAX_RETRIES_EXCEEDED
317
+ "Max retries exceeded"
318
+
319
+ when MAX_ERROR_RATE
320
+ "Max errors limit reached for node"
321
+
322
+ when RACK_NOT_DEFINED
323
+ "Requested Rack for node/namespace was not defined in the cluster."
324
+
325
+ when INVALID_CLUSTER_PARTITION_MAP
326
+ "Cluster has an invalid partition map, usually due to bad configuration."
327
+
328
+ when SERVER_NOT_AVAILABLE
329
+ "Server is not accepting requests."
330
+
331
+ when CLUSTER_NAME_MISMATCH_ERROR
332
+ "Cluster Name does not match the ClientPolicy.ClusterName value"
333
+
334
+ when RECORDSET_CLOSED
335
+ "Recordset has already been closed or cancelled."
336
+
337
+ when NO_AVAILABLE_CONNECTIONS_TO_NODE
338
+ "No available connections to the node. Connection Pool was empty, and limited to certain number of connections."
339
+
340
+ when TYPE_NOT_SUPPORTED
341
+ "Type cannot be converted to Value Type."
342
+
268
343
  when COMMAND_REJECTED
269
344
  "Command rejected"
270
345
 
@@ -316,8 +391,8 @@ module Aerospike
316
391
  when NO_XDS
317
392
  "XDS not available"
318
393
 
319
- when SERVER_NOT_AVAILABLE
320
- "Server not available"
394
+ when PARTITION_UNAVAILABLE
395
+ "Partition not available"
321
396
 
322
397
  when BIN_TYPE_ERROR
323
398
  "Bin type error"
@@ -49,7 +49,7 @@ module Aerospike
49
49
  def to_s
50
50
  "Role [name=#{@name}, privileges=#{@privileges}, allowlist=#{@allowlist}, readQuota=#{@read_quota}, writeQuota=#{@write_quota}]";
51
51
  end
52
-
52
+
53
53
  end # class
54
54
 
55
- end # module
55
+ end # module
@@ -70,7 +70,7 @@ module Aerospike
70
70
 
71
71
  case status
72
72
  when 'ABORTED'
73
- raise raise Aerospike::Exceptions::QueryTerminated
73
+ raise Aerospike::Exceptions::QueryTerminated
74
74
  when 'IN PROGRESS'
75
75
  return false
76
76
  when 'DONE'
@@ -82,4 +82,4 @@ module Aerospike
82
82
  end
83
83
 
84
84
  end
85
- end
85
+ end
@@ -25,7 +25,7 @@ module Aerospike
25
25
 
26
26
  class IndexTask < Task
27
27
 
28
- MATCHER = /.*load_pct=(?<load_pct>\d+(\.\d+)?).*/
28
+ MATCHER = /.*load_pct=(?<load_pct>\d+(\.\d+)?).*/.freeze
29
29
 
30
30
  def initialize(cluster, namespace, index_name, done=false)
31
31
  super(cluster, done)
@@ -52,4 +52,4 @@ module Aerospike
52
52
 
53
53
  end
54
54
 
55
- end
55
+ end