aerospike 2.6.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +3 -1
  4. data/lib/aerospike.rb +9 -5
  5. data/lib/aerospike/client.rb +101 -83
  6. data/lib/aerospike/cluster.rb +11 -50
  7. data/lib/aerospike/cluster/create_connection.rb +1 -1
  8. data/lib/aerospike/cluster/find_nodes_to_remove.rb +66 -0
  9. data/lib/aerospike/cluster/partition.rb +5 -2
  10. data/lib/aerospike/command/batch_direct_command.rb +104 -0
  11. data/lib/aerospike/command/batch_direct_exists_command.rb +51 -0
  12. data/lib/aerospike/command/batch_direct_node.rb +40 -0
  13. data/lib/aerospike/command/batch_index_command.rb +119 -0
  14. data/lib/aerospike/command/batch_index_exists_command.rb +45 -0
  15. data/lib/aerospike/command/batch_index_node.rb +52 -0
  16. data/lib/aerospike/command/batch_item.rb +18 -47
  17. data/lib/aerospike/command/command.rb +6 -65
  18. data/lib/aerospike/command/field_type.rb +13 -10
  19. data/lib/aerospike/command/{batch_command.rb → multi_command.rb} +29 -9
  20. data/lib/aerospike/command/read_command.rb +4 -2
  21. data/lib/aerospike/command/single_command.rb +6 -9
  22. data/lib/aerospike/connection/create.rb +3 -3
  23. data/lib/aerospike/host/parse.rb +28 -2
  24. data/lib/aerospike/node.rb +6 -2
  25. data/lib/aerospike/node/refresh/friends.rb +1 -1
  26. data/lib/aerospike/node/refresh/peers.rb +1 -1
  27. data/lib/aerospike/node_validator.rb +3 -3
  28. data/lib/aerospike/peers.rb +4 -0
  29. data/lib/aerospike/peers/parse.rb +26 -6
  30. data/lib/aerospike/policy/batch_policy.rb +25 -15
  31. data/lib/aerospike/policy/client_policy.rb +2 -2
  32. data/lib/aerospike/policy/query_policy.rb +25 -12
  33. data/lib/aerospike/policy/scan_policy.rb +39 -16
  34. data/lib/aerospike/query/stream_command.rb +6 -5
  35. data/lib/aerospike/record.rb +4 -3
  36. data/lib/aerospike/socket/ssl.rb +13 -13
  37. data/lib/aerospike/socket/tcp.rb +8 -1
  38. data/lib/aerospike/utils/string_parser.rb +7 -3
  39. data/lib/aerospike/version.rb +1 -1
  40. metadata +11 -7
  41. data/lib/aerospike/command/batch_command_exists.rb +0 -93
  42. data/lib/aerospike/command/batch_command_get.rb +0 -84
  43. data/lib/aerospike/command/batch_node.rb +0 -82
@@ -21,10 +21,10 @@ module Aerospike
21
21
  module Connection # :nodoc:
22
22
  module Create
23
23
  class << self
24
- def call(host, port, timeout: 30, tls_name: nil, ssl_options: nil)
25
- if !ssl_options.nil? && ssl_options[:enable] != false
24
+ def call(host, port, timeout: 30, tls_name: nil, tls_options: nil)
25
+ if !tls_options.nil? && tls_options[:enable] != false
26
26
  ::Aerospike::Socket::SSL.connect(
27
- host, port, timeout, tls_name, ssl_options
27
+ host, port, timeout, tls_name, tls_options
28
28
  )
29
29
  else
30
30
  ::Aerospike::Socket::TCP.connect(host, port, timeout)
@@ -23,7 +23,14 @@ module Aerospike
23
23
  INTEGER_REGEX = /\A\d+\z/
24
24
 
25
25
  class << self
26
- # Parse hosts from string format: hostname1[:tlsname1][:port1],...
26
+ ##
27
+ # Parse hosts from string format: hostname1[:tlsname1][:port1],...
28
+ #
29
+ # Hostname may also be an IP address in the following formats:
30
+ # - xxx.xxx.xxx.xxx
31
+ # - [xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]
32
+ # - [xxxx::xxxx]
33
+ #
27
34
  def call(hosts, default_port = 3000)
28
35
  case hosts
29
36
  when Host
@@ -32,7 +39,7 @@ module Aerospike
32
39
  hosts
33
40
  when String
