neo4j-ruby-driver 4.4.0.alpha.6 → 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 (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