neo4j-ruby-driver 4.4.0.alpha.5 → 4.4.0.alpha.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/lib/neo4j/driver/exceptions/protocol_exception.rb +2 -2
  3. data/lib/neo4j/driver/internal/bolt_server_address.rb +6 -6
  4. data/lib/neo4j/driver/types/time.rb +4 -2
  5. data/ruby/neo4j/driver/config.rb +1 -1
  6. data/ruby/neo4j/driver/graph_database.rb +2 -2
  7. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +2 -3
  8. data/ruby/neo4j/driver/internal/async/network_session.rb +4 -3
  9. data/ruby/neo4j/driver/internal/async/pool/{netty_channel_tracker.rb → channel_tracker.rb} +6 -8
  10. data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +3 -3
  11. data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +18 -20
  12. data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +10 -20
  13. data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +2 -2
  14. data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +38 -55
  15. data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +1 -4
  16. data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +6 -6
  17. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +44 -80
  18. data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +6 -9
  19. data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +65 -155
  20. data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +2 -2
  21. data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +8 -12
  22. data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +19 -3
  23. data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +46 -67
  24. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +42 -61
  25. data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +15 -19
  26. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +31 -19
  27. data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +12 -15
  28. data/ruby/neo4j/driver/internal/database_name_util.rb +3 -3
  29. data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +1 -7
  30. data/ruby/neo4j/driver/internal/direct_connection_provider.rb +1 -1
  31. data/ruby/neo4j/driver/internal/driver_factory.rb +4 -4
  32. data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +4 -4
  33. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +90 -51
  34. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +33 -44
  35. data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +7 -1
  36. data/ruby/neo4j/driver/internal/impersonation_util.rb +2 -2
  37. data/ruby/neo4j/driver/internal/internal_bookmark.rb +1 -1
  38. data/ruby/neo4j/driver/internal/internal_database_name.rb +3 -5
  39. data/ruby/neo4j/driver/internal/internal_result.rb +5 -5
  40. data/ruby/neo4j/driver/internal/internal_session.rb +1 -1
  41. data/ruby/neo4j/driver/internal/internal_transaction.rb +4 -4
  42. data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +3 -1
  43. data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +8 -2
  44. data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +8 -13
  45. data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +4 -1
  46. data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +2 -3
  47. data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +2 -2
  48. data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +5 -10
  49. data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +5 -3
  50. data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +2 -2
  51. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +8 -4
  52. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +1 -1
  53. data/ruby/neo4j/driver/internal/read_only_bookmark_holder.rb +13 -0
  54. data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +35 -0
  55. data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +14 -9
  56. data/ruby/neo4j/driver/internal/util/error_util.rb +1 -1
  57. data/ruby/neo4j/driver/internal/util/result_holder.rb +70 -0
  58. data/ruby/neo4j/driver/net/{server_address1.rb → server_address.rb} +2 -2
  59. data/ruby/neo4j/driver/query.rb +1 -1
  60. data/ruby/neo4j/driver/transaction_config.rb +5 -1
  61. data/ruby/neo4j/driver/values.rb +3 -3
  62. data/ruby/neo4j/driver/version.rb +1 -1
  63. metadata +16 -14
  64. data/ruby/neo4j/driver/internal/database_name.rb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92d999b42ad79f180328388f8b50e610e35190b2efc0b5ad9f799773a3d5d006
4
- data.tar.gz: 759f1058c5dcf0c12d970dec2793bd2f6a5600aecfcdeb43f63b19630f038fb2
3
+ metadata.gz: d282964e01764e3a21d07c1e836567b3bc1f334e08d45b7392984db661faa14a
4
+ data.tar.gz: afc45978f3583f6f491c75c5f4f9da89099620d0be88c0367c8e9469554ecc20
5
5
  SHA512:
