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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/ruby/neo4j/driver/graph_database.rb +2 -2
  3. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +2 -3
  4. data/ruby/neo4j/driver/internal/async/network_connection.rb +5 -6
  5. data/ruby/neo4j/driver/internal/async/network_session.rb +6 -9
  6. data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +18 -20
  7. data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +2 -2
  8. data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +1 -2
  9. data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +15 -16
  10. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +29 -19
  11. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +0 -4
  12. data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +2 -2
  13. data/ruby/neo4j/driver/internal/cursor/result_cursor_factory_impl.rb +0 -5
  14. data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +4 -4
  15. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +23 -64
  16. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +35 -45
  17. data/ruby/neo4j/driver/internal/handlers/pulln/basic_pull_response_handler.rb +28 -18
  18. data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +7 -1
  19. data/ruby/neo4j/driver/internal/internal_driver.rb +0 -4
  20. data/ruby/neo4j/driver/internal/internal_result.rb +6 -17
  21. data/ruby/neo4j/driver/internal/internal_session.rb +1 -1
  22. data/ruby/neo4j/driver/internal/internal_transaction.rb +4 -4
  23. data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +1 -1
  24. data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +4 -1
  25. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +7 -3
  26. data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +13 -13
  27. data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +4 -15
  28. data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +2 -16
  29. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +2 -13
  30. data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +1 -1
  31. data/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +1 -1
  32. data/ruby/neo4j/driver/internal/util/metadata_extractor.rb +1 -3
  33. data/ruby/neo4j/driver/internal/util/result_holder.rb +72 -0
  34. data/ruby/neo4j/driver/version.rb +1 -1
  35. metadata +3 -3
  36. data/ruby/neo4j/driver/session_config.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a035a8385e54c70c851003ce4131072610617d515f118d2d4b03f6ada71de3a7
4
- data.tar.gz: bc8dfddb76165d4aea25d702e1d4bb1be5db3bb375d25f48fab39acb7f247c07
3
+ metadata.gz: 41dc794832386239a05ddcc44bb1937da85f8d1b3d0be4977ab3b53157ab5ac0
4
+ data.tar.gz: e085f6bfce9255985ead9e0aab6bd70a8495f9b62bbfa16fbe38efaac1508032
5
5
  SHA512:
6
- metadata.gz: 17a1b5ada9f09120e7dda4316504d59fedf366696d27c26e87c5feeee381a876409a75eaa05cbc177af64415946af7ec8c1de7b4ed5e637ffc464a40c1fd4eea
7
- data.tar.gz: aa41d20c4794dac6841aa1bf70cb0c3e8573a658e74d8aa4e475f45a2a0a9072056633a83f8744251014ab5a805b6ec368f4a75b036316c2179bc1bcc1f8f8fa
6
+ metadata.gz: d3eeaeaeb2a4f8d19ffacdec93f2fb64ff5c8a65ab27bf6593d4ae3ce2c08e092b97662bd6ab58f4cc59a5bb4d2215e1c8fe80c916c05eda9e9b9454b72411a5
7
+ data.tar.gz: 0a86332ba42e153c1f21964fbca5a0cdba75bf5b3cea574ce40db4a1a54f090dd43d1b1f6096acb51e04ac7d6cdddaf03a3f84dad6fb4582de911d11f22824b5
@@ -26,12 +26,12 @@ module Neo4j::Driver
26
26
  )
27
27
  end
28
28
 
29
- def routing_driver(routing_uris, auth_toke, **config)
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, auth_toke, **config)
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
- Connection::ChannelAttributes.authorization_state_listener(@channel).on_expired(@current_error, @channel)
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
 
@@ -79,11 +79,10 @@ module Neo4j::Driver
79
79
 
80
80
  def terminate_and_release(reason)
81
81
  if @status.compare_and_set(Status::OPEN, Status::TERMINATED)
82
- Connection::ChannelAttributes.set_termination_reason(@channel, reason)
83
- Util::Futures.as_completion_stage(@channel.close).exceptionally(-> (_throwable) { nil }).then_compose(-> (_ignored) { @channel_pool.release(@channel) }).when_complete do |_ignored, _throwable|
84
- @release_future.complete(nil)
85
- @metrics_listener.after_connection_released(Connection::ChannelAttributes.pool_id(@channel), @in_use_event)
86
- end
82
+ @channel.attributes[:termination_reason] = reason
83
+ @channel.close rescue nil
84
+ @channel_pool.release(@channel)
85
+ # @metrics_listener.after_connection_released(Connection::ChannelAttributes.pool_id(@channel), @in_use_event)
87
86
  end
