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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) 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/internal/async/network_session.rb +4 -3
  6. data/ruby/neo4j/driver/internal/async/pool/{netty_channel_tracker.rb → channel_tracker.rb} +6 -8
  7. data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +3 -3
  8. data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +10 -20
  9. data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +2 -2
  10. data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +37 -54
  11. data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +1 -4
  12. data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +6 -6
  13. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +44 -80
  14. data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +6 -9
  15. data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +65 -155
  16. data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +2 -2
  17. data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +8 -12
  18. data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +19 -3
  19. data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +46 -67
  20. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +42 -61
  21. data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +8 -10
  22. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +2 -1
  23. data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +11 -14
  24. data/ruby/neo4j/driver/internal/database_name_util.rb +3 -3
  25. data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +1 -7
  26. data/ruby/neo4j/driver/internal/direct_connection_provider.rb +1 -1
  27. data/ruby/neo4j/driver/internal/driver_factory.rb +4 -4
  28. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +34 -24
  29. data/ruby/neo4j/driver/internal/impersonation_util.rb +2 -2
  30. data/ruby/neo4j/driver/internal/internal_bookmark.rb +1 -1
  31. data/ruby/neo4j/driver/internal/internal_database_name.rb +3 -5
  32. data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +3 -1
  33. data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +8 -2
  34. data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +8 -13
  35. data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +2 -3
  36. data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +2 -2
  37. data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +5 -10
  38. data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +5 -3
  39. data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +2 -2
  40. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +1 -1
  41. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +1 -1
  42. data/ruby/neo4j/driver/internal/read_only_bookmark_holder.rb +13 -0
  43. data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +35 -0
  44. data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +14 -9
  45. data/ruby/neo4j/driver/internal/util/error_util.rb +1 -1
  46. data/ruby/neo4j/driver/net/{server_address1.rb → server_address.rb} +2 -2
  47. data/ruby/neo4j/driver/query.rb +1 -1
  48. data/ruby/neo4j/driver/transaction_config.rb +5 -1
  49. data/ruby/neo4j/driver/values.rb +3 -3
  50. data/ruby/neo4j/driver/version.rb +1 -1
  51. metadata +6 -5
  52. data/ruby/neo4j/driver/internal/database_name.rb +0 -12
@@ -2,78 +2,57 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Cluster
4
4
  class RoutingTableRegistryImpl
5
- def initialize(connection_pool, rediscovery, clock, logger, routing_table_purge_delay_ms)
6
- @factory = RoutingTableHandlerFactory.new(connection_pool, rediscovery, clock, logger, routing_table_purge_delay_ms)
7
- @routing_table_handlers = Concurrent::Hash.new
8
- @principal_to_database_name_stage = {}
5
+ def initialize(connection_pool, rediscovery, clock, logger, routing_table_purge_delay)
6
+ @factory = RoutingTableHandlerFactory.new(connection_pool, rediscovery, clock, logger, routing_table_purge_delay)
7
+ @routing_table_handlers = Concurrent::Map.new
8
+ @principal_to_database_name = {}
9
9
  @clock = clock
10
10
  @connection_pool = connection_pool
11
11
  @rediscovery = rediscovery
12
12
  @log = logger
13
+ @mutex = Mutex.new
13
14
  end
14
15
 
15
16
  def ensure_routing_table(context)
16
- ensure_database_name_is_completed(context).then_compose do |ctx_and_handler|
17
- completed_context = ctx_and_handler.context
18
- handler = ctx_and_handler.handler.nil? ? get_or_create(Util::Futures.join_now_or_else_throw(completed_context.database_name_future, Async::ConnectionContext::PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER)) : ctx_and_handler.handler
19
- handler.ensure_routing_table(completed_context).then_apply(-> (_ignored) { handler })
20
- end
17
+ ctx_and_handler = ensure_database_name_is_completed(context)
18
+ (ctx_and_handler.handler || get_or_create(context.database_name))
19
+ .tap { |handler| handler.ensure_routing_table(ctx_and_handler.context) }
21
20
  end
