aerospike 4.0.0 → 4.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cbbb3eae452fb9c1bbe7a0a99e7505b4fa774396b9591edc80ae707abb9896e0
4
- data.tar.gz: cd2bf9f22247dbc8f49581507b17f6347edf0a6f46a0c307f87eae45c3bf775b
3
+ metadata.gz: e3f436fbfb9e52e5bc36f953a2392559ca2455c8b1f7b8e2749511c6eb6bef62
4
+ data.tar.gz: '0947b6de2c480f3cbeada2da92c9394142bb376bcc4c4fd216eca2970b59e112'
5
5
  SHA512:
6
- metadata.gz: 88c12b118fcdf74f170a06ac3158b47f3e81076ee7c851d5ca06ea80b82d2b668c2df6588444e22c011dd43cbddce6586ecaaa30c895e54cefd47573e75b55ac
7
- data.tar.gz: ffc436ee1b5696765fdc8ab00f87ef0c6e33afea3ae3ddc2d63dcd01fed91e62f3ddb8b109acf9fae65bc5bcabd9c1f36af8c60b87e86fb25c8b1528ed5e926b
6
+ metadata.gz: 6322255e49d66ca929b88ffcb38110ae0d2f40cb8a6ba9b616291c9befb61f41c6b2a00ac5d01afa7ca4233eb748f2a7245dcd41d87394022847617f039acf96
7
+ data.tar.gz: a928ce8356bf8d36377bd165e5939dad19f3a052285f181e2b7a178528f1d66f47de57d4f729578453451cc7d18c70f341667e0f681f21fb0b666519425019fb
data/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [4.1.0] 2024-10-22
6
+
7
+ - **New Features**
8
+ - [CLIENT-2833] Support `Policy#ReadTouchTtlPercent`.
9
+ - [CLIENT-2826] Support `QueryDuration` in `QueryPolicy#ExpectedDuration`.
10
+ - [CLIENT-3103] Support `XDR_KEY_BUSY`.
11
+
12
+ - **Fixes**
13
+ - [CLIENT-3144] Various fixes. PR #132 and #133 Thanks to [Igor Pstyga](https://github.com/opti)
14
+ - Fix `BatchRead` for multiple records with operations.
15
+ - Use correct namespace for the `MapReturnType`.
16
+ - `BatchRead` with operations would throw an exception.
17
+ - Fix a test with invalid map key in Server v7.1.
18
+
5
19
  ## [4.0.0] 2024-08-14
6
20
 
7
21
  - **New Features**
@@ -75,7 +75,7 @@ module Aerospike
75
75
  @write_attr = 0
76
76
  @info_attr = 0
77
77
 
78
- @expiration = 0
78
+ @expiration = rp.read_touch_ttl_percent
79
79
  @generation = 0
80
80
  @has_write = false
81
81
  @send_key = false
@@ -88,7 +88,7 @@ module Aerospike
88
88
  @write_attr = 0
89
89
  @info_attr = 0
90
90
 
91
- @expiration = 0
91
+ @expiration = rp.read_touch_ttl_percent
92
92
  @generation = 0
93
93
  @has_write = false
94
94
  @send_key = false
@@ -68,7 +68,7 @@ module Aerospike
68
68
  # For internal use only.
69
69
  def ==(other) # :nodoc:
70
70
  other && other.instance_of?(self.class) &&
71
- @bin_names.sort == other.bin_names.sort && @ops.sort == other.ops.sort &&
71
+ @bin_names&.sort == other.bin_names&.sort && @ops == other.ops &&
72
72
  @policy == other.policy && @read_all_bins == other.read_all_bins
73
73
  end
74
74
 
@@ -88,7 +88,7 @@ module Aerospike
88
88
  raise AerospikeException.new(ResultCode::PARAMETER_ERROR, "Write operations not allowed in batch read")
89
89
  end
90
90
  size += op.bin_name.bytesize + Aerospike::OPERATION_HEADER_SIZE
91
- size += op.value.estimate_size
91
+ size += op.bin_value.estimate_size
92
92
  end
93
93
 
94
94
  size
@@ -62,7 +62,7 @@ module Aerospike
62
62
  end
63
63
  end
64
64
  size_buffer
65
- write_header_read(policy, read_attr | INFO1_BATCH, 0, field_count, 0)
65
+ write_header_read(policy, read_attr | INFO1_BATCH, 0, 0, field_count, 0)
66
66
 
67
67
  write_filter_exp(@policy.filter_exp, exp_size)
68
68
 
@@ -92,7 +92,7 @@ module Aerospike
92
92
  if record.bin_names&.length&.> 0