88
87
  end
89
88
 
@@ -96,7 +95,7 @@ module Neo4j::Driver
96
95
  # auto-read could've been disabled, re-enable it to automatically receive response for RESET
97
96
  @channel.auto_read = true
98
97
  @message_dispatcher.enqueue(reset_handler)
99
- @channel.write_and_flush(Messaging::Request::ResetMessage::RESET)#.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
98
+ @channel.write_and_flush(Messaging::Request::ResetMessage::RESET) #.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
100
99
  end
101
100
  end
102
101
 
@@ -22,12 +22,6 @@ module Neo4j::Driver
22
22
  new_result_cursor.map_successful_run_completion_async
23
23
  end
24
24
 
25
- def run_rx(query, **config)
26
- new_result_cursor_stage = build_result_cursor_factory(query, config).then_flat(Cursor::ResultCursorFactory.rx_result)
27
- @result_cursor_stage = new_result_cursor_stage.rescue {}
28
- new_result_cursor_stage
29
- end
30
-
31
25
  def begin_transaction_async(mode = @mode, **config)
32
26
  ensure_session_is_open
33
27
  ensure_no_open_tx_before_starting_tx
@@ -67,9 +61,12 @@ module Neo4j::Driver
67
61
  def close_async
68
62
  return unless @open.make_false
69
63
  # there exists a cursor with potentially unconsumed error, try to extract and propagate it
70
- @result_cursor&.discard_all_failure_async
71
- ensure
64
+ error = @result_cursor&.discard_all_failure_async
72
65
  close_transaction_and_release_connection
66
+ rescue => tx_close_error
67
+ error = Util::Futures.combine_errors(error, tx_close_error)
68
+ ensure
69
+ raise error if error
73
70
  end
74
71
 
75
72
  def current_connection_open?
@@ -89,7 +86,7 @@ module Neo4j::Driver
89
86
 
90
87
  def acquire_connection(mode)
91
88
  # make sure previous result is fully consumed and connection is released back to the pool
92
- @result_cursor&.pull_all_failure_async
89
+ @result_cursor&.pull_all_failure_async&.result!&.then(&method(:raise))
93
90
  if @connection&.open?
94
91
  # there somehow is an existing open connection, this should not happen, just a precondition
95
92
  raise Neo4j::Driver::Exceptions::IllegalStateException.new('Existing open connection detected')
@@ -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
- raise Neo4j::Driver::Exceptions::ClientException, commit ? CANT_COMMIT_COMMITTED_MSG : CANT_ROLLBACK_COMMITTED_MSG
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
- raise Neo4j::Driver::Exceptions::ClientException, commit ? CANT_COMMIT_ROLLED_BACK_MSG : CANT_ROLLBACK_ROLLED_BACK_MSG
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
- raise Neo4j::Driver::Exceptions::ClientException, CANT_COMMIT_ROLLING_BACK_MSG
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 = true
69
+ @commit_pending = Util::ResultHolder.new
68
70
  nil
69
71
  end
70
72
  else
71
73
  if @commit_pending
72
- raise Neo4j::Driver::Exceptions::ClientException, CANT_ROLLBACK_COMMITTING_MSG
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 = true
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
- handle_transaction_completion(commit, nil)
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::Futures.failed_future(exception)
176
+ Util::ResultHolder.failed(exception)
179
177
  else
