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.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/lib/neo4j/driver/exceptions/protocol_exception.rb +2 -2
- data/lib/neo4j/driver/internal/bolt_server_address.rb +6 -6
- data/lib/neo4j/driver/types/time.rb +4 -2
- data/ruby/neo4j/driver/config.rb +1 -1
- data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +1 -1
- data/ruby/neo4j/driver/internal/async/network_connection.rb +15 -22
- data/ruby/neo4j/driver/internal/async/network_session.rb +4 -3
- data/ruby/neo4j/driver/internal/async/pool/channel.rb +1 -0
- data/ruby/neo4j/driver/internal/async/pool/{netty_channel_tracker.rb → channel_tracker.rb} +6 -8
- data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +4 -3
- data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +10 -20
- data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +2 -2
- data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +37 -54
- data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +1 -4
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +6 -6
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +44 -80
- data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +6 -9
- data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +65 -155
- data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +2 -2
- data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +8 -12
- data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +19 -3
- data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +46 -67
- data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +42 -61
- data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +8 -10
- data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +2 -1
- data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +11 -14
- data/ruby/neo4j/driver/internal/database_name_util.rb +3 -3
- data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +1 -7
- data/ruby/neo4j/driver/internal/direct_connection_provider.rb +1 -1
- data/ruby/neo4j/driver/internal/driver_factory.rb +4 -4
- data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +11 -10
- data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +35 -25
- data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +1 -2
- data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +1 -1
- data/ruby/neo4j/driver/internal/impersonation_util.rb +2 -2
- data/ruby/neo4j/driver/internal/internal_bookmark.rb +1 -1
- data/ruby/neo4j/driver/internal/internal_database_name.rb +3 -5
- data/ruby/neo4j/driver/internal/internal_driver.rb +1 -1
- data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +3 -1
- data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +8 -2
- data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +8 -13
- data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +2 -3
- data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +2 -2
- data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +5 -10
- data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +5 -3
- data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +2 -2
- data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +1 -1
- data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +1 -1
- data/ruby/neo4j/driver/internal/read_only_bookmark_holder.rb +13 -0
- data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +35 -0
- data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +14 -9
- data/ruby/neo4j/driver/internal/util/error_util.rb +1 -1
- data/ruby/neo4j/driver/net/{server_address1.rb → server_address.rb} +2 -2
- data/ruby/neo4j/driver/query.rb +1 -1
- data/ruby/neo4j/driver/transaction_config.rb +5 -1
- data/ruby/neo4j/driver/values.rb +3 -3
- data/ruby/neo4j/driver/version.rb +1 -1
- metadata +11 -24
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a035a8385e54c70c851003ce4131072610617d515f118d2d4b03f6ada71de3a7
|
4
|
+
data.tar.gz: bc8dfddb76165d4aea25d702e1d4bb1be5db3bb375d25f48fab39acb7f247c07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
@@ -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
|
74
|
-
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
|
34
|
-
other.is_a?(self.class) && self.class.significant_fields.all? { |elem| 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
|
data/ruby/neo4j/driver/config.rb
CHANGED
@@ -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)
|
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.
|
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
|
-
|
36
|
+
@channel.auto_read = true if open?
|
37
37
|
end
|
38
38
|
|
39
39
|
def disable_auto_read
|
40
|
-
|
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
|
-
|
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
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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(
|
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
|
-
|
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
|
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
|
9
|
+
def initialize(metrics_listener, logger, **options)
|
10
10
|
@metrics_listener = metrics_listener
|
11
11
|
@log = logger
|
12
|
-
@all_channels = options[:channels]
|
13
|
-
@lock =
|
14
|
-
@
|
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
|
-
|
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
|
-
|
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
|
-
@
|
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
|
-
|
10
|
+
writers.present?
|
18
11
|
end
|
19
12
|
|
20
13
|
def has_routers_and_readers?
|
21
|
-
|
14
|
+
routers.present? && readers.present?
|
22
15
|
end
|
23
16
|
|
24
17
|
def self.parse(record, now)
|
25
|
-
return
|
26
|
-
new(expiration_timestamp: expiration_timestamp(now, record), database_name: record[
|
27
|
-
**record[
|
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
|
-
|
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 :
|
5
|
+
attr_reader :cluster_composition, :resolved_initial_routers
|
6
6
|
|
7
7
|
def initialize(composition, resolved_initial_routers = nil)
|
8
|
-
@
|
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
|
-
|
8
|
-
|
9
|
-
def initialize(of_database, clock, routing_addresses)
|
7
|
+
def initialize(of_database, _clock, *routing_addresses)
|
10
8
|
@database_name = of_database
|
11
|
-
@
|
12
|
-
@
|
13
|
-
@
|
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
|
-
|
23
|
-
@expiration_timestamp
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
52
|
+
@table_lock.with_read_lock { @readers }
|
60
53
|
end
|
61
54
|
|
62
55
|
def writers
|
63
|
-
|
56
|
+
@table_lock.with_read_lock { @writers }
|
64
57
|
end
|
65
58
|
|
66
59
|
def routers
|
67
|
-
|
60
|
+
@table_lock.with_read_lock { @routers }
|
68
61
|
end
|
69
62
|
|
70
63
|
def servers
|
71
|
-
|
72
|
-
|
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
|
-
|
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
|
-
|
85
|
+
@table_lock.with_read_lock { @prefer_initial_router }
|
93
86
|
end
|
94
87
|
|
95
88
|
def expiration_timestamp
|
96
|
-
|
89
|
+
@table_lock.with_read_lock { @expiration_timestamp }
|
97
90
|
end
|
98
91
|
|
99
92
|
def to_s
|
100
|
-
|
101
|
-
"Ttl #{@expiration_timestamp}, currentTime #{
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb
CHANGED
@@ -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
|
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 =
|
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
|
55
|
+
index = (index + 1) % size
|
56
56
|
|
57
|
-
break if 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}")
|