6
- metadata.gz: 50d2744664faa1596e8fe964db0b083e216f58b001a4d3d7d70218752814a164d4e83ea71f5d4b4b2330432aa58d74b12875ea182bb8f99aad701a831032cc73
7
- data.tar.gz: 5d8f9e3e8eb358d7aa494d7be74d3ee49507ff2496f346d0b5ab9defea5c92a6017e147ae51b0e128728a667ef924cdf8b7e13f69ff398a1f6f6606d24cddeef
6
+ metadata.gz: 0a40657edbf022793691d6926f93ae779d4b671878cdbd29538a0ff83bd82de1912210380715390219503a1fbfb3ada37ae70cce66e6184664b1a90fbff12f80
7
+ data.tar.gz: 4ae8f0cb141fc923df3fc8bfab0696adb979a40331e76a440096eb64b3d8060a2f70e49934ed6af06015f734cc1d4f85468b0118b3231db1df4369ff93c0fa63
@@ -8,8 +8,8 @@ module Neo4j
8
8
  class ProtocolException < Neo4jException
9
9
  CODE = "Protocol violation: "
10
10
 
11
- def initialize(message, e)
12
- super("#{CODE}message", e)
11
+ def initialize(message, e = nil)
12
+ super(nil, "#{CODE}#{message}", e)
13
13
  end
14
14
  end
15
15
  end
@@ -67,13 +67,15 @@ module Neo4j::Driver
67
67
  LOCAL_DEFAULT = new(host: 'localhost', port: DEFAULT_PORT)
68
68
 
69
69
  def self.from(address)
70
- address.is_a?(BoltServerAddress) ? address : new(address.host, address.port)
70
+ address.is_a?(BoltServerAddress) ? address : new(host: address.host, port: address.port)
71
71
  end
72
72
 
73
- def eql?(other)
74
- attributes.eql?(other&.attributes)
73
+ def ==(other)
74
+ attributes == other&.attributes
75
75
  end
76
76
 
77
+ alias eql? ==
78
+
77
79
  def to_s
78
80
  "#{host}#{"(#{connection_host})" unless host == connection_host}:#{port}"
79
81
  end
@@ -84,11 +86,9 @@ module Neo4j::Driver
84
86
 
85
87
  # @return stream of unicast addresses.
86
88
  def unicast_stream
87
- [self]
89
+ Set[self]
88
90
  end
89
91
 
90
- private
91
-
92
92
  def attributes
93
93
  [@host, @connection_host, @port]
94
94
  end
@@ -30,10 +30,12 @@ module Neo4j
30
30
  end
31
31
  end
32
32
 
33
- def eql?(other)
34
- other.is_a?(self.class) && self.class.significant_fields.all? { |elem| send(elem).eql?(other.send(elem)) }
33
+ def ==(other)
34
+ other.is_a?(self.class) && self.class.significant_fields.all? { |elem| send(elem) == other.send(elem) }
35
35
  end
36
36
 
37
+ alias eql? ==
38
+
37
39
  def +(numeric)
38
40
  self.class.new(@time + numeric)
39
41
  end
@@ -79,7 +79,7 @@ module Neo4j
79
79
 
80
80
  def init_security_and_trust_config
81
81
  relevant = %i[encryption trust_strategy]
82
- customized = slice(*relevant) == DEFAULTS.slice(*relevant)
82
+ customized = slice(*relevant) != DEFAULTS.slice(*relevant)
83
83
  merge!(security_settings: Neo4j::Driver::Internal::SecuritySetting.new(
84
84
  fetch(:encryption), TrustStrategy.new(**fetch(:trust_strategy)), customized),
85
85
  )
@@ -26,12 +26,12 @@ module Neo4j::Driver
26
26
  )
27
27
  end
28
28
 
29
- def routing_driver(routing_uris, auth_toke, **config)
29
+ def routing_driver(routing_uris, auth_token, **config)
30
30
  assert_routing_uris(routing_uris)
31
31
  log = Config.new(**config)[:logger]
32
32
 
33
33
  routing_uris.each do |uri|
34
- driver = driver(uri, auth_toke, **config)
34
+ driver = driver(uri, auth_token, **config)
35
35
  begin
36
36
  return driver.tap(&:verify_connectivity)
37
37
  rescue Exceptions::ServiceUnavailableException => e
@@ -59,7 +59,8 @@ module Neo4j::Driver
59
59
  raise @current_error if Util::ErrorUtil.fatal?(@current_error) # TODO clarify
60
60
 
61
61
  if @current_error.is_a?(Exceptions::AuthorizationExpiredException)
62
- Connection::ChannelAttributes.authorization_state_listener(@channel).on_expired(@current_error, @channel)
62
+ # TODO: ??????
63
+ # Connection::ChannelAttributes.authorization_state_listener(@channel).on_expired(@current_error, @channel)
63
64
  else