180
- @protocol.commit_transaction(@connection, @bookmark_holder)
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::Futures.completed_with_null
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 { |_fulfilled, _value, commit_or_rollback_error|
194
- combined_error = Util::Futures.combined_error(cursor_failure, commit_or_rollback_error)
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
@@ -105,8 +105,8 @@ module Neo4j::Driver
105
105
  addresses.map { |address| address == old_address ? new_address : address }.freeze
106
106
  end
107
107
 
108
- def new_with_reused_addresses(current_addresses, disused_addresses, new_addresses)
109
- (current_addresses + disused_addresses + new_addresses).freeze
108
+ def new_with_reused_addresses(*addresses)
109
+ addresses.map(&:to_set).reduce(&:+).freeze
110
110
  end
111
111
 
112
112
  def to_bolt_server_address(address)
@@ -48,8 +48,7 @@ module Neo4j::Driver
48
48
  resolved_addresses = @resolver.call(@initial_router).flat_map do |server_address|
49
49
  resolve_all_by_domain_name(server_address).unicast_stream
50
50
  # rescue java.net.UnknownHostException => e
51
- rescue => e
52
- exception&.add_suppressed(e)
51
+ rescue SocketError => e
53
52
  exception ||= e
54
53
  []
55
54
  end
@@ -16,9 +16,14 @@ 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
- records = run_procedure(delegate, procedure, bookmark_holder)
20
- release_connection(delegate)
21
- process_procedure_response(procedure, records, error)
19
+ begin
20
+ records = run_procedure(delegate, procedure, bookmark_holder)
21
+ RoutingProcedureResponse.new(procedure, records: records)
22
+ rescue => error
23
+ handle_error(procedure, error)
24
+ ensure
25
+ release_connection(delegate)
26
+ end
22
27
  end
23
28
 
24
29
  private
@@ -32,7 +37,7 @@ module Neo4j::Driver
32
37
  raise Exceptions::FatalDiscoveryException, "Refreshing routing table for multi-databases is not supported in server version lower than 4.0. Current server version: #{server_version}. Database name: '#{database_name.description}'"
33
38
  end
34
39
 
35
- Query.new(GET_ROUTING_TABLE, Values.parameters(ROUTING_CONTEXT, @context.to_map))
40
+ Query.new(GET_ROUTING_TABLE, ROUTING_CONTEXT => @context.to_h)
36
41
  end
37
42
 
38
43
  def bookmark_holder(_ignored)
@@ -43,7 +48,7 @@ module Neo4j::Driver
43
48
  connection.protocol
44
49
  .run_in_auto_commit_transaction(connection, procedure, bookmark_holder, TransactionConfig.empty,
45
50
  Handlers::Pulln::FetchSizeUtil::UNLIMITED_FETCH_SIZE)
46
- .async_result.to_a
51
+ .async_result.then(&:to_a)
47
52
  end
48
53
 
49
54
  def release_connection(connection)
@@ -55,18 +60,12 @@ module Neo4j::Driver
55
60
  connection.release
56
61
  end
57
62
 
58
- def process_procedure_response(procedure, records, error)
59
- cause = Util::Futures.completion_exception_cause(error)
60
-
61
- return RoutingProcedureResponse.new(procedure, records) if cause.nil?
62
-
63
- handle_error(procedure, cause)
64
- end
65
-
66
63
  def handle_error(procedure, error)
67
- return RoutingProcedureResponse.new(procedure, records) if error.is_a? Exceptions::ClientException
68
-
69
- raise java.util.concurrent.CompletionException, error
64
+ if error.is_a? Exceptions::ClientException
65
+ RoutingProcedureResponse.new(procedure, error: error)
66
+ else
67
+ raise error
68
+ end
70
69
  end
71
70
  end
72
71
  end
@@ -15,20 +15,24 @@ module Neo4j::Driver
15
15
  end
16
16
 
17
17
  def single_async
18
- first_record = next_async
19
- unless first_record
20
- raise Exceptions::NoSuchRecordException, 'Cannot retrieve a single record, because this result is empty.'
21
- end
22
- if next_async
23
- raise Exceptions::NoSuchRecordException,
24
- 'Expected a result with a single record, but this result contains at least one more. Ensure your query returns only one record.'
18
+ next_async.compose do |first_record|
19
+ unless first_record
20
+ raise Exceptions::NoSuchRecordException, 'Cannot retrieve a single record, because this result is empty.'
21
+ end
22
+ next_async.then do |second_record|
23
+ if second_record
24
+ raise Exceptions::NoSuchRecordException,
25
+ 'Expected a result with a single record, but this result contains at least one more. Ensure your query returns only one record.'
26
+ end
27
+ first_record
28
+ end
25
29
  end
26
- first_record
27
30
  end
28
31
 
29
32
  def each(&action)
30
- internal_for_each_async(&action)
31
- consume_async
33
+ result_holder = Util::ResultHolder.new
34
+ internal_for_each_async(result_holder, &action)
35
+ result_holder.then { consume_async }
32
36
  end
33
37
 
34
38
  def to_async(&map_function)
@@ -37,8 +41,7 @@ module Neo4j::Driver
37
41
 
38
42
  def discard_all_failure_async
39
43
  # runError has priority over other errors and is expected to have been reported to user by now
40
- consume_async #.chain { |_fulfilled, _summary, error| @run_error ? nil : error }
41
- nil
44
+ consume_async.error.then { |error| run_error ? nil : error }
42
45
  end
43
46
 
44
47
  def pull_all_failure_async
@@ -46,18 +49,25 @@ module Neo4j::Driver
46
49
  @pull_all_handler.pull_all_failure_async.then { |error| run_error ? nil : error }
47
50
  end
48
51
 
49
- private def internal_for_each_async
50
- while record = next_async
51
- begin
52
- yield record
53
- rescue
54
- nil
52
+ private def internal_for_each_async(result_holder, &action)
53
+ next_async.chain do |record, error|
54
+ if error
55
+ result_holder.fail(error)
56
+ elsif record
57
+ begin
58
+ yield record
59
+ rescue => action_error
60
+ result_holder.fail(action_error)
61
+ end
62
+ internal_for_each_async(result_holder, &action)
63
+ else
64
+ result_holder.succeed(nil)
55
65
  end
56
66
  end
57
67
  end
58
68
 
59
69
  def map_successful_run_completion_async
60
- run_error || self
70
+ run_error&.then(&Util::ResultHolder.method(:failed)) || Util::ResultHolder.successful(self)
61
71
  end
62
72
 
63
73
  def run_error
@@ -18,10 +18,6 @@ module Neo4j::Driver
18
18
 
19
19
  DisposableAsyncResultCursor.new(AsyncResultCursorImpl.new(@run_handler, @pull_all_handler))
20
20
  end
21
-
22
- def rx_result
23
- Util::Futures.failed_future(Exceptions::ClientException.new('Driver is connected to the database that does not support driver reactive API. In order to use the driver reactive API, please upgrade to neo4j 4.0.0 or later.'))
24
- end
25
21
  end
26
22
  end
27
23
  end
@@ -40,7 +40,7 @@ module Neo4j::Driver
40
40
  end
41
41
 
42
42
  private def assert_not_disposed
43
- raise Neo4j::Driver::Internal::Util.new_result_consumed_error if @disposed
43
+ raise Util::ErrorUtil.new_result_consumed_error if @disposed
44
44
  end
45
45
 
46
46
  def disposed?
@@ -48,7 +48,7 @@ module Neo4j::Driver
48
48
  end
49
49
 
50
50
  def map_successful_run_completion_async
51
- @delegate.map_successful_run_completion_async
51
+ @delegate.map_successful_run_completion_async.then { self }
52
52
  end
53
53
  end
54
54
  end
@@ -18,11 +18,6 @@ module Neo4j::Driver
18
18
 
19
19
  DisposableAsyncResultCursor.new(AsyncResultCursorImpl.new(@run_handler, @pull_all_handler))
20
20
  end
21
-
22
- def rx_result
23
- @connection.write_and_flush(@run_message, @run_handler)
24
- @run_future.handle { |_ignored, error| RxResultCursorImpl.new(error, @run_handler, @pull_handler) }
25
- end
26
21
  end
27
22
  end
28
23
  end
@@ -4,16 +4,16 @@ module Neo4j::Driver
4
4
  class CommitTxResponseHandler
5
5
  include Spi::ResponseHandler
6
6
 
7
- def initialize(completion_listener)
8
- @completion_listener = completion_listener
7
+ def initialize(result_holder)
8
+ @result_holder = result_holder
9
9
  end
10
10
 
11
11
  def on_success(metadata)
12
- @completion_listener.bookmark = metadata[:bookmark]&.then(&InternalBookmark.method(:parse))
12
+ @result_holder.succeed(metadata[:bookmark]&.then(&InternalBookmark.method(:parse)))
13
13
  end
14
14
 
15
15
  def on_failure(error)
16
- raise error
16
+ @result_holder.fail(error)
17
17
  end
18
18
 
19
19
  def on_record(fields)
@@ -4,6 +4,7 @@ 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
+ include Enumerable
7
8
  RECORD_BUFFER_LOW_WATERMARK = ENV['record_buffer_low_watermark']&.to_i || 300
8
9
  RECORD_BUFFER_HIGH_WATERMARK = ENV['record_buffer_high_watermark']&.to_i || 1000
9
10
 
@@ -67,52 +68,27 @@ module Neo4j::Driver
67
68
  while @records.empty? && !(@ignore_records || @finished)
68
69
  @records.wait
69
70
  end
70
- @records.items.first
71
-
72
- # if record.nil?
73
- # return Util::Futures.failed_future(extract_failure) unless @failure.nil?
74
-
75
- # return Util::Futures.completed_with_null if @ignore_records || @finished
76
-
77
- # @record_future = java.util.concurrent.CompletableFuture.new if @record_future.nil?
78
-
79
- # @record_future
80
- # else
81
- # # java.util.concurrent.CompletableFuture.completed_future(record)
82
- # record
83
- # end
71
+ @records.items.first&.then(&Util::ResultHolder.method(:successful)) or
72
+ @failure ? Util::ResultHolder.failed(extract_failure) : Util::ResultHolder.successful(nil)
84
73
  end
85
74
 
86
75
  def next_async
87
- dequeue_record if peek_async
76
+ peek_async.then { |record| dequeue_record if record }
88
77
  end
89
78
 
90
79
  def consume_async
91
80
  @ignore_records = true
92
81
  @records.items.clear
93
-
94
- if pull_all_failure_async.nil?
95
- @summary
96
- else
97
- raise Util::Futures.as_completion_exception, pull_all_failure_async
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
82
+ pull_all_failure_async.result!&.then(&Util::ResultHolder.method(:failed)) or
83
+ Util::ResultHolder.successful(@summary)
107
84
  end
108
85
 
109
- def list_async(map_function)
110
- pull_all_failure_async.then_apply do |error|
111
- unless error.nil?
112
- raise Util::Futures.as_completion_exception, error
86
+ def each
87
+ pull_all_failure_async.then do
88
+ unless @finished
89
+ raise Exceptions::IllegalStateException, "Can't get records as list because SUCCESS or FAILURE did not arrive"
113
90
  end
114
-
115
- records_as_list(map_function)
91
+ @records.each { |record| yield record }
116
92
  end
117
93
  end
118
94
 
@@ -121,21 +97,17 @@ module Neo4j::Driver
121
97
  end
122
98
 
123
99
  def pull_all_failure_async
124
- if !@failure.nil?
125
- return java.util.concurrent.CompletableFuture.completed_future(extract_failure)
100
+ if @failure
101
+ Util::ResultHolder.successful(extract_failure)
126
102
  elsif @finished
127
- return nil
128
- # return Util::Futures.completed_with_null
103
+ Util::ResultHolder.successful
129
104
  else
130
- if @failure_future.nil?
105
+ (@failed_future ||= Util::ResultHolder.new).tap do |_|
131
106
  # neither SUCCESS nor FAILURE message has arrived, register future to be notified when it arrives
132
107
  # future will be completed with null on SUCCESS and completed with Throwable on FAILURE
133
108
  # enable auto-read, otherwise we might not read SUCCESS/FAILURE if records are not consumed
134
109
  enable_auto_read
135
- @failure_future = java.util.concurrent.CompletableFuture.new
136
110
  end
137
-
138
- @failure_future
139
111
  end
140
112
  end
141
113
 
@@ -191,33 +163,20 @@ module Neo4j::Driver
191
163
  end
192
164
 
193
165
  def complete_record_future(record)
194
- unless @record_future.nil?
195
- future = @record_future
196
- @record_future = nil
197
- future.complete(record)
198
- end
166
+ @record_future&.succeed(record)
167
+ @record_future = nil
199
168
  end
200
169
 
201
170
  def fail_record_future(error)
202
- unless @record_future.nil?
203
- future = @record_future
204
- @record_future = nil
205
- future.complete_exceptionally(error)
206
- return true
207
- end
208
-
209
- false
171
+ @record_future&.fail(error)
172
+ ensure
173
+ @record_future = nil
210
174
  end
211
175
 
212
176
  def complete_failure_future(error)
213
- unless @failure_future.nil?
214
- future = @failure_future
215
- @failure_future = nil
216
- future.complete(error)
217
- return true
218
- end
219
-
220
- false
177
+ @failure_future&.fail(error)
178
+ ensure
179
+ @failure_future = nil
221
180
  end
222
181
 
223
182
  def extract_result_summary(metadata)