93
93
  write_batch_bin_names(key, record.bin_names, attr, attr.filter_exp)
94
94
  elsif record.ops&.length&.> 0
95
- attr.adjust_read(br.ops)
95
+ attr.adjust_read(record.ops)
96
96
  write_batch_operations(key, record.ops, attr, attr.filter_exp)
97
97
  else
98
98
  attr.adjust_read_all_bins(record.read_all_bins)
@@ -58,7 +58,8 @@ module Aerospike
58
58
  INFO2_DURABLE_DELETE = Integer(1 << 4)
59
59
  # Create only. Fail if record already exists.
60
60
  INFO2_CREATE_ONLY = Integer(1 << 5)
61
-
61
+ # Treat as long query, but relax read consistency.
62
+ INFO2_RELAX_AP_LONG_QUERY = (1 << 6)
62
63
  # Return a result for every operation.
63
64
  INFO2_RESPOND_ALL_OPS = Integer(1 << 7)
64
65
 
@@ -195,7 +196,7 @@ module Aerospike
195
196
  field_count += 1 if exp_size > 0
196
197
 
197
198
  size_buffer
198
- write_header_read(policy, INFO1_READ | INFO1_GET_ALL, 0, field_count, 0)
199
+ write_header_read(policy, INFO1_READ | INFO1_GET_ALL, 0, 0, field_count, 0)
199
200
  write_key(key)
200
201
  write_filter_exp(@policy.filter_exp, exp_size)
201
202
  end_cmd
@@ -220,7 +221,7 @@ module Aerospike
220
221
  attr |= INFO1_GET_ALL
221
222
  end
222
223
 
223
- write_header_read(policy, attr, 0, field_count, bin_names.length)
224
+ write_header_read(policy, attr, 0, 0, field_count, bin_names.length)
224
225
  write_key(key)
225
226
  write_filter_exp(@policy.filter_exp, exp_size)
226
227
 
@@ -269,7 +270,7 @@ module Aerospike
269
270
 
270
271
  size_buffer
271
272
 
272
- write_header_read_write(policy, args.read_attr, args.write_attr, field_count, args.operations.length)
273
+ write_header_read_write(policy, args, field_count)
273
274
  write_key(key, policy)
274
275
  write_filter_exp(policy.filter_exp, exp_size)
275
276
 
@@ -377,7 +378,7 @@ module Aerospike
377
378
  operation_count = bin_names.length
378
379
  end
379
380
 
380
- write_header_read(policy, read_attr, info_attr, field_count, operation_count)
381
+ write_header_read(policy, read_attr, 0, info_attr, field_count, operation_count)
381
382
 
382
383
  if namespace
383
384
  write_field_string(namespace, Aerospike::FieldType::NAMESPACE)
@@ -591,10 +592,16 @@ module Aerospike
591
592
  write_header_write(policy, INFO2_WRITE, field_count, operation_count)
592
593
  else
593
594
  read_attr = INFO1_READ
595
+ write_attr = 0
596
+
594
597
  read_attr |= INFO1_NOBINDATA unless policy.include_bin_data
595
- read_attr |= INFO1_SHORT_QUERY if policy.short_query
598
+ if policy.short_query || policy.expected_duration == QueryDuration::SHORT
599
+ read_attr |= INFO1_SHORT_QUERY
600
+ elsif policy.expected_duration == QueryDuration::LONG_RELAX_AP
601
+ write_attr |= INFO2_RELAX_AP_LONG_QUERY
602
+ end
596
603
  info_attr = INFO3_PARTITION_DONE if is_new
597
- write_header_read(policy, read_attr, info_attr, field_count, operation_count)
604
+ write_header_read(policy, read_attr, write_attr, info_attr, field_count, operation_count)
598
605
  end
599
606
 
600
607
 
@@ -903,10 +910,14 @@ module Aerospike
903
910
  end
904
911
 
905
912
  # Header write for write operations.
906
- def write_header_read_write(policy, read_attr, write_attr, field_count, operation_count)
913
+ def write_header_read_write(policy, args, field_count)
907
914
  # Set flags.
908
915
  generation = Integer(0)
916
+ ttl = args.has_write ? policy.expiration : policy.read_touch_ttl_percent
917
+ read_attr = args.read_attr
918
+ write_attr = args.write_attr
909
919
  info_attr = Integer(0)
920
+ operation_count = args.operations.length
910
921
 
911
922
  case policy.record_exists_action
912
923
  when Aerospike::RecordExistsAction::UPDATE
@@ -942,7 +953,7 @@ module Aerospike
942
953
  @data_buffer.write_byte(0, 12) # unused