64
65
  # write a RESET to "acknowledge" the failure
65
66
  enqueue(Handlers::ResetResponseHandler.new(self))
@@ -115,8 +116,6 @@ module Neo4j::Driver
115
116
  end
116
117
 
117
118
  def clear_current_error
118
- raise @current_error if @current_error
119
- ensure
120
119
  @current_error = nil
121
120
  end
122
121
 
@@ -10,8 +10,8 @@ module Neo4j::Driver
10
10
  @retry_logic = retry_logic
11
11
  @log = Logging::PrefixedLogger.new("[#{hash}]", logger)
12
12
  @bookmark_holder = bookmark_holder
13
- @database_name = database_name.database_name
14
- @connection_context = NetworkSessionConnectionContext.new(@database_name, @bookmark_holder.bookmark, impersonated_user)
13
+ # @database_name = database_name.database_name
14
+ @connection_context = NetworkSessionConnectionContext.new(database_name, @bookmark_holder.bookmark, impersonated_user)
15
15
  @fetch_size = fetch_size
16
16
  @open = Concurrent::AtomicBoolean.new(true)
17
17
  end
@@ -133,7 +133,8 @@ module Neo4j::Driver
133
133
  # This bookmark is only used for rediscovery.
134
134
  # It has to be the initial bookmark given at the creation of the session.
135
135
  # As only that bookmark could carry extra system bookmarks
136
- attr_reader :database_name, :mode, :rediscovery_bookmark, :impersonated_user
136
+ attr_accessor :database_name
137
+ attr :mode, :rediscovery_bookmark, :impersonated_user
137
138
 
138
139
  def initialize(database_name, bookmark, impersonated_user)
139
140
  @database_name = database_name
@@ -2,22 +2,20 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Async
4
4
  module Pool
5
- class NettyChannelTracker
5
+ class ChannelTracker
6
6
  attr_reader :lock, :read, :write, :address_to_in_use_channel_count, :address_to_idle_channel_count, :log,
7
7
  :metrics_listener, :close_listener, :all_channels
8
8
 
9
- def initialize(metrics_listener, logger, options = {},event_executor = nil, channels = nil)
9
+ def initialize(metrics_listener, logger, **options)
10
10
  @metrics_listener = metrics_listener
11
11
  @log = logger
12
- @all_channels = options[:channels] ? channels : Java::IoNettyChannelGroup::DefaultChannelGroup.new("all-connections", options[:event_executor])
13
- @lock = java.util.concurrent.locks.ReentrantReadWriteLock.new
14
- @read = lock.read_lock
15
- @write = lock.write_lock
16
- @close_listener = -> (future) { channel_closed(future.channel) }
12
+ @all_channels = options[:channels]
13
+ @lock = Concurrent::ReentrantReadWriteLock.new
14
+ @close_listener = method(:channel_closed)
17
15
  end
18
16
 
19
17
  def channel_released(channel)
20
- do_in_write_lock do
18
+ @lock.with_write_lock do
21
19
  decrement_in_use(channel)
22
20
  increment_idle(channel)
23
21
  channel.close_future.add_listener(close_listener)
@@ -32,8 +32,7 @@ module Neo4j::Driver
32
32
  @address_to_pool_lock.with_write_lock do
33
33
  @address_to_pool.each do |address, pool|
34
34
  unless addresses_to_retain.include?(address)
35
- active_channels = @netty_channel_tracker.in_use_channel_count(address)
36
- if active_channels.zero?
35
+ unless pool.busy?
37
36
  # address is not present in updated routing table and has no active connections
38
37
  # it's now safe to terminate corresponding connection pool and forget about it
39
38
  @address_to_pool.delete(address)
@@ -48,7 +47,8 @@ module Neo4j::Driver
48
47
  end
49
48
 
50
49
  def in_use_connections(address)
51
- @netty_channel_tracker.in_use_channel_count(address)
50
+ @address_to_pool[address]&.size || 0
51
+ # @netty_channel_tracker.in_use_channel_count(address)
52
52
  end
53
53
 
54
54
  def idle_connections(address)
@@ -52,28 +52,30 @@ module Neo4j::Driver
52
52
  def close_async(commit = false, complete_with_null_if_not_open = true)
53
53
  @lock.synchronize do