22
21
 
23
22
  private def ensure_database_name_is_completed(context)
24
- context_database_name_future = context.database_name_future
23
+ context_database_name = context.database_name
24
+
25
+ return ConnectionContextAndHandler.new(context, nil) if context_database_name
26
+ @mutex.synchronize do
27
+ return ConnectionContextAndHandler.new(context, nil) if context_database_name
25
28
 
26
- if context_database_name_future.done?
27
- context_and_handler_stage = java.util.concurrent.CompletableFuture.completed_future(ConnectionContextAndHandler.new(context, nil))
28
- else
29
29
  impersonated_user = context.impersonated_user
30
30
  principal = Principal.new(impersonated_user)
31
- database_name_stage = @principal_to_database_name_stage[principal]
32
- handler_ref = java.util.concurrent.atomic.AtomicReference.new
33
-
34
- if database_name_stage.nil?
35
- database_name_future = java.util.concurrent.CompletableFuture.new
36
- @principal_to_database_name_stage[principal] = database_name_future
37
- database_name_stage = database_name_future
38
-
39
- routing_table = ClusterRoutingTable.new(DatabaseNameUtil::DEFAULT_DATABASE, @clock)
40
-
41
- @rediscovery.lookup_cluster_composition(routing_table, @connection_pool, context.rediscovery_bookmark, impersonated_user).then_compose do |composition_lookup_result|
42
- database_name = DatabaseNameUtil.database(composition_lookup_result.cluster_composition.database_name)
43
- handler = get_or_create(database_name)
44
- handler_ref.set(handler)
45
- handler.update_routing_table(composition_lookup_result).then_apply(-> (_ignored) { database_name })
46
- end.when_complete do |database_name, _throwable|
47
- @principal_to_database_name_stage.delete(principal)
48
- end.when_complete do |database_name, throwable|
49
- if throwable.nil?
50
- database_name_future.complete(database_name)
51
- else
52
- database_name_future.complete_exceptionally(throwable)
53
- end
54
- end
55
- end
31
+ database_name = @principal_to_database_name[principal]
32
+ handler_ref = Concurrent::AtomicReference.new
56
33
 
57
- context_and_handler_stage =
58
- database_name_stage.then_apply do |database_name|
59
- context_database_name_future.complete(database_name)
60
- ConnectionContextAndHandler.new(context, handler_ref)
34
+ if database_name.nil?
35
+ @principal_to_database_name[principal] = database_name
36
+
37
+ routing_table = ClusterRoutingTable.new(DatabaseNameUtil.default_database, @clock)
38
+
39
+ composition_lookup_result = @rediscovery.lookup_cluster_composition(routing_table, @connection_pool, context.rediscovery_bookmark, impersonated_user)
40
+ database_name = DatabaseNameUtil.database(composition_lookup_result.cluster_composition.database_name)
41
+ handler = get_or_create(database_name)
42
+ handler_ref.set(handler)
43
+ handler.update_routing_table(composition_lookup_result)
44
+ @principal_to_database_name.delete(principal)
61
45
  end
62
- end
63
46
 
64
- context_and_handler_stage
47
+ context.database_name = database_name
48
+ ConnectionContextAndHandler.new(context, handler_ref.get)
49
+ end
65
50
  end
66
51
 
67
52
  def all_servers
68
53
  # obviously we just had a snapshot of all servers in all routing tables
69
54
  # after we read it, the set could already be changed.
70
- servers = []
71
-
72
- @routing_table_handlers.values.each do |table_handler|
73
- servers << table_handler.servers
74
- end
75
-
76
- servers
55
+ @routing_table_handlers.values.map(&:servers).reduce(&:+)
77
56
  end
78
57
 
79
58
  def remove(database_name)
@@ -90,17 +69,19 @@ module Neo4j::Driver
90
69
  end
91
70
  end
92
71
 