34
41
  hosts.split(?,).map { |host|
35
- addr, tls_name, port = host.split(?:)
42
+ addr, tls_name, port = components(host)
36
43
  if port.nil? && tls_name && tls_name.match(INTEGER_REGEX)
37
44
  port = tls_name
38
45
  tls_name = nil
@@ -44,6 +51,25 @@ module Aerospike
44
51
  fail TypeError, "hosts should be a Host object, an Array of Host objects, or a String"
45
52
  end
46
53
  end
54
+
55
+ # Extract addr, tls_name and port components from a host strin
56
+ def components(host_string)
57
+ host_string = host_string.strip
58
+
59
+ # IPv6
60
+ if host_string.start_with?('[')
61
+ end_idx = host_string.index(']')
62
+ raise ::Aerospike::Exceptions::Parse, 'Invalid IPv6 host' if end_idx.nil?
63
+
64
+ # Slice away brackets and what's inside them, then split on : and
65
+ # replace first entry with string inside brackets
66
+ host_string.slice(end_idx+1..-1).split(':').tap do |result|
67
+ result[0] = host_string[1...end_idx]
68
+ end
69
+ else
70
+ host_string.split(?:)
71
+ end
72
+ end
47
73
  end
48
74
  end
49
75
  end
@@ -139,6 +139,10 @@ module Aerospike
139
139
  @reference_count.value = 0
140
140
  end
141
141
 
142
+ def referenced?
143
+ @reference_count.value > 0
144
+ end
145
+
142
146
  def responded!
143
147
  @responded.value = true
144
148
  end
@@ -155,8 +159,8 @@ module Aerospike
155
159
  @peers_count.value > 0
156
160
  end
157
161
 
158
- def failed?
159
- @failures.value > 0
162
+ def failed?(threshold = 1)
163
+ @failures.value >= threshold
160
164
  end
161
165
 
162
166
  def failed!
@@ -60,7 +60,7 @@ module Aerospike
60
60
  host,
61
61
  cluster.connection_timeout,
62
62
  cluster.cluster_name,
63
- cluster.ssl_options
63
+ cluster.tls_options
64
64
  )
65
65
 
66
66
  node = peers.find_node_by_name(nv.name)
@@ -41,7 +41,7 @@ module Aerospike
41
41
 
42
42
  peer.hosts.each do |host|
43
43
  begin
44
- nv = NodeValidator.new(cluster, host, cluster.connection_timeout, cluster.cluster_name, cluster.ssl_options)
44
+ nv = NodeValidator.new(cluster, host, cluster.connection_timeout, cluster.cluster_name, cluster.tls_options)
45
45
 
46
46
  if nv.name != peer.node_name
47
47
  ::Aerospike.logger.warn("Peer node #{peer.node_name} is different than actual node #{nv.name} for host #{host}");
@@ -21,15 +21,15 @@ module Aerospike
21
21
  class NodeValidator # :nodoc:
22
22
  VERSION_REGEXP = /(?<v1>\d+)\.(?<v2>\d+)\.(?<v3>\d+).*/.freeze
23
23
 
24
- attr_reader :host, :aliases, :name, :use_new_info, :features, :cluster_name, :ssl_options, :conn
24
+ attr_reader :host, :aliases, :name, :use_new_info, :features, :cluster_name, :tls_options, :conn
25
25
 
26
- def initialize(cluster, host, timeout, cluster_name, ssl_options = {})
26
+ def initialize(cluster, host, timeout, cluster_name, tls_options = {})
27
27
  @cluster = cluster
28
28
  @use_new_info = true
29
29
  @features = Set.new
30
30
  @host = host
31
31
  @cluster_name = cluster_name
32
- @ssl_options = ssl_options
32
+ @tls_options = tls_options
33
33
 
34
34
  set_aliases(host)
35
35
  set_address(timeout)
@@ -37,6 +37,10 @@ module Aerospike
37
37
  @generation_changed == true
38
38
  end
39
39
 
40
+ def reset_refresh_count!
41
+ @refresh_count = 0
42
+ end
43
+
40
44
  def use_peers?
41
45
  @use_peers == true
42
46
  end
@@ -72,15 +72,35 @@ module Aerospike
72
72
  end
73
73
 
74
74
  def parse_hosts(parser, peer)
75
+ result = []
75
76
  parser.expect('[')
76
- return [] if parser.current == ']'
77
+ return result if parser.current == ']'
77
78
 
78
- # TODO(wallin): handle IPv6
79
- raise ::Aerospike::Exceptions::Parse if parser.current == '['
80
- parser.read_until(']').split(',').map do |host|
81
- hostname, port = host.split(':')
82
- ::Aerospike::Host.new(hostname, port, peer.tls_name)
79
+ loop do
80
+ result << parse_host(parser, peer)
81
+ break if parser.current == ']'
83
82
  end