54
54
  if complete_with_null_if_not_open && !open?
55
- nil
55
+ Util::ResultHolder.successful(nil)
56
56
  elsif @state == State::COMMITTED
57
- raise Neo4j::Driver::Exceptions::ClientException, commit ? CANT_COMMIT_COMMITTED_MSG : CANT_ROLLBACK_COMMITTED_MSG
57
+ Util::ResultHolder.failed(Neo4j::Driver::Exceptions::ClientException.new(
58
+ commit ? CANT_COMMIT_COMMITTED_MSG : CANT_ROLLBACK_COMMITTED_MSG))
58
59
  elsif @state == State::ROLLED_BACK
59
- raise Neo4j::Driver::Exceptions::ClientException, commit ? CANT_COMMIT_ROLLED_BACK_MSG : CANT_ROLLBACK_ROLLED_BACK_MSG
60
+ Util::ResultHolder.failed(Neo4j::Driver::Exceptions::ClientException.new(
61
+ commit ? CANT_COMMIT_ROLLED_BACK_MSG : CANT_ROLLBACK_ROLLED_BACK_MSG))
60
62
  else
61
63
  if commit
62
64
  if @rollback_pending
63
- raise Neo4j::Driver::Exceptions::ClientException, CANT_COMMIT_ROLLING_BACK_MSG
65
+ Util::ResultHolder.failed(Neo4j::Driver::Exceptions::ClientException.new(CANT_COMMIT_ROLLING_BACK_MSG))
64
66
  elsif @commit_pending
65
67
  @commit_pending
66
68
  else
67
- @commit_pending = true
69
+ @commit_pending = Util::ResultHolder.new
68
70
  nil
69
71
  end
70
72
  else
71
73
  if @commit_pending
72
- raise Neo4j::Driver::Exceptions::ClientException, CANT_ROLLBACK_COMMITTING_MSG
74
+ Util::ResultHolder.failed(Neo4j::Driver::Exceptions::ClientException.new(CANT_ROLLBACK_COMMITTING_MSG))
73
75
  elsif @rollback_pending
74
76
  @rollback_pending
75
77
  else
76
- @rollback_pending = true
78
+ @rollback_pending = Util::ResultHolder.new
77
79
  nil
78
80
  end
79
81
  end
@@ -83,22 +85,18 @@ module Neo4j::Driver
83
85
  if commit
84
86
  target_future = @commit_pending
85
87
  target_action = lambda { |throwable|
86
- do_commit_async(throwable)
87
- handle_commit_or_rollback(throwable)
88
+ do_commit_async(throwable).chain(&handle_commit_or_rollback(throwable))
88
89
  }
89
90
  else
90
91
  target_future = @rollback_pending
91
92
  target_action = lambda { |throwable|
92
- do_rollback_async
93
- handle_commit_or_rollback(throwable)
93
+ do_rollback_async.chain(&handle_commit_or_rollback(throwable))
94
94
  }
95
95
  end
96
96
 
97
97
  @result_cursors.retrieve_not_consumed_error.then(&target_action)
98
- handle_transaction_completion(commit, nil)
98
+ .side { |_, error| handle_transaction_completion(commit, error) }.copy_to(target_future)
99
99
  target_future
100
- rescue => throwable
101
- handle_transaction_completion(commit, throwable)
102
100
  end
103
101
  end
104
102
 
@@ -148,7 +146,7 @@ module Neo4j::Driver
148
146
  raise Neo4j::Driver::Exceptions::ClientException, 'Cannot run more queries in this transaction, it has been rolled back'
149
147
  when State::TERMINATED
150
148
  # TODO clunky positional arguments of Neo4jException#initialize, move to named parameters
151
- raise Neo4j::Driver::Exceptions::ClientException, 'Cannot run more queries in this transaction, it has either experienced an fatal error or was explicitly terminated'#, # TODO should be able to pass @cause_of_termination
149
+ raise Neo4j::Driver::Exceptions::ClientException, 'Cannot run more queries in this transaction, it has either experienced an fatal error or was explicitly terminated' #, # TODO should be able to pass @cause_of_termination
152
150
  end
153
151
  end
154
152
  end
@@ -175,23 +173,23 @@ module Neo4j::Driver
175
173
  end
176
174
 
177
175
  if exception