943
954
  @data_buffer.write_byte(0, 13) # clear the result code
944
955
  @data_buffer.write_uint32(generation, 14)
945
- @data_buffer.write_uint32(policy.ttl, 18)
956
+ @data_buffer.write_uint32(ttl, 18)
946
957
 
947
958
  # Initialize timeout. It will be written later.
948
959
  @data_buffer.write_byte(0, 22)
@@ -956,18 +967,19 @@ module Aerospike
956
967
  @data_offset = MSG_TOTAL_HEADER_SIZE
957
968
  end
958
969
 
959
- def write_header_read(policy, read_attr, info_attr, field_count, operation_count)
970
+ def write_header_read(policy, read_attr, write_attr, info_attr, field_count, operation_count)
960
971
  read_attr |= INFO1_COMPRESS_RESPONSE if policy.use_compression
961
972
  #TODO: Add SC Mode
962
973
 
963
974
  @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length.
964
975
  @data_buffer.write_byte(read_attr, 9)
965
- @data_buffer.write_byte(0, 10)
976
+ @data_buffer.write_byte(write_attr, 10)
966
977
  @data_buffer.write_byte(info_attr, 11)
967
978
 
968
- (12...22).each { |i| @data_buffer.write_byte(0, i) }
979
+ (12...18).each { |i| @data_buffer.write_byte(0, i) }
969
980
 
970
981
  # Initialize timeout. It will be written later.
982
+ @data_buffer.write_int32(policy.read_touch_ttl_percent, 18)
971
983
  @data_buffer.write_byte(0, 22)
972
984
  @data_buffer.write_byte(0, 23)
973
985
  @data_buffer.write_byte(0, 24)
@@ -988,9 +1000,10 @@ module Aerospike
988
1000
  @data_buffer.write_byte(0, 10)
989
1001
  @data_buffer.write_byte(info_attr, 11)
990
1002
 
991
- (12...22).each { |i| @data_buffer.write_byte(0, i) }
1003
+ (12...18).each { |i| @data_buffer.write_byte(0, i) }
992
1004
 
993
1005
  # Initialize timeout. It will be written later.
1006
+ @data_buffer.write_int32(policy.read_touch_ttl_percent, 18)
994
1007
  @data_buffer.write_byte(0, 22)
995
1008
  @data_buffer.write_byte(0, 23)
996
1009
  @data_buffer.write_byte(0, 24)
@@ -476,21 +476,21 @@ module Aerospike
476
476
  def self.get_value_type(return_type)
477
477
  t = return_type & ~CDT::MapReturnType::INVERTED
478
478
  case t
479
- when MapReturnType::INDEX, MapReturnType::REVERSE_INDEX, MapReturnType::RANK, MapReturnType::REVERSE_RANK
479
+ when CDT::MapReturnType::INDEX, CDT::MapReturnType::REVERSE_INDEX, CDT::MapReturnType::RANK, CDT::MapReturnType::REVERSE_RANK
480
480
  # This method only called from expressions that can return multiple integers (ie list).
481
481
  Exp::Type::LIST
482
482
 
483
- when MapReturnType::COUNT
483
+ when CDT::MapReturnType::COUNT
484
484
  Exp::Type::INT
485
485
 
486
- when MapReturnType::KEY, MapReturnType::VALUE
486
+ when CDT::MapReturnType::KEY, CDT::MapReturnType::VALUE
487
487
  # This method only called from expressions that can return multiple objects (ie list).
488
488
  Exp::Type::LIST
489
489
 
490
- when MapReturnType::KEY_VALUE, MapReturnType::ORDERED_MAP, MapReturnType::UNORDERED_MAP
490
+ when CDT::MapReturnType::KEY_VALUE, CDT::MapReturnType::ORDERED_MAP, CDT::MapReturnType::UNORDERED_MAP
491
491
  Exp::Type::MAP
492
492
 
493
- when MapReturnType::EXISTS
493
+ when CDT::MapReturnType::EXISTS
494
494
  Exp::Type::BOOL
495
495
 
496
496
  else
@@ -20,7 +20,7 @@ module Aerospike
20
20
  # Policy attributes used in batch read commands.
21
21
  class BatchReadPolicy
22
22
 
23
- attr_accessor :filter_exp
23
+ attr_accessor :filter_exp, :read_touch_ttl_percent
24
24
 
25
25
  def initialize(opt={})
26
26
  # Optional expression filter. If filter_exp exists and evaluates to false, the specific batch key
@@ -33,6 +33,23 @@ module Aerospike
33
33
  #
34
34
  # Default: nil
35
35
  @filter_exp = opt[:filter_exp]
