aerospike 2.7.0 → 2.8.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.
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2016-2017 Aerospike, Inc.
2
+ # Copyright 2016-2018 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -16,22 +16,22 @@
16
16
 
17
17
  module Aerospike
18
18
  module CDT
19
-
20
19
  class MapPolicy
21
20
 
22
- attr_accessor :order, :write_mode
21
+ attr_accessor :order, :write_mode, :flags
22
+
23
+ def initialize(order: nil, write_mode: nil, flags: nil)
24
+ if write_mode && flags
25
+ raise ArgumentError, "Use write mode for server versions < 4.3; use write flags for server versions >= 4.3."
26
+ end
23
27
 
24
- def initialize(order: nil, write_mode: nil)
25
28
  @order = order || MapOrder::DEFAULT
26
29
  @write_mode = write_mode || MapWriteMode::DEFAULT
30
+ @flags = flags || MapWriteFlags::DEFAULT
27
31
  end
28
32
 
29
33
  DEFAULT = MapPolicy.new
30
34
 
31
- def value
32
- order.to_int
33
- end
34
35
  end
35
-
36
36
  end
37
37
  end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+ # Copyright 2018 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
+ module Aerospike
18
+ module CDT
19
+
20
+ ##
21
+ # Map write bit flags.
22
+ # Requires server versions >= 4.3.
23
+ module MapWriteFlags
24
+
25
+ ##
26
+ # Default. Allow create or update.
27
+ DEFAULT = 0
28
+
29
+ ##
30
+ # If the key already exists, the item will be denied.
31
+ # If the key does not exist, a new item will be created.
32
+ CREATE_ONLY = 1
33
+
34
+ ##
35
+ # If the key already exists, the item will be overwritten.
36
+ # If the key does not exist, the item will be denied.
37
+ UPDATE_ONLY = 2
38
+
39
+ ##
40
+ # Do not raise error, if a map item is denied due to write flag
41
+ # constraints.
42
+ NO_FAIL = 4
43
+
44
+ ##
45
+ # Allow other valid map items to be committed, if a map item is denied
46
+ # due to write flag constraints.
47
+ PARTIAL = 8
48
+
49
+ end
50
+ end
51
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2016-2017 Aerospike, Inc.
2
+ # Copyright 2016-2018 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -16,6 +16,12 @@
16
16
 
17
17
  module Aerospike
18
18
  module CDT
19
+
20
+ ##
21
+ # Unique key map write type.
22
+ #
23
+ # This enum should only be used for server versions < 4.3.
24
+ # MapWriteFlags are recommended for server versions >= 4.3.
19
25
  module MapWriteMode
20
26
 
21
27
  ##
@@ -430,6 +430,10 @@ module Aerospike
430
430
  ::Aerospike::Node.new(self, nv)
431
431
  end
432
432
 
433
+ def create_connection(host)
434
+ ::Aerospike::Cluster::CreateConnection.(self, host)
435
+ end
436
+
433
437
  def find_nodes_to_remove(refresh_count)
434
438
  FindNodesToRemove.(self, refresh_count)
435
439
  end
data/lib/aerospike/key.rb CHANGED
@@ -24,7 +24,7 @@ module Aerospike
24
24
  class Key
25
25
 
26
26
  @@digest_pool = Pool.new
27
- @@digest_pool.create_block = Proc.new do
27
+ @@digest_pool.create_proc = Proc.new do
28
28
  if RUBY_PLATFORM == 'java'
29
29
  OpenSSL::Digest::RIPEMD160.new
30
30
  else
@@ -52,19 +52,7 @@ module Aerospike
52
52
  @active = Atomic.new(true)
53
53
  @failures = Atomic.new(0)
54
54
 
55
- @connections = Pool.new(@cluster.connection_queue_size)
56
-
57
- # TODO: put in separate methods
58
- @connections.create_block = Proc.new do
59
- conn = nil
60
- loop do
61
- conn = Cluster::CreateConnection.(cluster, host)
62
- break if conn.connected?
63
- end
64
- conn
65
- end
66
-
67
- @connections.cleanup_block = Proc.new { |conn| conn.close if conn }
55
+ @connections = ::Aerospike::ConnectionPool.new(cluster, host)
68
56
  end
69
57
 
70
58
  # Get a connection to the node. If no cached connection is not available,
@@ -35,16 +35,8 @@ module Aerospike
35
35
  end