83
+
84
+ result
85
+ end
86
+
87
+ def parse_host(parser, peer)
88
+ if parser.current == '[' # IPv6
89
+ parser.step
90
+ host = parser.read_until(']')
91
+ # skip one extra if port is detected, to match read behavior below
92
+ parser.step if parser.current == ':'
93
+ else
94
+ host = parser.read_until(',', ':', ']')
95
+ end
96
+
97
+ port = parser.prev == ':' ? parser.read_until(',', ']').to_i : nil
98
+
99
+ if parser.prev == ',' || parser.prev == ']'
100
+ return ::Aerospike::Host.new(host, port, peer.tls_name)
101
+ end
102
+
103
+ raise ::Aerospike::Exceptions::Parse, "Unterminated host in response"
84
104
  end
85
105
  end
86
106
  end
@@ -1,17 +1,19 @@
1
- # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
1
+ # Copyright 2014-2018 Aerospike, Inc.
3
2
  #
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
3
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
+ # license agreements.
7
5
  #
8
- # http:#www.apache.org/licenses/LICENSE-2.0
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
+ # use this file except in compliance with the License. You may obtain a copy of
8
+ # the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
9
11
  #
10
12
  # 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.
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.
15
17
 
16
18
  require 'aerospike/policy/policy'
17
19
 
@@ -20,15 +22,23 @@ module Aerospike
20
22
  # Container object for batch policy command.
21
23
  class BatchPolicy < Policy
22
24
 
23
- attr_accessor :max_concurrent_nodes, :record_queue_size,
24
- :wait_until_migrations_are_over
25
+ attr_accessor :use_batch_direct
25
26
 
26
27
  def initialize(opt={})
27
28
  super(opt)
28
29
 
29
- @max_concurrent_nodes = opt[:max_concurrent_nodes] || 0
30
- @record_queue_size = opt[:record_queue_size] || 5000
31
- @wait_until_migrations_are_over = opt[:wait_until_migrations_are_over].nil? ? false : wait_until_migrations_are_over
30
+ # Use old batch direct protocol where batch reads are handled by direct
31
+ # low-level batch server database routines. The batch direct protocol can
32
+ # be faster when there is a single namespace. But there is one important
33
+ # drawback: The batch direct protocol will not proxy to a different
34
+ # server node when the mapped node has migrated a record to another node
35
+ # (resulting in not found record). This can happen after a node has been
36
+ # added/removed from the cluster and there is a lag between records being
37
+ # migrated and client partition map update (once per second). The batch
38
+ # index protocol will perform this record proxy when necessary.
39
+ #
40
+ # Default: false (use new batch index protocol if server supports it)
41
+ @use_batch_direct = opt.fetch(:use_batch_direct) { false }
32
42
 
33
43
  self
34
44
  end
@@ -25,7 +25,7 @@ module Aerospike
25
25
  attr_accessor :user, :password
26
26
  attr_accessor :timeout, :connection_queue_size, :fail_if_not_connected, :tend_interval
27
27
  attr_accessor :cluster_name
28
- attr_accessor :ssl_options
28
+ attr_accessor :tls
29
29
 
30
30
  def initialize(opt={})
31
31
  # Initial host connection timeout in seconds. The timeout when opening a connection
@@ -51,7 +51,7 @@ module Aerospike
51
51
  # Cluster Name
52
52
  @cluster_name = opt[:cluster_name]
53
53
 
54
- @ssl_options = opt[:ssl_options]
54
+ @tls = opt[:tls] || opt[:ssl_options]
55
55
  end
56
56
 
57
57
  def requires_authentication
@@ -1,34 +1,47 @@
1
- # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
1
+ # Copyright 2014-2018 Aerospike, Inc.
3
2
  #
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
3
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
+ # license agreements.
7
5
  #
8
- # http:#www.apache.org/licenses/LICENSE-2.0
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
+ # use this file except in compliance with the License. You may obtain a copy of
8
+ # the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
9
11
  #
10
12
  # 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.
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.
15
17
 
16
- require 'aerospike/policy/batch_policy'
18
+ require 'aerospike/policy/policy'
17
19
 
18
20
  module Aerospike
19
21
 
20
22
  # Container object for query policy command.
21
- class QueryPolicy < BatchPolicy
23
+ class QueryPolicy < Policy
22
24
 
23
25
  attr_accessor :include_bin_data
26
+ attr_accessor :record_queue_size
24
27
 
25
28
  def initialize(opt={})
26
29
  super(opt)
27
30
 
28
31
  @max_retries = 0
29
32
 
