aerospike 2.7.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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