36
36
 
37
37
  def read_from_socket(length)
38
- begin
38
+ with_timeout(@timeout) do
39
39
  read_nonblock(length)
40
- rescue ::IO::WaitReadable => e
41
- if ::IO::select([self], nil, nil, @timeout)
42
- retry
43
- else
44
- raise ::Aerospike::Exceptions::Connection.new("#{e}")
45
- end
46
- rescue => e
47
- raise ::Aerospike::Exceptions::Connection.new("#{e}")
48
40
  end
49
41
  end
50
42
 
@@ -56,16 +48,8 @@ module Aerospike
56
48
  end
57
49
 
58
50
  def write_to_socket(data)
59
- begin
51
+ with_timeout(@timeout) do
60
52
  write_nonblock(data)
61
- rescue ::IO::WaitWritable => e
62
- if ::IO::select(nil, [self], nil, @timeout)
63
- retry
64
- else
65
- raise ::Aerospike::Exceptions::Connection.new("#{e}")
66
- end
67
- rescue => e
68
- raise ::Aerospike::Exceptions::Connection.new("#{e}")
69
53
  end
70
54
  end
71
55
 
@@ -77,10 +61,53 @@ module Aerospike
77
61
  !closed?
78
62
  end
79
63
 
64
+ # Returns whether the connection to the server is alive.
65
+ #
66
+ # It is useful to call this method before making a call to the server
67
+ # that would change data on the server.
68
+ #
69
+ # Note: This method is only useful if the server closed the connection or
70
+ # if a previous connection failure occurred. If the server is hard killed
71
+ # this will still return true until one or more writes are attempted.
72
+ def alive?
73
+ return false if closed?
74
+
75
+ if IO.select([self], nil, nil, 0)
76
+ !eof? rescue false
77
+ else
78
+ true
79
+ end
80
+ rescue IOError
81
+ false
82
+ end
83
+
80
84
  def close
81
85
  return if closed?
82
86
  super()
83
87
  end
88
+
89
+ private
90
+
91
+ # Note: For SSL connections, read_nonblock may invoke write system call,
92
+ # which may raise IO::WaitWritable, and vice versa, due to SSL
93
+ # renegotiation, so we should always rescue both.
94
+ def with_timeout(timeout, &block)
95
+ block.call
96
+ rescue IO::WaitReadable => e
97
+ if IO::select([self], nil, nil, timeout)
98
+ retry
99
+ else
100
+ fail Aerospike::Exceptions::Connection, "Socket timeout: #{e}"
101
+ end
102
+ rescue IO::WaitWritable => e
103
+ if IO::select(nil, [self], nil, timeout)
104
+ retry
105
+ else
106
+ fail Aerospike::Exceptions::Connection, "Socket timeout: #{e}"
107
+ end
108
+ rescue => e
109
+ raise Aerospike::Exceptions::Connection, "Socket error: #{e}"
110
+ end
84
111
  end
85
112
  end
86
113
  end
@@ -17,6 +17,8 @@
17
17
  # License for the specific language governing permissions and limitations under
18
18
  # the License.
19
19
 
20
+ require 'openssl'
21
+
20
22
  module Aerospike
21
23
  module Socket
22
24
  class SSL < ::OpenSSL::SSL::SSLSocket
@@ -27,7 +27,7 @@ module Aerospike
27
27
  class Buffer #:nodoc:
28
28
 
29
29
  @@buf_pool = Pool.new
30
- @@buf_pool.create_block = Proc.new { Buffer.new }
30
+ @@buf_pool.create_proc = Proc.new { Buffer.new }
31
31
 
32
32
  attr_accessor :buf
33
33
 
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ # Copyright 2017 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
+ module Aerospike
18
+ class ConnectionPool < Pool
19
+
20
+ attr_accessor :cluster, :host
21
+
22
+ def initialize(cluster, host)
23
+ self.cluster = cluster
24
+ self.host = host
25
+ super(cluster.connection_queue_size)
26
+ end
27
+
28
+ def create
29
+ conn = nil
30
+ loop do
31
+ conn = cluster.create_connection(host)
32
+ break if conn.connected?
33
+ end
34
+ conn
35
+ end
36
+
37
+ def check(conn)
38
+ conn.alive?
39
+ end
40
+
41
+ def cleanup(conn)
42
+ conn.close if conn
43
+ end
44
+ end
45
+ end
@@ -24,7 +24,7 @@ module Aerospike
24
24
  class Packer < MessagePack::Packer #:nodoc:
25
25
 
26
26
  @@pool = Pool.new
27
- @@pool.create_block = Proc.new { Packer.new }
27
+ @@pool.create_proc = Proc.new { Packer.new }
28
28
 
29
29
  def self.use
30
30
  packer = @@pool.poll
@@ -1,5 +1,5 @@
1
- # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
1
+ # frozen_string_literal: true
2
+ # Copyright 2014-2018 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -16,15 +16,14 @@
16
16
 
17
17
  module Aerospike
18
18
 
19
- private
20
-
21
19
  class Pool #:nodoc:
22
20
 
23
- attr_accessor :create_block, :cleanup_block
21
+ attr_accessor :create_proc, :cleanup_proc, :check_proc
24
22
 
25
23
  def initialize(max_size = 256, &block)
26
- @create_block = block
27
- @cleanup_block = nil
24
+ @create_proc = block
25
+ @cleanup_proc = nil
26
+ @check_proc = nil
28
27
 
29
28
  @pool = Queue.new
30
29
  @max_size = max_size
@@ -33,17 +32,24 @@ module Aerospike
33
32
  def offer(obj)
34
33
  if @pool.length < @max_size
35
34
  @pool << obj
36
- elsif @cleanup_block
37
- @cleanup_block.call(obj)
35
+ else
36
+ cleanup(obj)
38
37
  end
39
38
  end
40
39
  alias_method :<<, :offer
41
40
 
42
41
  def poll(create_new=true)
43
42
  non_block = true
44
- @pool.pop(non_block)
45
- rescue
46
- @create_block.call() if @create_block && create_new
43
+ begin
44
+ obj = @pool.pop(non_block)
45
+ if !check(obj)
46
+ cleanup(obj)
47
+ obj = nil
48
+ end
49
+ end until obj
50
+ obj
51
+ rescue ThreadError
52
+ create if create_new
47
53
  end
48
54
 
49
55
  def empty?
@@ -59,6 +65,23 @@ module Aerospike
59
65
  "#<Aerospike::Pool: size=#{size}>"
60
66
  end
61
67
 
68
+ protected
69
+
70
+ def create
71
+ return unless create_proc
72
+ create_proc.()
73
+ end
74
+
75
+ def check(obj)
76
+ return true unless check_proc
77
+ check_proc.(obj)
78
+ end
79
+
80
+ def cleanup(obj)
81
+ return unless cleanup_proc
82
+ cleanup_proc.(obj)
83
+ end
84
+
62
85
  end
63
86
 
64
87
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2016-2017 Aerospike, Inc.
2
+ # Copyright 2016-2018 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -24,7 +24,7 @@ module Aerospike
24
24
  class Unpacker
25
25
 
26
26
  @@pool = Pool.new
27
- @@pool.create_block = Proc.new { Unpacker.new }
27
+ @@pool.create_proc = Proc.new { Unpacker.new }
28
28
 
29
29
  def self.use
30
30
  unpacker = @@pool.poll
@@ -36,9 +36,9 @@ module Aerospike
36
36
 
37
37
  MsgPackExt = Struct.new(:type, :data)
38
38
  MsgPackExt::TYPES = [
39
- # Map Create Flags:
40
- 0x00, # UNORDERED
41
- 0x01, # K_ORDERED
39
+ # Map Create Flags: List Create Flags:
40
+ 0x00, # UNORDERED UNORDERED
41
+ 0x01, # K_ORDERED ORDERED
42
42
  0x03, # KV_ORDERED
43
43
  0x08, # PRESERVE_ORDER
44
44
  ]
@@ -66,12 +66,16 @@ module Aerospike
66
66
  private
67
67
 
68
68
  def unpack_list(array)
69
- normalize_strings_in_array(array)
69
+ list = normalize_strings_in_array(array)
70
+ unless list.empty?
71
+ list.shift if MsgPackExt === list.first
72
+ end
73
+ list
70
74
  end
71
75
 
72
76
  def unpack_map(hash)
73
77
  hash = normalize_strings_in_map(hash)
74
- if hash.any?
78
+ unless hash.empty?
75
79
  (key, _) = hash.first
76
80
  hash.shift if MsgPackExt === key
77
81
  end