93
- def get_routing_table_handler(database_name)
94
- java.util.Optional.of_nullable(@routing_table_handlers[database_name])
72
+ def routing_table_handler(database_name)
73
+ database_name = DatabaseNameUtil.database(database_name) unless database_name.is_a?(InternalDatabaseName)
74
+ @routing_table_handlers[database_name]
95
75
  end
96
76
 
97
- def contains(database_name)
98
- @routing_table_handlers.keys.include?(database_name)
99
- end
77
+ # For tests
78
+ delegate :key?, to: :@routing_table_handlers
100
79
 
101
80
  def get_or_create(database_name)
102
- @routing_table_handlers.compute_if_absent(database_name) do |name|
103
- handler = @factory.new_instance(name, self)
81
+ @routing_table_handlers.compute_if_absent(database_name) do
82
+ # TODO: Verify if applies
83
+ # Note: Atomic methods taking a block do not allow the self instance to be used within the block. Doing so will cause a deadlock.
84
+ handler = @factory.new_instance(database_name, self)
104
85
  @log.debug("Routing table handler for database '#{database_name.description}' is added.")
105
86
  handler
106
87
  end
@@ -109,17 +90,17 @@ module Neo4j::Driver
109
90
  private
110
91
 
111
92
  class RoutingTableHandlerFactory
112
- def initialize(connection_pool, rediscovery, clock, logger, routing_table_purge_delay_ms)
93
+ def initialize(connection_pool, rediscovery, clock, logger, routing_table_purge_delay)
113
94
  @connection_pool = connection_pool
114
95
  @rediscovery = rediscovery
115
96
  @clock = clock
116
97
  @logger = logger
117
- @routing_table_purge_delay_ms = routing_table_purge_delay_ms
98
+ @routing_table_purge_delay = routing_table_purge_delay
118
99
  end
119
100
 
120
101
  def new_instance(database_name, all_tables)
121
102
  routing_table = ClusterRoutingTable.new(database_name, @clock)
122
- RoutingTableHandlerImpl.new(routing_table, @rediscovery, @connection_pool, all_tables, @logger, @routing_table_purge_delay_ms)
103
+ RoutingTableHandlerImpl.new(routing_table, @rediscovery, @connection_pool, all_tables, @logger, @routing_table_purge_delay)
123
104
  end
124
105
  end
125
106
 
@@ -5,7 +5,7 @@ module Neo4j::Driver
5
5
  # This implementation of the {@link RoutingProcedureRunner} works with single database versions of Neo4j calling
6
6
  # the procedure `dbms.cluster.routing.getRoutingTable`
7
7
  class SingleDatabaseRoutingProcedureRunner
8
- ROUTING_CONTEXT = 'context'
8
+ ROUTING_CONTEXT = :context
9
9
  GET_ROUTING_TABLE = "CALL dbms.cluster.routing.getRoutingTable($#{ROUTING_CONTEXT})"
10
10
 
11
11
  def initialize(context)
@@ -16,17 +16,15 @@ module Neo4j::Driver
16
16
  delegate = connection(connection)
17
17
  procedure = procedure_query(connection.server_version, database_name)
18
18
  bookmark_holder = bookmark_holder(bookmark)
19
- run_procedure(delegate, procedure, bookmark_holder).then_compose do |records|
20
- release_connection(delegate, records).handle do |records, error|
21
- process_procedure_response(procedure, records, error)
22
- end
23
- end
19
+ records = run_procedure(delegate, procedure, bookmark_holder)
20
+ release_connection(delegate)
21
+ process_procedure_response(procedure, records, error)
24
22
  end
25
23
 
26
24
  private
27
25
 
28
26
  def connection(connection)
29
- Async::Connection::DirectConnection.new(connection, default_database, AccessMode::WRITE, nil)
27
+ Async::Connection::DirectConnection.new(connection, DatabaseNameUtil.default_database, AccessMode::WRITE, nil)
30
28
  end
31
29
 
32
30
  def procedure_query(server_version, database_name)
@@ -45,16 +43,16 @@ module Neo4j::Driver
45
43
  connection.protocol
46
44
  .run_in_auto_commit_transaction(connection, procedure, bookmark_holder, TransactionConfig.empty,
47
45
  Handlers::Pulln::FetchSizeUtil::UNLIMITED_FETCH_SIZE)
48
- .async_result.then_compose(Async::ResultCursor::list_async)
46
+ .async_result.to_a
49
47
  end
50
48
 
51
- def release_connection(connection, records)
49
+ def release_connection(connection)
52
50
  # It is not strictly required to release connection after routing procedure invocation because it'll
53
51
  # be released by the PULL_ALL response handler after result is fully fetched. Such release will happen
54
52
  # in background. However, releasing it early as part of whole chain makes it easier to reason about
55
53
  # rediscovery in stub server tests. Some of them assume connections to instances not present in new
56
54
  # routing table will be closed immediately.
57
- connection.release.then_apply(->(_ignore) { records } )
55
+ connection.release
58
56
  end
59
57
 
60
58
  def process_procedure_response(procedure, records, error)
@@ -2,6 +2,7 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Cursor
4
4
  class AsyncResultCursorImpl
5
+ include Enumerable
5
6
  delegate :consume_async, :next_async, :peek_async, to: :@pull_all_handler
6
7
 
7
8
  def initialize(run_handler, pull_all_handler)
@@ -25,7 +26,7 @@ module Neo4j::Driver
25
26
  first_record
26
27
  end
27
28
 
28
- def each_async(&action)
29
+ def each(&action)
29
30
  internal_for_each_async(&action)
30
31
  consume_async
31
32
  end
@@ -2,6 +2,7 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Cursor
4
4
  class DisposableAsyncResultCursor
5
+ include Enumerable
5
6
  delegate :keys, :pull_all_failure_async, to: :@delegate
6
7
 
7
8
  def initialize(delegate)
@@ -14,25 +15,23 @@ module Neo4j::Driver
14
15
  end
15
16
 
16
17
  def next_async
17
- assert_not_disposed.then_compose(-> (_ignored) { @delegate.next_async })
18
+ assert_not_disposed
19
+ @delegate.next_async
18
20
  end
19
21
 
20
22
  def peek_async
21
- assert_not_disposed.then_compose(-> (_ignored) { @delegate.peek_async })
23
+ assert_not_disposed
24
+ @delegate.peek_async
22
25
  end
23
26
 
24
27
  def single_async
25
- assert_not_disposed.then_compose(-> (_ignored) { @delegate.single_async })
28
+ assert_not_disposed
29
+ @delegate.single_async
26
30
  end
27
31
 
28
- def for_each_async(action)
29
- assert_not_disposed.then_compose(-> (_ignored) { @delegate.for_each_async(action) })
30
- end
31
-
32
- def list_async(map_function = nil)
33
- return assert_not_disposed.then_compose(-> (_ignored) { @delegate.list_async(map_function) }) if map_function.present?
34
-
35
- assert_not_disposed.then_compose(-> (_ignored) { @delegate.list_async })
32
+ def each(&action)
33
+ assert_not_disposed
34
+ @delegate.each(&action)
36
35
  end
37
36
 
38
37
  def discard_all_failure_async
@@ -41,9 +40,7 @@ module Neo4j::Driver
41
40
  end
42
41
 
43
42
  private def assert_not_disposed
44
- return Util::Futures.failed_future(new_result_consumed_error) if @disposed
45
-
46
- Util::Futures.completed_with_null
43
+ raise Neo4j::Driver::Internal::Util.new_result_consumed_error if @disposed
47
44
  end
48
45
 
49
46
  def disposed?
@@ -6,8 +6,8 @@ module Neo4j::Driver
6
6
 
7
7
  private
8
8
 
9
- DEFAULT_DATABASE = Struct.new(:database_name, :description).new(nil, '<default database>')
10
- SYSTEM_DATABASE = InternalDatabaseName.new(SYSTEM_DATABASE_NAME)
9
+ DEFAULT_DATABASE = InternalDatabaseName.new(description: '<default database>')
10
+ SYSTEM_DATABASE = InternalDatabaseName.new(database_name: SYSTEM_DATABASE_NAME)
11
11
 
12
12
  public
13
13
 
@@ -27,7 +27,7 @@ module Neo4j::Driver
27
27
  when SYSTEM_DATABASE_NAME
28
28
  system_database
29
29
  else
30
- InternalDatabaseName.new(name)
30
+ InternalDatabaseName.new(database_name: name)
31
31
  end
32
32
  end
33
33
  end
@@ -1,12 +1,6 @@
1
1
  module Neo4j::Driver
2
2
  module Internal
3
- class DefaultBookmarkHolder
4
- attr_reader :bookmark
5
-
6
- def initialize(bookmark = InternalBookmark.empty)
7
- @bookmark = bookmark
8
- end
9
-
3
+ class DefaultBookmarkHolder < ReadOnlyBookmarkHolder
10
4
  def bookmark=(bookmark)
11
5
  @bookmark = bookmark if bookmark.present?
12
6
  end
@@ -22,7 +22,7 @@ module Neo4j::Driver
22
22
 
23
23
  def supports_multi_db?
24
24
  private_acquire_connection.then do |conn|
25
- supports_multi_database?(conn)
25
+ Messaging::Request::MultiDatabaseUtil.supports_multi_database?(conn)
26
26
  ensure
27
27
  conn.release
28
28
  end
@@ -83,8 +83,8 @@ module Neo4j::Driver::Internal
83
83
  driver(:Direct, securityPlan, address, connection_provider, retryLogic, metricsProvider, config)
84
84
  end
85
85
 
86
- def create_routing_driver(securityPlan, address, connection_pool, eventExecutorGroup, routingSettings, retryLogic, metricsProvider, config)
87
- connection_provider = create_load_balancer(address, connection_pool, eventExecutorGroup, config, routingSettings)
86
+ def create_routing_driver(securityPlan, address, connection_pool, eventExecutorGroup, routing_settings, retryLogic, metricsProvider, config)
87
+ connection_provider = create_load_balancer(address, connection_pool, eventExecutorGroup, config, routing_settings)
88
88
  driver(:Routing, securityPlan, address, connection_provider, retryLogic, metricsProvider, config)
89
89
  end
90
90
 
@@ -95,11 +95,11 @@ module Neo4j::Driver::Internal
95
95
  end
96
96
  end
97
97
 
98
- def create_load_balancer(address, connection_pool, eventExecutorGroup, config, routingSettings)
98
+ def create_load_balancer(address, connection_pool, eventExecutorGroup, config, routing_settings)
99
99
  load_balancing_strategy = Cluster::Loadbalancing::LeastConnectedLoadBalancingStrategy.new(connection_pool, config[:logger])
100
100
  resolver = create_resolver(config)
101
101
  Cluster::Loadbalancing::LoadBalancer.new(
102
- address, routingSettings, connection_pool, eventExecutorGroup,
102
+ address, routing_settings, connection_pool, eventExecutorGroup,
103
103
  config[:logger], load_balancing_strategy, resolver, &method(:domain_name_resolver))
104
104
  end
105
105
 
@@ -4,7 +4,6 @@ module Neo4j::Driver
4
4
  # This is the Pull All response handler that handles pull all messages in Bolt v3 and previous protocol versions.
5
5
  class LegacyPullAllResponseHandler
6
6
  include Spi::ResponseHandler
7
- UNINITIALIZED_RECORDS = []
8
7
  RECORD_BUFFER_LOW_WATERMARK = ENV['record_buffer_low_watermark']&.to_i || 300
9
8
  RECORD_BUFFER_HIGH_WATERMARK = ENV['record_buffer_high_watermark']&.to_i || 1000
10
9
 
@@ -14,7 +13,7 @@ module Neo4j::Driver
14
13
  @metadata_extractor = Internal::Validator.require_non_nil!(metadata_extractor)
15
14
  @connection = Internal::Validator.require_non_nil!(connection)
16
15
  @completion_listener = Internal::Validator.require_non_nil!(completion_listener)
17
- @records = UNINITIALIZED_RECORDS
16
+ @records = ::Async::Queue.new
18
17
  end
19
18
 
20
19
  def can_manage_auto_read?
@@ -39,7 +38,7 @@ module Neo4j::Driver
39
38
 
40
39
  failed_record_future = fail_record_future(error)
41
40
 
42
- if fail_record_future
41
+ if failed_record_future
43
42
  # error propagated through the record future
44
43
  complete_failure_future(nil)
45
44
  else
@@ -54,7 +53,7 @@ module Neo4j::Driver
54
53
  if @ignore_records
55
54
  complete_record_future(nil)
56
55
  else
57
- record = InternalRecord.new(run_response_handler.query_keys, fields)
56
+ record = InternalRecord.new(@run_response_handler.query_keys, fields)
58
57
  enqueue_record(record)
59
58
  complete_record_future(record)
60
59
  end
@@ -65,36 +64,46 @@ module Neo4j::Driver
65
64
  end
66
65
 
67
66
  def peek_async
68
- record = @records.first
67
+ while @records.empty? && !(@ignore_records || @finished)
68
+ @records.wait
69
+ end
70
+ @records.items.first
69
71
 
70
- if record.nil?
71
- return Util::Futures.failed_future(extract_failure) unless @failure.nil?
72
+ # if record.nil?
73
+ # return Util::Futures.failed_future(extract_failure) unless @failure.nil?
72
74
 
73
- return Util::Futures.completed_with_null if @ignore_records || @finished
75
+ # return Util::Futures.completed_with_null if @ignore_records || @finished
74
76
 
75
- @record_future = java.util.concurrent.CompletableFuture.new if @record_future.nil?
77
+ # @record_future = java.util.concurrent.CompletableFuture.new if @record_future.nil?
76
78
 
77
- @record_future
78
- else
79
- java.util.concurrent.CompletableFuture.completed_future(record)
80
- end
79
+ # @record_future
80
+ # else
81
+ # # java.util.concurrent.CompletableFuture.completed_future(record)
82
+ # record
83
+ # end
81
84
  end
82
85
 
83
86
  def next_async
84
- peek_async.then_apply(-> (_ignore) { dequeue_record })
87
+ dequeue_record if peek_async
85
88
  end
86
89
 
87
90
  def consume_async
88
91
  @ignore_records = true
89
- @records.clear
90
-
91
- pull_all_failure_async.then_apply do |error|
92
- unless error.nil?
93
- raise Util::Futures.as_completion_exception, error
94
- end
92
+ @records.items.clear
95
93
 
94
+ if pull_all_failure_async.nil?
96
95
  @summary
96
+ else
97
+ raise Util::Futures.as_completion_exception, pull_all_failure_async
97
98
  end
99
+
100
+ # pull_all_failure_async do |error|
101
+ # unless error.nil?
102
+ # raise Util::Futures.as_completion_exception, error
103
+ # end
104
+
105
+ # @summary
106
+ # end
98
107
  end
99
108
 
100
109
  def list_async(map_function)
@@ -115,7 +124,8 @@ module Neo4j::Driver
115
124
  if !@failure.nil?
116
125
  return java.util.concurrent.CompletableFuture.completed_future(extract_failure)
117
126
  elsif @finished
118
- return Util::Futures.completed_with_null
127
+ return nil
128
+ # return Util::Futures.completed_with_null
119
129
  else
120
130
  if @failure_future.nil?
121
131
  # neither SUCCESS nor FAILURE message has arrived, register future to be notified when it arrives
@@ -139,7 +149,7 @@ module Neo4j::Driver
139
149
  # when failure is requested we have to buffer all remaining records and then return the error
140
150
  # do not disable auto-read in this case, otherwise records will not be consumed and trailing
141
151
  # SUCCESS or FAILURE message will not arrive as well, so callers will get stuck waiting for the error
142
- if !should_buffer_all_records && records.size > RECORD_BUFFER_HIGH_WATERMARK
152
+ if !should_buffer_all_records && @records.size > RECORD_BUFFER_HIGH_WATERMARK
143
153
  # more than high watermark records are already queued, tell connection to stop auto-reading from network
144
154
  # this is needed to deal with slow consumers, we do not want to buffer all records in memory if they are
145
155
  # fetched from network faster than consumed
@@ -148,7 +158,7 @@ module Neo4j::Driver
148
158
  end
149
159
 
150
160
  def dequeue_record
151
- record = @records.drop(1)
161
+ record = @records.dequeue
152
162
 
153
163
  if @records.size < RECORD_BUFFER_LOW_WATERMARK
154
164
  # less than low watermark records are now available in the buffer, tell connection to pre-fetch more
@@ -170,7 +180,7 @@ module Neo4j::Driver
170
180
  result << map_function.apply(record)
171
181
  end
172
182
 
173
- @records.clear
183
+ @records.items.clear
174
184
  result
175
185
  end
176
186
 
@@ -14,8 +14,8 @@ module Neo4j::Driver
14
14
  private
15
15
 
16
16
  def self.supports_impersonation?(connection)
17
- connection.server_version.greater_than_or_equal(Util::ServerVersion::V4_4_0) &&
18
- connection.protocol.version.compare_to( Messaging::V44::BoltProtocolV44::VERSION ) >= 0
17
+ connection.server_version >= Util::ServerVersion::V4_4_0 &&
18
+ connection.protocol.version >= Messaging::V44::BoltProtocolV44::VERSION
19
19
  end
20
20
  end
21
21
  end
@@ -2,13 +2,13 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  class InternalBookmark
4
4
  include Bookmark
5
- EMPTY = new
6
5
  attr :values
7
6
  delegate :hash, :empty?, to: :values
8
7
 
9
8
  private def initialize(*values)
10
9
  @values = values.to_set
11
10
  end
11
+ EMPTY = new.freeze
12
12
 
13
13
  def ==(other)
14
14
  equal?(other) || self.class == other.class && values == other.values
@@ -1,10 +1,8 @@
1
1
  module Neo4j::Driver
2
2
  module Internal
3
- class InternalDatabaseName < Struct.new(:database_name)
4
- alias description database_name
5
-
6
- def initialize(database_name)
7
- super(Validator.require_non_nil!(database_name))
3
+ class InternalDatabaseName < Struct.new(:database_name, :description)
4
+ def initialize(database_name: nil, description: database_name)
5
+ super(database_name, description)
8
6
  end
9
7
  end
10
8
  end
@@ -2,10 +2,12 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Messaging
4
4
  class BoltProtocolVersion < Struct.new(:major_version, :minor_version)
5
+ include Comparable
6
+
5
7
  def self.from_raw_bytes(raw_version)
6
8
  major = raw_version & 0x000000FF
7
9
  minor = (raw_version >> 8) & 0x000000FF
8
- new(major,minor)
10
+ new(major, minor)
9
11
  end
10
12
 
11
13
  def to_int
@@ -8,8 +8,14 @@ module Neo4j::Driver
8
8
  Util::Preconditions.check_argument(message, Request::RouteMessage)
9
9
  packer.pack_struct_header(3, message.signature)
10
10
  packer.pack(message.routing_context)
11
- packer.pack(message.bookmark.present? ? Values.value(message.bookmark.values) : Values.value(java.util.Collections.empty_list))
12
- packer.pack(message.database_name)
11
+ packer.pack(message.bookmark&.values || [])
12
+ packer.pack(option(message))
13
+ end
14
+
15
+ private
16
+
17
+ def option(message)
18
+ message.database_name
13
19
  end
14
20
  end
15
21
  end
@@ -3,22 +3,17 @@ module Neo4j::Driver
3
3
  module Messaging
4
4
  module Encode
5
5
  # Encodes the ROUTE message to the stream
6
- class RouteV44MessageEncoder
7
- def encode(message, packer)
8
- Util::Preconditions.check_argument(message, Request::RouteMessage)
9
- packer.pack_struct_header(3, message.signature)
10
- packer.pack(message.routing_context)
11
- packer.pack(message.bookmark.present? ? Values.value(message.bookmark.values) : Values.value(java.util.Collections.empty_list))
6
+ class RouteV44MessageEncoder < RouteMessageEncoder
7
+ private
12
8
 
13
- if !message.impersonated_user.nil? && message.database_name.nil?
14
- params = java.util.Collections.singleton_map("imp_user", Values.value(message.impersonated_user))
15
- elsif !message.database_name.nil?
16
- params = java.util.Collections.singleton_map("db", Values.value(message.database_name))
9
+ def option(message)
10
+ if message.impersonated_user && !message.database_name
11
+ { imp_user: message.impersonated_user }
12
+ elsif message.database_name
13
+ { db: message.database_name }
17
14
  else
18
- params = java.util.Collections.empty_map
15
+ {}
19
16
  end
20
-
21
- packer.pack(params)
22
17
  end
23
18
  end
24
19
  end
@@ -7,9 +7,8 @@ module Neo4j::Driver
7
7
 
8
8
  def initialize(bookmark, config, database_name, mode, impersonated_user)
9
9
  super(Request::TransactionMetadataBuilder.build_metadata(
10
- tx_timeout: config[:timeout]&.then(&DurationNormalizer.method(:milliseconds)),
11
- tx_metadata: config[:metadata], database_name: database_name, mode: mode, bookmark: bookmark,
12
- impersonated_user: impersonated_user))
10
+ timeout: config[:timeout], tx_metadata: config[:metadata], database_name: database_name, mode: mode,
11
+ bookmark: bookmark, impersonated_user: impersonated_user))
13
12
  end
14
13
 
15
14
  def signature
@@ -10,12 +10,12 @@ module Neo4j::Driver
10
10
  end
11
11
  end
12
12
 
13
- def supports_multi_database(connection)
13
+ def supports_multi_database?(connection)
14
14
  connection.server_version >= Util::ServerVersion::V4_0_0 &&
15
15
  connection.protocol.version >= V4::BoltProtocolV4::VERSION
16
16
  end
17
17
 
18
- def supports_route_message(connection)
18
+ def supports_route_message?(connection)
19
19
  connection.protocol.version >= V43::BoltProtocolV43::VERSION
20
20
  end
21
21
  end
@@ -6,19 +6,14 @@ module Neo4j::Driver
6
6
  # instance can provide the wanted service.
7
7
  # <p>
8
8
  # This message is used to fetch this routing information.
9
+ #
10
+ # @param routingContext The routing context used to define the routing table. Multi-datacenter deployments is one of its use cases.
11
+ # @param bookmark The bookmark used when getting the routing table.
12
+ # @param databaseName The name of the database to get the routing table for.
13
+ # @param impersonatedUser The name of the impersonated user to get the routing table for, should be {@code null} for non-impersonated requests
9
14
  class RouteMessage < Struct.new(:routing_context, :bookmark, :database_name, :impersonated_user)
10
15
  SIGNATURE = 0x66
11
16
 
12
- # Constructor
13
-
14
- # @param routingContext The routing context used to define the routing table. Multi-datacenter deployments is one of its use cases.
15
- # @param bookmark The bookmark used when getting the routing table.
16
- # @param databaseName The name of the database to get the routing table for.
17
- # @param impersonatedUser The name of the impersonated user to get the routing table for, should be {@code null} for non-impersonated requests
18
- def initialize(routing_context, bookmark, database_name, impersonated_user)
19
- super(routing_context.freeze, bookmark, database_name, impersonated_user)
20
- end
21
-
22
17
  def signature
23
18
  SIGNATURE
24
19
  end