178
- Util::Futures.failed_future(exception)
176
+ Util::ResultHolder.failed(exception)
179
177
  else
180
- @protocol.commit_transaction(@connection, @bookmark_holder)
178
+ @protocol.commit_transaction(@connection).then(&@bookmark_holder.method(:bookmark=))
181
179
  end
182
180
  end
183
181
 
184
182
  def do_rollback_async
185
183
  if @lock.synchronize { @state } == State::TERMINATED
186
- Util::Futures.completed_with_null
184
+ Util::ResultHolder.successful(nil)
187
185
  else
188
186
  @protocol.rollback_transaction(@connection)
189
187
  end
190
188
  end
191
189
 
192
190
  def handle_commit_or_rollback(cursor_failure)
193
- lambda { |_fulfilled, _value, commit_or_rollback_error|
194
- combined_error = Util::Futures.combined_error(cursor_failure, commit_or_rollback_error)
191
+ lambda { |_value, commit_or_rollback_error|
192
+ combined_error = Util::Futures.combine_errors(cursor_failure, commit_or_rollback_error)
195
193
  raise combined_error if combined_error
196
194
  }
197
195
  end
@@ -2,45 +2,35 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Cluster
4
4
  class ClusterComposition < Struct.new(:expiration_timestamp, :readers, :writers, :routers, :database_name)
5
- private
6
-
7
- MAX_LONG = 2 ^ 63 - 1
8
- MAX_TTL = MAX_LONG / 1000
9
-
10
- public
11
-
12
5
  def initialize(expiration_timestamp:, database_name:, readers: [], writers: [], routers: [])
13
6
  super(expiration_timestamp, readers, writers, routers, database_name)
14
7
  end
15
8
 
16
9
  def has_writers?
17
- @writers.present?
10
+ writers.present?
18
11
  end
19
12
 
20
13
  def has_routers_and_readers?
21
- @routers.present? && @readers.present?
14
+ routers.present? && readers.present?
22
15
  end
23
16
 
24
17
  def self.parse(record, now)
25
- return if record.nil?
26
- new(expiration_timestamp: expiration_timestamp(now, record), database_name: record['db'],
27
- **record['servers'].to_h { |value| [servers(value['role']), BoltServerAddress.new(value['addresses'])] })
18
+ return unless record
19
+ new(expiration_timestamp: expiration_timestamp(now, record), database_name: record[:db],
20
+ **record[:servers].to_h do |value|
21
+ [servers(value[:role]),
22
+ value[:addresses].map { |address| BoltServerAddress.new(uri: BoltServerAddress.uri_from(address)) }]
23
+ end)
28
24
  end
29
25
 
30
26
  private
31
27
 
32
28
  def self.expiration_timestamp(now, record)
33
29
  ttl = record['ttl']
34
- expiration_timestamp = now + ttl * 1000
35
-
36
- if ttl < 0 || ttl >= MAX_TTL || expiration_timestamp < 0
37
- expiration_timestamp = MAX_LONG
38
- end
39
-
40
- expiration_timestamp
30
+ now + (ttl.negative? ? 1000.years : ttl.seconds)
41
31
  end
42
32
 
43
- def servers(role)
33
+ def self.servers(role)
44
34
  case role
45
35
  when 'READ'
46
36
  :readers
@@ -2,10 +2,10 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Cluster
4
4
  class ClusterCompositionLookupResult
5
- attr_reader :composition, :resolved_initial_routers
5
+ attr_reader :cluster_composition, :resolved_initial_routers
6
6
 
7
7
  def initialize(composition, resolved_initial_routers = nil)
8
- @composition = composition
8
+ @cluster_composition = composition
9
9
  @resolved_initial_routers = resolved_initial_routers
10
10
  end
11
11
  end
@@ -4,39 +4,32 @@ module Neo4j::Driver
4
4
  class ClusterRoutingTable
5
5
  MIN_ROUTERS = 1
6
6
 
7
- attr_reader :database_name
8
-
9
- def initialize(of_database, clock, routing_addresses)
7
+ def initialize(of_database, _clock, *routing_addresses)
10
8
  @database_name = of_database
11
- @clock = clock
12
- @expiration_timestamp = clock.millis - 1
13
- @routers = routing_addresses.freeze
14
- @table_lock = java.util.concurrent.locks.ReentrantReadWriteLock.new
9
+ @expiration_timestamp = Time.now
10
+ @routers = routing_addresses.to_set.freeze
11
+ @table_lock = Concurrent::ReentrantReadWriteLock.new
15
12
  @prefer_initial_router = true
16
- @disused = {}
17
- @readers = []
18
- @writers = []
13
+ @disused = Set.new
14
+ @readers = Set.new
15
+ @writers = Set.new
19
16
  end
20
17
 
21
18
  def stale_for?(mode)
22
- Util::LockUtil.execute_with_lock(@table_lock.read_lock) do
23
- @expiration_timestamp < @clock.millis ||
24
- routers.size < MIN_ROUTERS ||
25
- (mode == AccessMode::READ && @readers.size == 0) ||
26
- (mode == AccessMode::WRITE && @writers.size == 0)
19
+ @table_lock.with_read_lock do
20
+ @expiration_timestamp <= Time.now ||
21
+ routers.size < MIN_ROUTERS ||
22
+ (mode == AccessMode::READ && @readers.size == 0) ||
23
+ (mode == AccessMode::WRITE && @writers.size == 0)
27
24
  end
28
25
  end
29
26
 
30
27
  def has_been_stale_for?(extra_time)
31
- total_time = Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @expiration_timestamp }) + extra_time
32
-
33
- total_time = java.lang.Long::MAX_VALUE if total_time < 0
34
-
35
- total_time < @clock.millis
28
+ Time.now - @table_lock.with_read_lock { @expiration_timestamp } >= extra_time
36
29
  end
37
30
 
38
31
  def update(cluster)
39
- Util::LockUtil.execute_with_lock(@table_lock.write_lock) do
32
+ @table_lock.with_write_lock do
40
33
  @expiration_timestamp = cluster.expiration_timestamp
41
34
  @readers = new_with_reused_addresses(@readers, @disused, cluster.readers)
42
35
  @writers = new_with_reused_addresses(@writers, @disused, cluster.writers)
@@ -47,7 +40,7 @@ module Neo4j::Driver
47
40
  end
48
41
 
49
42
  def forget(address)
50
- Util::LockUtil.execute_with_lock(@table_lock.write_lock) do
43
+ @table_lock.with_write_lock do
51
44
  @routers = new_without_address_if_present(@routers, address)
52
45
  @readers = new_without_address_if_present(@readers, address)
53
46
  @writers = new_without_address_if_present(@writers, address)
@@ -56,27 +49,27 @@ module Neo4j::Driver
56
49
  end
57
50
 
58
51
  def readers
59
- Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @readers })
52
+ @table_lock.with_read_lock { @readers }
60
53
  end
61
54
 
62
55
  def writers
63
- Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @writers })
56
+ @table_lock.with_read_lock { @writers }
64
57
  end
65
58
 
66
59
  def routers
67
- Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @routers })
60
+ @table_lock.with_read_lock { @routers }
68
61
  end
69
62
 
70
63
  def servers
71
- Util::LockUtil.execute_with_lock(@table_lock.write_lock) do
72
- servers = []
73
- servers << (@readers)
74
- servers << (@writers)
75
- servers << (@routers)
76
- servers << (@disused)
64
+ @table_lock.with_write_lock do
65
+ [@readers, @writers, @routers, @disused].reduce(&:+)
77
66
  end
78
67
  end
79
68
 
69
+ def database
70
+ @database_name
71
+ end
72
+
80
73
  def forget_writer(to_remove)
81
74
  Util::LockUtil.execute_with_lock(@table_lock.write_lock) do
82
75
  @writers = new_without_address_if_present(@writers, to_remove)
@@ -85,53 +78,43 @@ module Neo4j::Driver
85
78
  end
86
79
 
87
80
  def replace_router_if_present(old_router, new_router)
88
- Util::LockUtil.execute_with_lock(@table_lock.write_lock, -> () { @routers = new_with_address_replaced_if_present(@routers, old_router, new_router) } )
81
+ @table_lock.with_write_lock { @routers = new_with_address_replaced_if_present(@routers, old_router, new_router) }
89
82
  end
90
83
 
91
84
  def prefer_initial_router
92
- Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @prefer_initial_router })
85
+ @table_lock.with_read_lock { @prefer_initial_router }
93
86
  end
94
87
 
95
88
  def expiration_timestamp