36
+
37
+ # Determines how record TTL (time to live) is affected on reads. When enabled, the server can
38
+ # efficiently operate as a read-based LRU cache where the least recently used records are expired.
39
+ # The value is expressed as a percentage of the TTL sent on the most recent write such that a read
40
+ # within this interval of the record’s end of life will generate a touch.
41
+ #
42
+ # For example, if the most recent write had a TTL of 10 hours and read_touch_ttl_percent is set to
43
+ # 80, the next read within 8 hours of the record's end of life (equivalent to 2 hours after the most
44
+ # recent write) will result in a touch, resetting the TTL to another 10 hours.
45
+ #
46
+ # Values:
47
+ #
48
+ # 0 : Use server config default-read-touch-ttl-pct for the record's namespace/set.
49
+ # -1 : Do not reset record TTL on reads.
50
+ # 1 - 100 : Reset record TTL on reads when within this percentage of the most recent write TTL.
51
+ # Default: 0
52
+ @read_touch_ttl_percent = opt[:read_touch_ttl_percent] || 0
36
53
  end
37
54
  end
38
55
  end
@@ -22,7 +22,7 @@ module Aerospike
22
22
  # Container object for client policy command.
23
23
  class Policy
24
24
  attr_accessor :filter_exp, :priority, :timeout, :max_retries, :sleep_between_retries, :consistency_level,
25
- :fail_on_filtered_out, :replica, :use_compression, :socket_timeout
25
+ :fail_on_filtered_out, :replica, :use_compression, :socket_timeout, :read_touch_ttl_percent
26
26
 
27
27
  alias total_timeout timeout
28
28
  alias total_timeout= timeout=
@@ -95,6 +95,23 @@ module Aerospike
95
95
  # has not yet been exceeded.
96
96
  @max_retries = opt[:max_retries] || 2
97
97
 
98
+ # Determines how record TTL (time to live) is affected on reads. When enabled, the server can
99
+ # efficiently operate as a read-based LRU cache where the least recently used records are expired.
100
+ # The value is expressed as a percentage of the TTL sent on the most recent write such that a read
101
+ # within this interval of the record’s end of life will generate a touch.
102
+ #
103
+ # For example, if the most recent write had a TTL of 10 hours and read_touch_ttl_percent is set to
104
+ # 80, the next read within 8 hours of the record's end of life (equivalent to 2 hours after the most
105
+ # recent write) will result in a touch, resetting the TTL to another 10 hours.
106
+ #
107
+ # Values:
108
+ #
109
+ # 0 : Use server config default-read-touch-ttl-pct for the record's namespace/set.
110
+ # -1 : Do not reset record TTL on reads.
111
+ # 1 - 100 : Reset record TTL on reads when within this percentage of the most recent write TTL.
112
+ # Default: 0
113
+ @read_touch_ttl_percent = opt[:read_touch_ttl_percent] || 0
114
+
98
115
  # Duration to sleep between retries if a transaction fails and the
99
116
  # timeout was not exceeded. Enter zero to skip sleep.
100
117
  @sleep_between_retries = opt[:sleep_between_retries] || 0.5
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ # Copyright 2014-2024 Aerospike, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http:#www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ module Aerospike
17
+
18
+ # Defines the expected query duration. The server treats the query in different ways depending on the expected duration.
19
+ # This enum is ignored for aggregation queries, background queries and server versions < 6.0.
20
+ module QueryDuration
21
+
22
+ # The query is expected to return more than 100 records per node. The server optimizes for a large record set in
23
+ # the following ways:
24
+ #
25
+ # Allow query to be run in multiple threads using the server's query threading configuration.
26
+ # Do not relax read consistency for AP namespaces.
27
+ # Add the query to the server's query monitor.
28
+ # Do not add the overall latency to the server's latency histogram.
29
+ # Do not allow server timeouts.
30
+ LONG = 0
31
+
32
+ # The query is expected to return less than 100 records per node. The server optimizes for a small record set in
33
+ # the following ways:
34
+ # Always run the query in one thread and ignore the server's query threading configuration.
35
+ # Allow query to be inlined directly on the server's service thread.
36
+ # Relax read consistency for AP namespaces.
37
+ # Do not add the query to the server's query monitor.
38
+ # Add the overall latency to the server's latency histogram.
39
+ # Allow server timeouts. The default server timeout for a short query is 1 second.
40
+ SHORT = 1
41
+
42
+ # Treat query as a LONG query, but relax read consistency for AP namespaces.
43
+ # This value is treated exactly like LONG for server versions < 7.1.
44
+ LONG_RELAX_AP = 2
45
+
46
+ end # module
47
+
48
+ end # module
@@ -15,6 +15,7 @@
15
15
  # License for the specific language governing permissions and limitations under
