neo4j-ruby-driver 4.4.0.alpha.4 → 4.4.0.alpha.7

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/lib/neo4j/driver/exceptions/protocol_exception.rb +2 -2
  4. data/lib/neo4j/driver/internal/bolt_server_address.rb +6 -6
  5. data/lib/neo4j/driver/types/time.rb +4 -2
  6. data/ruby/neo4j/driver/config.rb +1 -1
  7. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +1 -1
  8. data/ruby/neo4j/driver/internal/async/network_connection.rb +15 -22
  9. data/ruby/neo4j/driver/internal/async/network_session.rb +4 -3
  10. data/ruby/neo4j/driver/internal/async/pool/channel.rb +1 -0
  11. data/ruby/neo4j/driver/internal/async/pool/{netty_channel_tracker.rb → channel_tracker.rb} +6 -8
  12. data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +4 -3
  13. data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +10 -20
  14. data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +2 -2
  15. data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +37 -54
  16. data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +1 -4
  17. data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +6 -6
  18. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +44 -80
  19. data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +6 -9
  20. data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +65 -155
  21. data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +2 -2
  22. data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +8 -12
  23. data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +19 -3
  24. data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +46 -67
  25. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +42 -61
  26. data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +8 -10
  27. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +2 -1
  28. data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +11 -14
  29. data/ruby/neo4j/driver/internal/database_name_util.rb +3 -3
  30. data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +1 -7
  31. data/ruby/neo4j/driver/internal/direct_connection_provider.rb +1 -1
  32. data/ruby/neo4j/driver/internal/driver_factory.rb +4 -4
  33. data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +11 -10
  34. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +35 -25
  35. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +1 -2
  36. data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +1 -1
  37. data/ruby/neo4j/driver/internal/impersonation_util.rb +2 -2
  38. data/ruby/neo4j/driver/internal/internal_bookmark.rb +1 -1
  39. data/ruby/neo4j/driver/internal/internal_database_name.rb +3 -5
  40. data/ruby/neo4j/driver/internal/internal_driver.rb +1 -1
  41. data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +3 -1
  42. data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +8 -2
  43. data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +8 -13
  44. data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +2 -3
  45. data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +2 -2
  46. data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +5 -10
  47. data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +5 -3
  48. data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +2 -2
  49. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +1 -1
  50. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +1 -1
  51. data/ruby/neo4j/driver/internal/read_only_bookmark_holder.rb +13 -0
  52. data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +35 -0
  53. data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +14 -9
  54. data/ruby/neo4j/driver/internal/util/error_util.rb +1 -1
  55. data/ruby/neo4j/driver/net/{server_address1.rb → server_address.rb} +2 -2
  56. data/ruby/neo4j/driver/query.rb +1 -1
  57. data/ruby/neo4j/driver/transaction_config.rb +5 -1
  58. data/ruby/neo4j/driver/values.rb +3 -3
  59. data/ruby/neo4j/driver/version.rb +1 -1
  60. metadata +11 -24
  61. 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: dceecd30fd6fa4473c3ec6bb640b6126bd7bb06eb5057d58e46064d8c434a929
4
- data.tar.gz: 0e1a77da3ca678a1b4a201fa0d0211a771a009a77bb81b1a0c98e331b22c5471
3
+ metadata.gz: a035a8385e54c70c851003ce4131072610617d515f118d2d4b03f6ada71de3a7
4
+ data.tar.gz: bc8dfddb76165d4aea25d702e1d4bb1be5db3bb375d25f48fab39acb7f247c07
5
5
  SHA512:
6
- metadata.gz: fdd3c4bbdd314fb7036ce6c7fedba8a49e26b194450dea535a7aa05f380d58a6ab04ea7edbba6cf664514c1585084ad0e17c40fb719a9794f127ee3623c169db
7
- data.tar.gz: 673a7aa8a4f3192f7b9b15b91efaca7c05dfcb79779b39ed4f014989db06672f7c293fd3948e16fc515177cae84e428f5885b3f1d3b4c081f05e580afbd66b5d
6
+ metadata.gz: 17a1b5ada9f09120e7dda4316504d59fedf366696d27c26e87c5feeee381a876409a75eaa05cbc177af64415946af7ec8c1de7b4ed5e637ffc464a40c1fd4eea
7
+ data.tar.gz: aa41d20c4794dac6841aa1bf70cb0c3e8573a658e74d8aa4e475f45a2a0a9072056633a83f8744251014ab5a805b6ec368f4a75b036316c2179bc1bcc1f8f8fa
data/README.md CHANGED
@@ -42,6 +42,7 @@ This gem includes 2 different implementations: java driver wrapper and pure ruby
42
42
  ## Testing
43
43
 
44
44
  To run the tests the following tools need to be installed:
45
+
45
46
  $ brew install python
46
47
  $ pip3 install --user git+https://github.com/klobuczek/boltkit@1.3#egg=boltkit
47
48
  $ neoctrl-install -e 4.4.5 servers
@@ -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
  )
@@ -151,7 +151,7 @@ module Neo4j::Driver
151
151
  @auto_read_managing_handler.disable_auto_read_management
152
152
 
153
153
  # restore the default value of auto-read
154
- @channel.config.set_auto_read(true)
154
+ @channel.auto_read = true
155
155
  end
156
156
 
157
157
  @auto_read_managing_handler = new_handler
@@ -33,11 +33,11 @@ module Neo4j::Driver
33
33
  end
34
34
 
35
35
  def enable_auto_read
36
- set_auto_read(true) if open?
36
+ @channel.auto_read = true if open?
37
37
  end
38
38
 
39
39
  def disable_auto_read
40
- set_auto_read(false) if open?
40
+ @channel.auto_read = false if open?
41
41
  end
42
42
 
43
43
  def flush
@@ -69,13 +69,12 @@ module Neo4j::Driver
69
69
 
70
70
  def release
71
71
  if @status.compare_and_set(Status::OPEN, Status::RELEASED)
72
- @channel_pool.release(@channel)
72
+ handler = Handlers::ChannelReleasingResetResponseHandler.new(@channel, @channel_pool, @message_dispatcher, @log, @release)
73
+ write_reset_message_if_needed(handler, false)
74
+ # @metrics_listener.after_connection_released(Connection::ChannelAttributes.pool_id(@channel), @in_use_event)
75
+ # end
76
+ # @release_future
73
77
  end
74
- # handler = Handlers::ChannelReleasingResetResponseHandler.new(@channel, @channel_pool, @message_dispatcher, @clock, @release)
75
- # write_reset_message_if_needed(handler, false)
76
- # @metrics_listener.after_connection_released(Connection::ChannelAttributes.pool_id(@channel), @in_use_event)
77
- # end
78
- # @release_future
79
78
  end
80
79
 
81
80
  def terminate_and_release(reason)
@@ -91,15 +90,13 @@ module Neo4j::Driver
91
90
  private
92
91
 
93
92
  def write_reset_message_if_needed(reset_handler, is_session_reset)
94
- @channel.event_loop.execute do
95
- if is_session_reset && !open?
96
- reset_handler.on_success(java.util.Collections.empty_map)
97
- else
98
- # auto-read could've been disabled, re-enable it to automatically receive response for RESET
99
- set_auto_read(true)
100
- @message_dispatcher.enqueue(reset_handler)
101
- @channel.write_and_flush(Messaging::Request::ResetMessage::RESET).add_listener(-> (_future) { register_connection_read_timeout(@channel) })
102
- end
93
+ if is_session_reset && !open?
94
+ reset_handler.on_success
95
+ else
96
+ # auto-read could've been disabled, re-enable it to automatically receive response for RESET
97
+ @channel.auto_read = true
98
+ @message_dispatcher.enqueue(reset_handler)
99
+ @channel.write_and_flush(Messaging::Request::ResetMessage::RESET)#.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
103
100
  end
104
101
  end
105
102
 
@@ -114,7 +111,7 @@ module Neo4j::Driver
114
111
  @message_dispatcher.enqueue(handler)
115
112
 
116
113
  if flush
117
- @channel.write_and_flush(message)#.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
114
+ @channel.write_and_flush(message) #.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
118
115
  else
119
116
  @channel.write(message)
120
117
  end
@@ -135,10 +132,6 @@ module Neo4j::Driver
135
132
  end
136
133
  end
137
134
 
138
- def set_auto_read(value)
139
- @channel.config.set_auto_read(value)
140
- end
141
-
142
135
  def verify_open(handler1, handler2)
143
136
  connection_status = @status.get
144
137
 
@@ -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
@@ -6,6 +6,7 @@ module Neo4j::Driver
6
6
  attr :stream
7
7
  attr_accessor :version, :protocol, :message_format, :message_dispatcher
8
8
  attr :attributes # should be attr
9
+ attr_accessor :auto_read
9
10
 
10
11
  def initialize(address, connector, logger)
11
12
  super()
@@ -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)
@@ -20,6 +20,7 @@ module Neo4j::Driver
20
20
 
21
21
  begin
22
22
  channel = pool.acquire
23
+ @log.debug{"Channel #{channel.object_id} acquired"}
23
24
  rescue => error
24
25
  process_acquisition_error(pool, address, error)
25
26
  end
@@ -31,8 +32,7 @@ module Neo4j::Driver
31
32
  @address_to_pool_lock.with_write_lock do
32
33
  @address_to_pool.each do |address, pool|
33
34
  unless addresses_to_retain.include?(address)
34
- active_channels = @netty_channel_tracker.in_use_channel_count(address)
35
- if active_channels.zero?
35
+ unless pool.busy?
36
36
  # address is not present in updated routing table and has no active connections
37
37
  # it's now safe to terminate corresponding connection pool and forget about it
38
38
  @address_to_pool.delete(address)
@@ -47,7 +47,8 @@ module Neo4j::Driver
47
47
  end
48
48
 
49
49
  def in_use_connections(address)
50
- @netty_channel_tracker.in_use_channel_count(address)
50
+ @address_to_pool[address]&.size || 0
51
+ # @netty_channel_tracker.in_use_channel_count(address)
51
52
  end
52
53
 
53
54
  def idle_connections(address)
@@ -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
108
  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
109
+ (current_addresses + disused_addresses + new_addresses).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}")