33
+ # Indicates if bin data is retrieved. If false, only record digests (and
34
+ # user keys if stored on the server) are retrieved.
35
+ # Default is true.
30
36
  @include_bin_data = opt.fetch(:include_bin_data, true)
31
37
 
38
+ # Number of records to place in queue before blocking. Records received
39
+ # from multiple server nodes will be placed in a queue. A separate thread
40
+ # consumes these records in parallel. If the queue is full, the producer
41
+ # threads will block until records are consumed.
42
+ # Default is 5000.
43
+ @record_queue_size = opt[:record_queue_size] || 5000
44
+
32
45
  self
33
46
  end
34
47
 
@@ -1,40 +1,63 @@
1
- # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
1
+ # Copyright 2014-2018 Aerospike, Inc.
3
2
  #
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
3
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
+ # license agreements.
7
5
  #
8
- # http:#www.apache.org/licenses/LICENSE-2.0
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
+ # use this file except in compliance with the License. You may obtain a copy of
8
+ # the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
9
11
  #
10
12
  # 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.
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.
15
17
 
16
- require 'aerospike/policy/batch_policy'
18
+ require 'aerospike/policy/policy'
17
19
 
18
20
  module Aerospike
19
21
 
20
22
  # Container object for scan policy command.
21
- class ScanPolicy < BatchPolicy
23
+ class ScanPolicy < Policy
22
24
 
23
25
  attr_accessor :scan_percent
24
26
  attr_accessor :concurrent_nodes
25
27
  attr_accessor :include_bin_data
26
28
  attr_accessor :fail_on_cluster_change
27
29
  attr_accessor :socket_timeout
30
+ attr_accessor :record_queue_size
28
31
 
29
32
  def initialize(opt={})
30
33
  super(opt)
31
34
 
35
+ @max_retries = 0
36
+
37
+ # Percent of data to scan. Valid integer range is 1 to 100.
38
+ # Default is 100.
32
39
  @scan_percent = opt[:scan_percent] || 100
33
- @concurrent_nodes = opt[:concurrent_nodes].nil? ? true : concurrent_nodes
34
- @include_bin_data = opt[:include_bin_data].nil? ? true : include_bin_data
35
- @fail_on_cluster_change = opt[:fail_on_cluster_change].nil? ? true : fail_on_cluster_change
40
+
41
+ # Issue scan requests in parallel or serially.
42
+ @concurrent_nodes = opt.fetch(:concurrent_nodes) { true }
43
+
44
+ # Indicates if bin data is retrieved. If false, only record digests (and
45
+ # user keys if stored on the server) are retrieved.
46
+ # Default is true.
47
+ @include_bin_data = opt.fetch(:include_bin_data) { true }
48
+
49
+ # Terminate scan if cluster in fluctuating state.
50
+ # Default is true.
51
+ @fail_on_cluster_change = opt.fetch(:fail_on_cluster_change) { true }
52
+
36
53
  @socket_timeout = opt[:socket_timeout] || 10000
37
- @max_retries = 0
54
+
55
+ # Number of records to place in queue before blocking. Records received
56
+ # from multiple server nodes will be placed in a queue. A separate thread
57
+ # consumes these records in parallel. If the queue is full, the producer
58
+ # threads will block until records are consumed.
59
+ # Default is 5000.
60
+ @record_queue_size = opt[:record_queue_size] || 5000
38
61
 
39
62
  self
40
63
  end
@@ -1,12 +1,13 @@
1
- # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
1
+ # Copyright 2014-2018 Aerospike, Inc.
3
2
  #
4
3
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
4
  # license agreements.
6
5
  #
7
6
  # Licensed under the Apache License, Version 2.0 (the "License"); you may not
8
7
  # 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
8
+ # the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
10
11
  #
11
12
  # Unless required by applicable law or agreed to in writing, software
12
13
  # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
@@ -24,9 +25,9 @@ module Aerospike
24
25
 
25
26
  private
26
27
 
27
- class StreamCommand < BatchCommand #:nodoc:
28
+ class StreamCommand < MultiCommand #:nodoc:
28
29
 
29
- def parse_record_results(receive_size)
30
+ def parse_group(receive_size)
30
31
  @data_offset = 0
31
32
 
32
33
  while @data_offset < receive_size
@@ -1,12 +1,13 @@
1
- # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
1
+ # Copyright 2014-2018 Aerospike, Inc.
3
2
  #
4
3
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
4
  # license agreements.
6
5
  #
7
6
  # Licensed under the Apache License, Version 2.0 (the "License"); you may not
8
7
  # 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
8
+ # the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
10
11
  #
11
12
  # Unless required by applicable law or agreed to in writing, software
12
13
  # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT