neo4j-ruby-driver 4.4.0.alpha.5 → 4.4.0.alpha.8
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/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/graph_database.rb +2 -2
- data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +2 -3
- data/ruby/neo4j/driver/internal/async/network_session.rb +4 -3
- 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 +3 -3
- data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +18 -20
- 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 +38 -55
- 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 +15 -19
- data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +31 -19
- data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +12 -15
- 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/commit_tx_response_handler.rb +4 -4
- data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +90 -51
- data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +33 -44
- data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +7 -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_result.rb +5 -5
- data/ruby/neo4j/driver/internal/internal_session.rb +1 -1
- data/ruby/neo4j/driver/internal/internal_transaction.rb +4 -4
- 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/abstract_streaming_message.rb +4 -1
- 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 +8 -4
- 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/internal/util/result_holder.rb +70 -0
- 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 +16 -14
- 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: d282964e01764e3a21d07c1e836567b3bc1f334e08d45b7392984db661faa14a
|
4
|
+
data.tar.gz: afc45978f3583f6f491c75c5f4f9da89099620d0be88c0367c8e9469554ecc20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a40657edbf022793691d6926f93ae779d4b671878cdbd29538a0ff83bd82de1912210380715390219503a1fbfb3ada37ae70cce66e6184664b1a90fbff12f80
|
7
|
+
data.tar.gz: 4ae8f0cb141fc923df3fc8bfab0696adb979a40331e76a440096eb64b3d8060a2f70e49934ed6af06015f734cc1d4f85468b0118b3231db1df4369ff93c0fa63
|
@@ -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
|
)
|
@@ -26,12 +26,12 @@ module Neo4j::Driver
|
|
26
26
|
)
|
27
27
|
end
|
28
28
|
|
29
|
-
def routing_driver(routing_uris,
|
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,
|
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
|
-
|
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(
|
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)
|
@@ -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
|
-
|
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
|
-
@
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
69
|
+
@commit_pending = Util::ResultHolder.new
|
68
70
|
nil
|
69
71
|
end
|
70
72
|
else
|
71
73
|
if @commit_pending
|
72
|
-
|
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 =
|
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
|
-
|
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::
|
176
|
+
Util::ResultHolder.failed(exception)
|
179
177
|
else
|
180
|
-
@protocol.commit_transaction(@connection
|
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::
|
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 { |
|
194
|
-
combined_error = Util::Futures.
|
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
|
-
|
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
|
-
def new_with_reused_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
|
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
|
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}")
|