aerospike 2.26.0 → 2.28.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/lib/aerospike/client.rb +54 -2
- data/lib/aerospike/cluster.rb +9 -8
- data/lib/aerospike/command/command.rb +251 -4
- data/lib/aerospike/node.rb +12 -1
- data/lib/aerospike/policy/client_policy.rb +21 -1
- data/lib/aerospike/policy/policy.rb +15 -3
- data/lib/aerospike/policy/priority.rb +5 -1
- data/lib/aerospike/policy/scan_policy.rb +8 -3
- data/lib/aerospike/policy/write_policy.rb +8 -3
- data/lib/aerospike/query/server_command.rb +60 -0
- data/lib/aerospike/query/statement.rb +31 -18
- data/lib/aerospike/record.rb +15 -1
- data/lib/aerospike/utils/pool.rb +1 -1
- data/lib/aerospike/version.rb +1 -1
- data/lib/aerospike.rb +1 -0
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 646dcb876d7a83fab511f844216980206ee489f5cdb50f6d169a5c1893184861
|
4
|
+
data.tar.gz: f508306bf2eb681e493f1e929cab19427475f6eb7c0976b3c16b86056083b443
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51e3be1cb3b4790695eeae954e989da0df09f62deb43c9bc7995cd6c17e72804f2be1a02cf4bfcf09179a9aaff03c6d87f457bf338226d214614a6d6e3c75719
|
7
|
+
data.tar.gz: c36094ad5db6f9758131aa33258ec551a59a9fcfd72c3f106008bdcc2a8de9530d47fae6bd90a6d1459bdf772902d8770ec842c8d3cc41ef4cd1d720dd3bd430
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,19 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## [2.27.0] 2023-05-18
|
6
|
+
- **New Features**
|
7
|
+
- [CLIENT-1432] Support minimum connections in connection pools
|
8
|
+
|
9
|
+
- **Updates**
|
10
|
+
- [CLIENT-1529] Remove Policy.priority, ScanPolicy.scanPercent and ScanPolicy.failOnClusterChange
|
11
|
+
|
12
|
+
|
13
|
+
## [2.27.0] 2023-05-18
|
14
|
+
- **New Features**
|
15
|
+
- [CLIENT-1176] Support write operations in background query
|
16
|
+
|
17
|
+
|
5
18
|
## [2.26.0] 2022-12-02
|
6
19
|
|
7
20
|
- **New Features**
|
data/lib/aerospike/client.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2014-
|
1
|
+
# Copyright 2014-2023 Aerospike, Inc.
|
2
2
|
#
|
3
3
|
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
4
4
|
# license agreements.
|
@@ -225,7 +225,6 @@ module Aerospike
|
|
225
225
|
policy = create_policy(options, Policy, default_info_policy)
|
226
226
|
|
227
227
|
node = @cluster.random_node
|
228
|
-
conn = node.get_connection(policy.timeout)
|
229
228
|
|
230
229
|
if set_name && !set_name.to_s.strip.empty?
|
231
230
|
str_cmd = "truncate:namespace=#{namespace}"
|
@@ -731,6 +730,59 @@ module Aerospike
|
|
731
730
|
query_partitions(Aerospike::PartitionFilter.all, statement, options)
|
732
731
|
end
|
733
732
|
|
733
|
+
#----------------------------------------------------------
|
734
|
+
# Query/Execute (Supported by Aerospike 3+ servers only)
|
735
|
+
#----------------------------------------------------------
|
736
|
+
|
737
|
+
# QueryExecute applies operations on records that match the statement filter.
|
738
|
+
# Records are not returned to the client.
|
739
|
+
# This asynchronous server call will return before the command is complete.
|
740
|
+
# The user can optionally wait for command completion by using the returned
|
741
|
+
# ExecuteTask instance.
|
742
|
+
#
|
743
|
+
# This method is only supported by Aerospike 3+ servers.
|
744
|
+
# If the policy is nil, the default relevant policy will be used.
|
745
|
+
#
|
746
|
+
# @param statement [Aerospike::Statement] The query or batch read statement.
|
747
|
+
# @param operations [Array<Aerospike::Operation>] An optional list of operations.
|
748
|
+
# @param options [Hash] An optional hash of policy options.
|
749
|
+
# @return [Aerospike::ExecuteTask] An ExecuteTask instance that can be used to wait for command completion.
|
750
|
+
#
|
751
|
+
# @raise [Aerospike::Exceptions::Aerospike] if an error occurs during the operation.
|
752
|
+
def query_execute(statement, operations = [], options = nil)
|
753
|
+
policy = create_policy(options, WritePolicy, default_write_policy)
|
754
|
+
|
755
|
+
if statement.nil?
|
756
|
+
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::INVALID_COMMAND, "Query failed of invalid statement.")
|
757
|
+
end
|
758
|
+
|
759
|
+
statement = statement.clone
|
760
|
+
unless operations.empty?
|
761
|
+
statement.operations = operations
|
762
|
+
end
|
763
|
+
|
764
|
+
task_id = statement.task_id
|
765
|
+
nodes = @cluster.nodes
|
766
|
+
if nodes.empty?
|
767
|
+
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_NOT_AVAILABLE, "Query failed because cluster is empty.")
|
768
|
+
end
|
769
|
+
|
770
|
+
# Use a thread per node
|
771
|
+
nodes.each do |node|
|
772
|
+
Thread.new do
|
773
|
+
Thread.current.abort_on_exception = true
|
774
|
+
begin
|
775
|
+
command = ServerCommand.new(@cluster, node, policy, statement, true, task_id)
|
776
|
+
execute_command(command)
|
777
|
+
rescue => e
|
778
|
+
Aerospike.logger.error(e)
|
779
|
+
raise e
|
780
|
+
end
|
781
|
+
end
|
782
|
+
end
|
783
|
+
ExecuteTask.new(@cluster, statement)
|
784
|
+
end
|
785
|
+
|
734
786
|
#-------------------------------------------------------
|
735
787
|
# User administration
|
736
788
|
#-------------------------------------------------------
|
data/lib/aerospike/cluster.rb
CHANGED
@@ -23,13 +23,8 @@ require 'aerospike/atomic/atomic'
|
|
23
23
|
|
24
24
|
module Aerospike
|
25
25
|
class Cluster
|
26
|
-
attr_reader :connection_timeout, :connection_queue_size, :user, :password
|
27
|
-
|
28
|
-
attr_reader :cluster_id, :aliases
|
29
|
-
attr_reader :cluster_name
|
30
|
-
attr_reader :client_policy
|
31
|
-
attr_accessor :rack_aware, :rack_id
|
32
|
-
attr_accessor :session_token, :session_expiration
|
26
|
+
attr_reader :connection_timeout, :connection_queue_size, :user, :password, :features, :tls_options, :cluster_id, :aliases, :cluster_name, :client_policy
|
27
|
+
attr_accessor :rack_aware, :rack_id, :session_token, :session_expiration
|
33
28
|
|
34
29
|
def initialize(policy, hosts)
|
35
30
|
@client_policy = policy
|
@@ -63,6 +58,10 @@ module Aerospike
|
|
63
58
|
end
|
64
59
|
|
65
60
|
initialize_tls_host_names(hosts) if tls_enabled?
|
61
|
+
|
62
|
+
if policy.min_connections_per_node > policy.max_connections_per_node
|
63
|
+
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::PARAMETER_ERROR, "Invalid policy configuration: Minimum connections per node cannot be greater than maximum connections per node.")
|
64
|
+
end
|
66
65
|
end
|
67
66
|
|
68
67
|
def connect
|
@@ -584,7 +583,9 @@ module Aerospike
|
|
584
583
|
end
|
585
584
|
|
586
585
|
def create_node(nv)
|
587
|
-
::Aerospike::Node.new(self, nv)
|
586
|
+
node = ::Aerospike::Node.new(self, nv)
|
587
|
+
node.fill_connection_pool_up_to(@client_policy.min_connections_per_node)
|
588
|
+
node
|
588
589
|
end
|
589
590
|
|
590
591
|
def create_connection(host)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2014-
|
1
|
+
# Copyright 2014-2024 Aerospike, Inc.
|
2
2
|
#
|
3
3
|
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
4
4
|
# license agreements.
|
@@ -465,6 +465,254 @@ module Aerospike
|
|
465
465
|
end_cmd
|
466
466
|
end
|
467
467
|
|
468
|
+
def set_query(policy, statement, background, node_partitions)
|
469
|
+
function_arg_buffer = nil
|
470
|
+
field_count = 0
|
471
|
+
filter_size = 0
|
472
|
+
|
473
|
+
begin_cmd
|
474
|
+
|
475
|
+
if statement.namespace
|
476
|
+
@data_offset += statement.namespace.bytesize + FIELD_HEADER_SIZE
|
477
|
+
field_count += 1
|
478
|
+
end
|
479
|
+
|
480
|
+
if statement.set_name
|
481
|
+
@data_offset += statement.set_name.bytesize + FIELD_HEADER_SIZE
|
482
|
+
field_count += 1
|
483
|
+
end
|
484
|
+
|
485
|
+
# Estimate recordsPerSecond field size. This field is used in new servers and not used
|
486
|
+
# (but harmless to add) in old servers.
|
487
|
+
if statement.records_per_second > 0
|
488
|
+
@data_offset += 4 + FIELD_HEADER_SIZE
|
489
|
+
field_count += 1
|
490
|
+
end
|
491
|
+
|
492
|
+
# Estimate socket timeout field size. This field is used in new servers and not used
|
493
|
+
# (but harmless to add) in old servers.
|
494
|
+
@data_offset += 4 + FIELD_HEADER_SIZE
|
495
|
+
field_count += 1
|
496
|
+
|
497
|
+
# Estimate task_id field.
|
498
|
+
@data_offset += 8 + FIELD_HEADER_SIZE
|
499
|
+
field_count += 1
|
500
|
+
|
501
|
+
filter = statement.filters[0]
|
502
|
+
bin_names = statement.bin_names
|
503
|
+
packed_ctx = nil
|
504
|
+
|
505
|
+
if filter
|
506
|
+
col_type = filter.collection_type
|
507
|
+
|
508
|
+
# Estimate INDEX_TYPE field.
|
509
|
+
if col_type > 0
|
510
|
+
@data_offset += FIELD_HEADER_SIZE + 1
|
511
|
+
field_count += 1
|
512
|
+
end
|
513
|
+
|
514
|
+
# Estimate INDEX_RANGE field.
|
515
|
+
@data_offset += FIELD_HEADER_SIZE
|
516
|
+
filter_size += 1 # num filters
|
517
|
+
filter_size += filter.estimate_size
|
518
|
+
|
519
|
+
@data_offset += filter_size
|
520
|
+
field_count += 1
|
521
|
+
|
522
|
+
packed_ctx = filter.packed_ctx
|
523
|
+
if packed_ctx
|
524
|
+
@data_offset += FIELD_HEADER_SIZE + packed_ctx.length
|
525
|
+
field_count += 1
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
statement.set_task_id
|
530
|
+
predexp = policy.predexp || statement.predexp
|
531
|
+
|
532
|
+
if predexp
|
533
|
+
@data_offset += FIELD_HEADER_SIZE
|
534
|
+
pred_size = Aerospike::PredExp.estimate_size(predexp)
|
535
|
+
@data_offset += pred_size
|
536
|
+
field_count += 1
|
537
|
+
end
|
538
|
+
|
539
|
+
unless policy.filter_exp.nil?
|
540
|
+
exp_size = estimate_expression_size(policy.filter_exp)
|
541
|
+
field_count += 1 if exp_size > 0
|
542
|
+
end
|
543
|
+
|
544
|
+
# Estimate aggregation/background function size.
|
545
|
+
if statement.function_name
|
546
|
+
@data_offset += FIELD_HEADER_SIZE + 1 # udf type
|
547
|
+
@data_offset += statement.package_name.bytesize + FIELD_HEADER_SIZE
|
548
|
+
@data_offset += statement.function_name.bytesize + FIELD_HEADER_SIZE
|
549
|
+
|
550
|
+
function_arg_buffer = ""
|
551
|
+
if statement.function_args && statement.function_args.length > 0
|
552
|
+
function_arg_buffer = Value.of(statement.function_args).to_bytes
|
553
|
+
end
|
554
|
+
@data_offset += FIELD_HEADER_SIZE + function_arg_buffer.bytesize
|
555
|
+
field_count += 4
|
556
|
+
end
|
557
|
+
|
558
|
+
max_records = 0
|
559
|
+
parts_full_size = 0
|
560
|
+
parts_partial_digest_size = 0
|
561
|
+
parts_partial_bval_size = 0
|
562
|
+
|
563
|
+
unless node_partitions.nil?
|
564
|
+
parts_full_size = node_partitions.parts_full.length * 2
|
565
|
+
parts_partial_digest_size = node_partitions.parts_partial.length * 20
|
566
|
+
|
567
|
+
unless filter.nil?
|
568
|
+
parts_partial_bval_size = node_partitions.parts_partial.length * 8
|
569
|
+
end
|
570
|
+
max_records = node_partitions.record_max
|
571
|
+
end
|
572
|
+
|
573
|
+
if parts_full_size > 0
|
574
|
+
@data_offset += parts_full_size + FIELD_HEADER_SIZE
|
575
|
+
field_count += 1
|
576
|
+
end
|
577
|
+
|
578
|
+
if parts_partial_digest_size > 0
|
579
|
+
@data_offset += parts_partial_digest_size + FIELD_HEADER_SIZE
|
580
|
+
field_count += 1
|
581
|
+
end
|
582
|
+
|
583
|
+
if parts_partial_bval_size > 0
|
584
|
+
@data_offset += parts_partial_bval_size + FIELD_HEADER_SIZE
|
585
|
+
field_count += 1
|
586
|
+
end
|
587
|
+
|
588
|
+
# Estimate max records field size. This field is used in new servers and not used
|
589
|
+
# (but harmless to add) in old servers.
|
590
|
+
if max_records > 0
|
591
|
+
@data_offset += 8 + FIELD_HEADER_SIZE
|
592
|
+
field_count += 1
|
593
|
+
end
|
594
|
+
|
595
|
+
operations = statement.operations
|
596
|
+
operation_count = 0
|
597
|
+
|
598
|
+
if !operations.empty?
|
599
|
+
|
600
|
+
unless background
|
601
|
+
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::PARAMETER_ERROR)
|
602
|
+
end
|
603
|
+
|
604
|
+
operations.each do |operation|
|
605
|
+
estimate_operation_size_for_operation(operation)
|
606
|
+
end
|
607
|
+
operation_count = operations.size
|
608
|
+
elsif !bin_names.empty?
|
609
|
+
bin_names.each do |bin_name|
|
610
|
+
estimate_operation_size_for_bin_name(bin_name)
|
611
|
+
end
|
612
|
+
operation_count = bin_names.length
|
613
|
+
# Estimate size for selected bin names (query bin names already handled for old servers).
|
614
|
+
end
|
615
|
+
|
616
|
+
size_buffer
|
617
|
+
|
618
|
+
if background
|
619
|
+
write_header_with_policy(policy, 0, INFO2_WRITE, field_count, operation_count)
|
620
|
+
else
|
621
|
+
read_attr = INFO1_READ
|
622
|
+
read_attr |= INFO1_NOBINDATA unless policy.include_bin_data
|
623
|
+
read_attr |= INFO1_SHORT_QUERY if policy.short_query
|
624
|
+
write_header(policy, read_attr, 0, field_count, operation_count)
|
625
|
+
end
|
626
|
+
|
627
|
+
write_field_string(statement.namespace, FieldType::NAMESPACE) if statement.namespace
|
628
|
+
write_field_string(statement.set_name, FieldType::TABLE) if statement.set_name
|
629
|
+
|
630
|
+
# Write records per second.
|
631
|
+
write_field_int(statement.records_per_second, FieldType::RECORDS_PER_SECOND) if statement.records_per_second > 0
|
632
|
+
|
633
|
+
write_filter_exp(policy.filter_exp, exp_size)
|
634
|
+
|
635
|
+
# Write socket idle timeout.
|
636
|
+
write_field_int(policy.socket_timeout, FieldType::SOCKET_TIMEOUT)
|
637
|
+
|
638
|
+
# Write task_id field
|
639
|
+
write_field_int64(statement.task_id, FieldType::TRAN_ID)
|
640
|
+
|
641
|
+
unless predexp.nil?
|
642
|
+
write_field_header(pred_size, Aerospike::FieldType::PREDEXP)
|
643
|
+
@data_offset = Aerospike::PredExp.write(
|
644
|
+
predexp, @data_buffer, @data_offset
|
645
|
+
)
|
646
|
+
end
|
647
|
+
|
648
|
+
if filter
|
649
|
+
type = filter.collection_type
|
650
|
+
|
651
|
+
if type > 0
|
652
|
+
write_field_header(1, FieldType::INDEX_TYPE)
|
653
|
+
@data_offset += @data_buffer.write_byte(type, @data_offset)
|
654
|
+
end
|
655
|
+
|
656
|
+
write_field_header(filter_size, FieldType::INDEX_RANGE)
|
657
|
+
@data_offset += @data_buffer.write_byte(1, @data_offset)
|
658
|
+
@data_offset = filter.write(@data_buffer, @data_offset)
|
659
|
+
|
660
|
+
if packed_ctx
|
661
|
+
write_field_header(packed_ctx.length, FieldType::INDEX_CONTEXT)
|
662
|
+
@data_offset += @data_buffer.write_binary(packed_ctx, @data_offset)
|
663
|
+
end
|
664
|
+
end
|
665
|
+
|
666
|
+
if statement.function_name
|
667
|
+
write_field_header(1, FieldType::UDF_OP)
|
668
|
+
@data_offset += @data_buffer.write_byte(1, @data_offset)
|
669
|
+
write_field_string(statement.package_name, FieldType::UDF_PACKAGE_NAME)
|
670
|
+
write_field_string(statement.function_name, FieldType::UDF_FUNCTION)
|
671
|
+
write_field_string(function_arg_buffer, FieldType::UDF_ARGLIST)
|
672
|
+
end
|
673
|
+
|
674
|
+
if parts_full_size > 0
|
675
|
+
write_field_header(parts_full_size, FieldType::PID_ARRAY)
|
676
|
+
node_partitions.parts_full.each do |part|
|
677
|
+
@data_offset += @data_buffer.write_uint16_little_endian(part.id, @data_offset)
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
if parts_partial_digest_size > 0
|
682
|
+
write_field_header(parts_partial_digest_size, FieldType::DIGEST_ARRAY)
|
683
|
+
node_partitions.parts_partial.each do |part|
|
684
|
+
@data_offset += @data_buffer.write_binary(part.digest, @data_offset)
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
688
|
+
if parts_partial_bval_size > 0
|
689
|
+
write_field_header(parts_partial_bval_size, FieldType::BVAL_ARRAY)
|
690
|
+
@node_partitions.parts_partial.each do |part|
|
691
|
+
@data_offset += @data_buffer.write_uint64_little_endian(part.bval, @data_offset)
|
692
|
+
end
|
693
|
+
end
|
694
|
+
|
695
|
+
if max_records > 0
|
696
|
+
write_field(max_records, FieldType::MAX_RECORDS)
|
697
|
+
end
|
698
|
+
|
699
|
+
if operations.empty?
|
700
|
+
if bin_names.empty?
|
701
|
+
bin_names.each do |bin_name|
|
702
|
+
write_operation_for_bin_name(bin_name, Operation::READ)
|
703
|
+
end
|
704
|
+
end
|
705
|
+
else
|
706
|
+
operations.each do |operation|
|
707
|
+
write_operation_for_operation(operation)
|
708
|
+
end
|
709
|
+
end
|
710
|
+
|
711
|
+
end_cmd
|
712
|
+
|
713
|
+
nil
|
714
|
+
end
|
715
|
+
|
468
716
|
def execute
|
469
717
|
iterations = 0
|
470
718
|
|
@@ -537,7 +785,7 @@ module Aerospike
|
|
537
785
|
parse_result
|
538
786
|
rescue => e
|
539
787
|
case e
|
540
|
-
|
788
|
+
# do not log the following exceptions
|
541
789
|
when Aerospike::Exceptions::ScanTerminated
|
542
790
|
when Aerospike::Exceptions::QueryTerminated
|
543
791
|
else
|
@@ -703,9 +951,8 @@ module Aerospike
|
|
703
951
|
read_attr |= INFO1_CONSISTENCY_ALL if policy.consistency_level == Aerospike::ConsistencyLevel::CONSISTENCY_ALL
|
704
952
|
write_attr |= INFO2_DURABLE_DELETE if policy.durable_delete
|
705
953
|
read_attr |= INFO1_COMPRESS_RESPONSE if policy.use_compression
|
706
|
-
|
707
954
|
# Write all header data except total size which must be written last.
|
708
|
-
@data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message
|
955
|
+
@data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message header.length.
|
709
956
|
@data_buffer.write_byte(read_attr, 9)
|
710
957
|
@data_buffer.write_byte(write_attr, 10)
|
711
958
|
@data_buffer.write_byte(info_attr, 11)
|
data/lib/aerospike/node.rb
CHANGED
@@ -22,7 +22,7 @@ require 'aerospike/atomic/atomic'
|
|
22
22
|
module Aerospike
|
23
23
|
class Node
|
24
24
|
|
25
|
-
attr_reader :reference_count, :responded, :name, :features, :cluster_name, :partition_generation, :rebalance_generation, :peers_generation, :failures, :cluster, :peers_count, :host
|
25
|
+
attr_reader :reference_count, :responded, :name, :features, :cluster_name, :partition_generation, :rebalance_generation, :peers_generation, :failures, :cluster, :peers_count, :host, :connections
|
26
26
|
|
27
27
|
PARTITIONS = 4096
|
28
28
|
FULL_HEALTH = 100
|
@@ -69,6 +69,17 @@ module Aerospike
|
|
69
69
|
racks[ns] == rack_id
|
70
70
|
end
|
71
71
|
|
72
|
+
def fill_connection_pool_up_to(min_connection_size)
|
73
|
+
current_number_of_connections = @connections.length
|
74
|
+
if min_connection_size > 0
|
75
|
+
while current_number_of_connections < min_connection_size
|
76
|
+
conn = @connections.create
|
77
|
+
@connections.offer(conn)
|
78
|
+
current_number_of_connections += 1
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
72
83
|
# Get a connection to the node. If no cached connection is not available,
|
73
84
|
# a new connection will be created
|
74
85
|
def get_connection(timeout)
|
@@ -23,7 +23,7 @@ module Aerospike
|
|
23
23
|
class ClientPolicy
|
24
24
|
|
25
25
|
attr_accessor :user, :password, :auth_mode
|
26
|
-
attr_accessor :timeout, :connection_queue_size, :fail_if_not_connected, :tend_interval
|
26
|
+
attr_accessor :timeout, :connection_queue_size, :fail_if_not_connected, :tend_interval, :max_connections_per_node, :min_connections_per_node
|
27
27
|
attr_accessor :cluster_name
|
28
28
|
attr_accessor :tls
|
29
29
|
attr_accessor :policies
|
@@ -74,6 +74,26 @@ module Aerospike
|
|
74
74
|
# ClientPolicy#rack_aware, Replica#PREFER_RACK and server rack
|
75
75
|
# configuration must also be set to enable this functionality.
|
76
76
|
@rack_id = opt[:rack_id] || 0
|
77
|
+
|
78
|
+
# Maximum number of synchronous connections allowed per server node. Transactions will go
|
79
|
+
# through retry logic and potentially fail with "ResultCode.NO_MORE_CONNECTIONS" if the maximum
|
80
|
+
# number of connections would be exceeded.
|
81
|
+
# The number of connections used per node depends on concurrent commands in progress
|
82
|
+
# plus sub-commands used for parallel multi-node commands (batch, scan, and query).
|
83
|
+
# One connection will be used for each command.
|
84
|
+
# Default: 100
|
85
|
+
@max_connections_per_node = opt[:max_connections_per_node] || 100
|
86
|
+
|
87
|
+
# MinConnectionsPerNode specifies the minimum number of synchronous connections allowed per server node.
|
88
|
+
# Preallocate min connections on client node creation.
|
89
|
+
# The client will periodically allocate new connections if count falls below min connections.
|
90
|
+
#
|
91
|
+
# Server proto-fd-idle-ms may also need to be increased substantially if min connections are defined.
|
92
|
+
# The proto-fd-idle-ms default directs the server to close connections that are idle for 60 seconds
|
93
|
+
# which can defeat the purpose of keeping connections in reserve for a future burst of activity.
|
94
|
+
#
|
95
|
+
# Default: 0
|
96
|
+
@min_connections_per_node = opt[:min_connections_per_node] || 0
|
77
97
|
end
|
78
98
|
|
79
99
|
def requires_authentication
|
@@ -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
|
-
:predexp, :fail_on_filtered_out, :replica, :use_compression
|
25
|
+
:predexp, :fail_on_filtered_out, :replica, :use_compression, :socket_timeout
|
26
26
|
|
27
27
|
alias total_timeout timeout
|
28
28
|
alias total_timeout= timeout=
|
@@ -51,8 +51,10 @@ module Aerospike
|
|
51
51
|
# Default: false
|
52
52
|
@fail_on_filtered_out = opt[:fail_on_filtered_out] || false
|
53
53
|
|
54
|
-
#
|
55
|
-
#
|
54
|
+
# [:nodoc:]
|
55
|
+
# DEPRECATED
|
56
|
+
# The Aerospike server does not support this policy anymore
|
57
|
+
# TODO: Remove for next major release
|
56
58
|
@priority = opt[:priority] || Priority::DEFAULT
|
57
59
|
|
58
60
|
# Set optional predicate expression filters in postfix notation.
|
@@ -133,6 +135,16 @@ module Aerospike
|
|
133
135
|
# Duration to sleep between retries if a transaction fails and the
|
134
136
|
# timeout was not exceeded. Enter zero to skip sleep.
|
135
137
|
@sleep_between_retries = opt[:sleep_between_retries] || 0.5
|
138
|
+
|
139
|
+
# Determines network timeout for each attempt.
|
140
|
+
#
|
141
|
+
# If socket_timeout is not zero and socket_timeout is reached before an attempt completes,
|
142
|
+
# the Timeout above is checked. If Timeout is not exceeded, the transaction
|
143
|
+
# is retried. If both socket_timeout and Timeout are non-zero, socket_timeout must be less
|
144
|
+
# than or equal to Timeout, otherwise Timeout will also be used for socket_timeout.
|
145
|
+
#
|
146
|
+
# Default: 30s
|
147
|
+
@socket_timeout = opt[:socket_timeout] || 30000
|
136
148
|
end
|
137
149
|
end # class
|
138
150
|
end # module
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
# Copyright 2014-
|
2
|
+
# Copyright 2014-2023 Aerospike, Inc.
|
3
3
|
#
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
# you may not use this file except in compliance with the License.
|
@@ -13,6 +13,10 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
+
|
17
|
+
#[:nodoc:]
|
18
|
+
# DEPRECATED
|
19
|
+
# TODO: Remove this module on the next major release
|
16
20
|
module Aerospike
|
17
21
|
|
18
22
|
module Priority
|
@@ -48,7 +48,10 @@ module Aerospike
|
|
48
48
|
# Default is 100.
|
49
49
|
@scan_percent = opt[:scan_percent] || 100
|
50
50
|
|
51
|
-
#
|
51
|
+
# [:nodoc:]
|
52
|
+
# DEPRECATED
|
53
|
+
# The Aerospike server does not support this policy anymore
|
54
|
+
# TODO: Remove for next major release
|
52
55
|
@concurrent_nodes = opt.fetch(:concurrent_nodes) { true }
|
53
56
|
|
54
57
|
# Indicates if bin data is retrieved. If false, only record digests (and
|
@@ -56,8 +59,10 @@ module Aerospike
|
|
56
59
|
# Default is true.
|
57
60
|
@include_bin_data = opt.fetch(:include_bin_data) { true }
|
58
61
|
|
59
|
-
#
|
60
|
-
#
|
62
|
+
# [:nodoc:]
|
63
|
+
# DEPRECATED
|
64
|
+
# The Aerospike server does not support this policy anymore
|
65
|
+
# TODO: Remove for next major release
|
61
66
|
@fail_on_cluster_change = opt.fetch(:fail_on_cluster_change) { true }
|
62
67
|
|
63
68
|
# Determines network timeout for each attempt.
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
# Copyright 2014-
|
2
|
+
# Copyright 2014-2023 Aerospike, Inc.
|
3
3
|
#
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
# you may not use this file except in compliance with the License.
|
@@ -24,8 +24,8 @@ module Aerospike
|
|
24
24
|
class WritePolicy < Policy
|
25
25
|
|
26
26
|
attr_accessor :record_exists_action, :generation_policy,
|
27
|
-
|
28
|
-
|
27
|
+
:generation, :ttl, :send_key, :commit_level,
|
28
|
+
:durable_delete
|
29
29
|
|
30
30
|
alias expiration ttl
|
31
31
|
alias expiration= ttl=
|
@@ -74,6 +74,11 @@ module Aerospike
|
|
74
74
|
# Valid for Aerospike Server Enterprise Edition 3.10+ only.
|
75
75
|
@durable_delete = opt.fetch(:durable_delete, false)
|
76
76
|
|
77
|
+
# Transaction timeout.
|
78
|
+
# This timeout is used to set the socket timeout and is also sent to the
|
79
|
+
# server along with the transaction in the wire protocol.
|
80
|
+
# Default for write policy is 1.
|
81
|
+
@timeout = opt[:timeout] || 1
|
77
82
|
self
|
78
83
|
end
|
79
84
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# Copyright 2014-2023 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
|
+
|
18
|
+
module Aerospike
|
19
|
+
class ServerCommand < MultiCommand
|
20
|
+
attr_accessor :statement, :task_id, :cluster, :write_policy, :background
|
21
|
+
|
22
|
+
def initialize(cluster, node, policy, statement, background, task_id)
|
23
|
+
super(node)
|
24
|
+
@statement = statement
|
25
|
+
@task_id = task_id
|
26
|
+
@cluster = cluster
|
27
|
+
@policy = policy
|
28
|
+
@background = background
|
29
|
+
end
|
30
|
+
|
31
|
+
def write?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def write_buffer
|
36
|
+
set_query(@policy, @statement, background, nil)
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_row
|
40
|
+
field_count = @data_buffer.read_int16(18)
|
41
|
+
result_code = @data_buffer.read(5).ord & 0xFF
|
42
|
+
skip_key(field_count)
|
43
|
+
|
44
|
+
if result_code != 0
|
45
|
+
if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
49
|
+
end
|
50
|
+
op_count = @data_buffer.read_int16(20)
|
51
|
+
if op_count <= 0
|
52
|
+
return Record.new(@node, key, bins, generation, expiration)
|
53
|
+
end
|
54
|
+
|
55
|
+
unless valid?
|
56
|
+
raise Aerospike::Exceptions::QueryTerminated
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
# Copyright 2014-
|
2
|
+
# Copyright 2014-2023 Aerospike, Inc.
|
3
3
|
#
|
4
4
|
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
5
5
|
# license agreements.
|
@@ -16,11 +16,14 @@
|
|
16
16
|
|
17
17
|
module Aerospike
|
18
18
|
|
19
|
+
# The Aerospike::Statement class represents a query or scan statement to be executed on the database.
|
20
|
+
# It provides a set of properties that define the query or scan, including namespace, set name, bin names,
|
21
|
+
# index name, filters, and operations.
|
19
22
|
class Statement
|
20
23
|
|
21
24
|
attr_accessor :namespace, :set_name, :index_name, :bin_names, :task_id
|
22
|
-
attr_accessor :filters, :package_name, :function_name, :function_args
|
23
|
-
attr_accessor :predexp, :return_data
|
25
|
+
attr_accessor :filters, :package_name, :function_name, :function_args, :operations
|
26
|
+
attr_accessor :predexp, :return_data, :records_per_second
|
24
27
|
|
25
28
|
def initialize(namespace, set_name, bin_names=[])
|
26
29
|
# Namespace determines query Namespace
|
@@ -56,6 +59,14 @@ module Aerospike
|
|
56
59
|
@package_name = nil
|
57
60
|
@function_name = nil
|
58
61
|
@function_args = nil
|
62
|
+
@operations = nil
|
63
|
+
|
64
|
+
|
65
|
+
# Limit returned records per second (rps) rate for each server.
|
66
|
+
# Will not apply rps limit if records_per_second is zero.
|
67
|
+
# Currently only applicable to a query without a defined filter (scan).
|
68
|
+
# Default is 0
|
69
|
+
@records_per_second = 0
|
59
70
|
|
60
71
|
# TaskId determines query task id. (Optional)
|
61
72
|
@task_id = rand(RAND_MAX)
|
@@ -64,33 +75,35 @@ module Aerospike
|
|
64
75
|
@return_data = true
|
65
76
|
end
|
66
77
|
|
67
|
-
|
78
|
+
def set_aggregate_function(package_name, function_name, function_args=[], return_data=true)
|
68
79
|
@package_name = package_name
|
69
80
|
@function_name = function_name
|
70
81
|
@function_args = function_args
|
71
82
|
@return_data = return_data
|
72
|
-
|
83
|
+
end
|
73
84
|
|
74
|
-
|
75
|
-
|
76
|
-
|
85
|
+
def is_scan?
|
86
|
+
return (filters.nil? || (filters.empty?))
|
87
|
+
end
|
77
88
|
|
78
|
-
|
79
|
-
|
80
|
-
|
89
|
+
def set_task_id
|
90
|
+
while @task_id == 0
|
91
|
+
@task_id = rand(RAND_MAX)
|
92
|
+
end
|
81
93
|
end
|
82
|
-
end
|
83
94
|
|
84
|
-
|
85
|
-
@task_id = rand(RAND_MAX)
|
86
|
-
while @task_id == 0
|
95
|
+
def reset_task_id
|
87
96
|
@task_id = rand(RAND_MAX)
|
97
|
+
while @task_id == 0
|
98
|
+
@task_id = rand(RAND_MAX)
|
99
|
+
end
|
88
100
|
end
|
89
|
-
end
|
90
101
|
|
91
|
-
private
|
92
102
|
|
93
|
-
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
RAND_MAX = 2**63 - 1
|
94
107
|
|
95
108
|
end # class
|
96
109
|
end
|
data/lib/aerospike/record.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2014-
|
1
|
+
# Copyright 2014-2023 Aerospike, Inc.
|
2
2
|
#
|
3
3
|
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
4
4
|
# license agreements.
|
@@ -33,6 +33,8 @@ module Aerospike
|
|
33
33
|
@node = node
|
34
34
|
end
|
35
35
|
|
36
|
+
|
37
|
+
|
36
38
|
def to_s
|
37
39
|
"key: `#{key}` bins: `#{bins}` generation: `#{generation}`, ttl: `#{ttl}`"
|
38
40
|
end
|
@@ -41,6 +43,18 @@ module Aerospike
|
|
41
43
|
|
42
44
|
CITRUSLEAF_EPOCH = 1262304000
|
43
45
|
|
46
|
+
# Arguments:
|
47
|
+
# value: the key to retrieve the value for
|
48
|
+
#
|
49
|
+
# Returns:
|
50
|
+
# the value of the specified key, or `nil` if `@bins` is `nil`
|
51
|
+
def get_value(value)
|
52
|
+
unless @bins.nil?
|
53
|
+
return @bins[value]
|
54
|
+
end
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
44
58
|
# Converts an absolute expiration time (in seconds from citrusleaf epoch)
|
45
59
|
# to relative time-to-live (TTL) in seconds
|
46
60
|
def expiration_to_ttl(secs_from_epoc)
|
data/lib/aerospike/utils/pool.rb
CHANGED
data/lib/aerospike/version.rb
CHANGED
data/lib/aerospike.rb
CHANGED
@@ -169,6 +169,7 @@ require "aerospike/query/scan_executor"
|
|
169
169
|
require "aerospike/query/scan_partition_command"
|
170
170
|
require "aerospike/query/query_executor"
|
171
171
|
require "aerospike/query/query_partition_command"
|
172
|
+
require "aerospike/query/server_command"
|
172
173
|
|
173
174
|
require "aerospike/exp/exp"
|
174
175
|
require "aerospike/exp/exp_map"
|
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aerospike
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.28.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Khosrow Afroozeh
|
8
8
|
- Jan Hecking
|
9
|
-
|
9
|
+
- Sachin Venkatesha Murthy
|
10
|
+
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date:
|
13
|
+
date: 2023-06-23 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: msgpack
|
@@ -44,6 +45,7 @@ description: Official Aerospike Client for ruby. Access your Aerospike cluster w
|
|
44
45
|
email:
|
45
46
|
- khosrow@aerospike.com
|
46
47
|
- jhecking@aerospike.com
|
48
|
+
- smurthy@aerospike.com
|
47
49
|
executables: []
|
48
50
|
extensions: []
|
49
51
|
extra_rdoc_files: []
|
@@ -181,6 +183,7 @@ files:
|
|
181
183
|
- lib/aerospike/query/scan_command.rb
|
182
184
|
- lib/aerospike/query/scan_executor.rb
|
183
185
|
- lib/aerospike/query/scan_partition_command.rb
|
186
|
+
- lib/aerospike/query/server_command.rb
|
184
187
|
- lib/aerospike/query/statement.rb
|
185
188
|
- lib/aerospike/query/stream_command.rb
|
186
189
|
- lib/aerospike/record.rb
|
@@ -227,8 +230,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
227
230
|
- !ruby/object:Gem::Version
|
228
231
|
version: '0'
|
229
232
|
requirements: []
|
230
|
-
rubygems_version: 3.3.
|
231
|
-
signing_key:
|
233
|
+
rubygems_version: 3.3.3
|
234
|
+
signing_key:
|
232
235
|
specification_version: 4
|
233
236
|
summary: An Aerospike driver for Ruby.
|
234
237
|
test_files: []
|