16
16
  # the License.
17
17
 
18
+ require 'aerospike/policy/query_duration'
18
19
  require 'aerospike/policy/policy'
19
20
 
20
21
  module Aerospike
@@ -22,16 +23,10 @@ module Aerospike
22
23
  # Container object for query policy command.
23
24
  class QueryPolicy < Policy
24
25
 
25
- attr_accessor :concurrent_nodes
26
- attr_accessor :max_records
27
- attr_accessor :include_bin_data
28
- attr_accessor :record_queue_size
29
- attr_accessor :records_per_second
30
- attr_accessor :socket_timeout
31
- attr_accessor :short_query
26
+ attr_accessor :concurrent_nodes, :max_records, :include_bin_data, :record_queue_size, :records_per_second, :socket_timeout, :short_query, :expected_duration
32
27
 
33
28
  def initialize(opt={})
34
- super(opt)
29
+ super
35
30
 
36
31
  # Indicates if bin data is retrieved. If false, only record digests (and
37
32
  # user keys if stored on the server) are retrieved.
@@ -74,11 +69,21 @@ module Aerospike
74
69
  # Default is 0
75
70
  @records_per_second = opt[:records_per_second] || 0
76
71
 
72
+ # Expected query duration. The server treats the query in different ways depending on the expected duration.
73
+ # This field is ignored for aggregation queries, background queries and server versions < 6.0.
74
+ #
75
+ # Default: QueryDuration::LONG
76
+ @expected_duration = opt[:expected_duration] || QueryDuration::LONG
77
+
78
+ # DEPRECATED
77
79
  # Detemine wether query expected to return less than 100 records.
78
80
  # If true, the server will optimize the query for a small record set.
79
81
  # This field is ignored for aggregation queries, background queries
80
82
  # and server versions 6.0+.
81
83
  #
84
+ # This field is deprecated and will eventually be removed. Use {expected_duration} instead.
85
+ # For backwards compatibility: If ShortQuery is true, the query is treated as a short query and
86
+ # {expected_duration} is ignored. If {short_query} is false, {expected_duration} is used as defaults to {Policy#QueryDuration#LONG}.
82
87
  # Default: false
83
88
  @short_query = opt[:short_query] ||false
84
89
 
@@ -168,6 +168,9 @@ module Aerospike
168
168
  # Write command loses conflict to XDR.
169
169
  LOST_CONFLICT = 28
170
170
 
171
+ # Write can't complete until XDR finishes shipping.
172
+ XDR_KEY_BUSY = 32
173
+
171
174
  # There are no more records left for query.
172
175
  QUERY_END = 50
173
176
 
@@ -445,6 +448,10 @@ module Aerospike
445
448
  when LOST_CONFLICT
446
449
  "Write command loses conflict to XDR."
447
450
 
451
+ # Write can't complete until XDR finishes shipping.
452
+ when XDR_KEY_BUSY
453
+ "XDR key busy"
454
+
448
455
  when QUERY_END
449
456
  "Query end"
450
457
 
@@ -580,7 +587,6 @@ module Aerospike
580
587
  else
581
588
  "ResultCode #{code} unknown in the client. Please file a github issue."
582
589
  end # case
583
-
584
590
  end
585
591
 
586
592
  end # class
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Aerospike
3
- VERSION = "4.0.0"
3
+ VERSION = "4.1.0"
4
4
  end
data/lib/aerospike.rb CHANGED
@@ -90,6 +90,7 @@ require "aerospike/cdt/bit_policy"
90
90
  require "aerospike/geo_json"
91
91
  require "aerospike/ttl"
92
92
 
93
+ require "aerospike/policy/query_duration"
93
94
  require "aerospike/policy/client_policy"
94
95
  require "aerospike/policy/priority"
95
96
  require "aerospike/policy/record_exists_action"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aerospike
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Khosrow Afroozeh
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-08-14 00:00:00.000000000 Z
13
+ date: 2024-10-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: msgpack
@@ -166,6 +166,7 @@ files:
166
166
  - lib/aerospike/policy/operate_policy.rb
167
167
  - lib/aerospike/policy/policy.rb
168
168
  - lib/aerospike/policy/priority.rb
169
+ - lib/aerospike/policy/query_duration.rb
169
170
  - lib/aerospike/policy/query_policy.rb
170
171
  - lib/aerospike/policy/record_bin_multiplicity.rb
171
172
  - lib/aerospike/policy/record_exists_action.rb