96
- Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @expiration_timestamp })
89
+ @table_lock.with_read_lock { @expiration_timestamp }
97
90
  end
98
91
 
99
92
  def to_s
100
- Util::LockUtil.execute_with_lock(@table_lock.read_lock) do
101
- "Ttl #{@expiration_timestamp}, currentTime #{@clock.millis}, routers #{@routers}, writers #{@writers}, readers #{@readers}, database '#{database_name.description}'"
93
+ @table_lock.with_read_lock do
94
+ "Ttl #{@expiration_timestamp}, currentTime #{Time.now}, routers #{@routers}, writers #{@writers}, readers #{@readers}, database '#{@database_name.description}'"
102
95
  end
103
96
  end
104
97
 
105
98
  private
106
99
 
107
100
  def new_without_address_if_present(addresses, address_to_skip)
108
- new_list = []
109
-
110
- addresses.each do |address|
111
- new_list << address unless address.eql?(address_to_skip)
112
- end
113
-
114
- new_list.freeze
101
+ (addresses - [address_to_skip]).freeze
115
102
  end
116
103
 
117
104
  def new_with_address_replaced_if_present(addresses, old_address, new_address)
118
- new_list = []
119
-
120
- addresses.each { |address| new_list << address.eql?(old_address) ? new_address : address }
121
-
122
- new_list.freeze
105
+ addresses.map { |address| address == old_address ? new_address : address }.freeze
123
106
  end
124
107
 
125
- def new_with_reused_addresses(current_addresses, disused_addresses, new_addresses)
126
- new_list = java.util.stream.Stream.concat(current_addresses.stream, disused_addresses.stream)
127
- .filter(-> (address) { new_addresses.remove(to_bolt_server_address(address)) })
128
- .collect(java.util.stream.Collectors.to_collection(-> () { Array.new(new_addresses.size) }))
129
- new_list << new_addresses
130
- new_list.freeze
108
+ def new_with_reused_addresses(*addresses)
109
+ addresses.map(&:to_set).reduce(&:+).freeze
131
110
  end
132
111
 
133
112
  def to_bolt_server_address(address)
134
- BoltServerAddress.class.eql?(address.class) ? address : BoltServerAddress.new(address.host, address.port)
113
+ if BoltServerAddress.class == address.class
114
+ address
115
+ else
116
+ BoltServerAddress.new(host: address.host, port: address.port)
117
+ end
135
118
  end
136
119
  end
137
120
  end
@@ -3,10 +3,7 @@ module Neo4j::Driver
3
3
  module Cluster
4
4
  class IdentityResolver
5
5
  IDENTITY_RESOLVER = new
6
-
7
- def resolve(initial_router)
8
- java.util.Collections.singleton(initial_router)
9
- end
6
+ alias resolve Array
10
7
  end
11
8
  end
12
9
  end
@@ -28,10 +28,9 @@ module Neo4j::Driver
28
28
 
29
29
  def select(addresses, addresses_index, address_type)
30
30
  size = addresses.size
31
-
32
31
  if size == 0
33
32
  @log.debug("Unable to select #{address_type}, no known addresses given")
34
- return nil
33
+ return
35
34
  end
36
35
 
37
36
  # choose start index for iteration in round-robin fashion
@@ -39,22 +38,23 @@ module Neo4j::Driver
39
38
  index = start_index
40
39
 
41
40
  least_connected_address = nil
42
- least_active_connections = java.lang.Integer::MAX_VALUE
41
+ least_active_connections = nil
43
42
 
44
43
  # iterate over the array to find the least connected address
44
+ addresses = addresses.to_a
45
45
  loop do
46
46
  address = addresses[index]
47
47
  active_connections = @connection_pool.in_use_connections(address)
48
48
 
49
- if active_connections < least_active_connections
49
+ if least_active_connections.nil? || active_connections < least_active_connections
50
50
  least_connected_address = address
51
51
  least_active_connections = active_connections
52
52
  end
53
53
 
54
54
  # loop over to the start of the array when end is reached
55
- index = (index == size - 1) ? 0 : index += 1
55
+ index = (index + 1) % size
56
56
 
57
- break if index != start_index
57
+ break if index == start_index
58
58
  end
59
59
 
60
60
  @log.debug("Selected #{address_type} with address: '#{least_connected_address}' and active connections: #{least_active_connections}")