neo4j-ruby-driver 4.4.0.beta.1 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c795045f581183398e15ba5c44c1f89b10ea234a9a6dc1e46fecd8c02b857bb3
4
- data.tar.gz: 1859daea7265d9409d001e748048ab97837fe26895d80fe4e24773b1b51ed49d
3
+ metadata.gz: aad2e30fa3fa23dc95e7db9f27847b1c5382c23600c019d93a7625fc5a66d085
4
+ data.tar.gz: 534c14f354f92df7a85b153e1451951ded71863fbbb10c61a50a280a8bf3bea7
5
5
  SHA512:
6
- metadata.gz: 5f72367997a92a64e8a75ef08bfca59d0acffaac7589e594b69d8fead9173dc3339d6b3dc26ad63ae1f2f0f7cde0a9f172908e9112b92b3496c209ef8c99e01d
7
- data.tar.gz: 7bee1a6da116192d42ad2d9b86091d787211af683278c9cfe136f3c8ebf3d1d8c807834b44d5162a308b47b5208ee8e0b40302961a5dfb83c16a7180353d617e
6
+ metadata.gz: 909be9c6542e378161b3e9b9c62ad9e45ef08c54f7410b4ea5a2ba3f15267fd445995757f74210aadcaa10f94475f839cddeb2294c23d44a9925e044e23cc162
7
+ data.tar.gz: 4d22446e5a24c6f7f99072202bfc4dbab1e222b535c64b1c716a31f4993f9fe0da07c8d5dfbd3f68d793fc1b11f6782f4a6062e3171f41b7b26a8c7260b0966a
@@ -66,7 +66,7 @@ module Neo4j::Driver
66
66
 
67
67
  def close_driver(driver, uri, log)
68
68
  driver.close
69
- rescue StandardError => close_error
69
+ rescue => close_error
70
70
  log.warn { "Unable to close driver towards URI: #{uri}\n#{close_error}" }
71
71
  end
72
72
 
@@ -7,7 +7,7 @@ module Neo4j::Driver
7
7
 
8
8
  attr_reader :server_agent, :server_address, :server_version
9
9
 
10
- def initialize(channel, channel_pool, logger)
10
+ def initialize(channel, channel_pool, logger, &on_pool_shutdown)
11
11
  @log = logger
12
12
  @channel = channel
13
13
  @message_dispatcher = channel.attributes[:message_dispatcher]
@@ -16,6 +16,7 @@ module Neo4j::Driver
16
16
  @server_version = channel.attributes[:server_version]
17
17
  @protocol = Messaging::BoltProtocol.for_channel(channel)
18
18
  @channel_pool = channel_pool
19
+ @on_pool_shutdow = on_pool_shutdown
19
20
  # @release_future = java.util.concurrent.CompletableFuture.new
20
21
  # @clock = clock
21
22
  # @connection_read_timeout = Connection::ChannelAttributes.connection_read_timeout(channel) || nil
@@ -89,10 +90,25 @@ module Neo4j::Driver
89
90
  # auto-read could've been disabled, re-enable it to automatically receive response for RESET
90
91
  @channel.auto_read = true
91
92
  @message_dispatcher.enqueue(reset_handler)
92
- @channel.write_and_flush(Messaging::Request::ResetMessage::RESET) #.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
93
+ write_to_channel(Messaging::Request::ResetMessage::RESET, true)
93
94
  end
94
95
  end
95
96
 
97
+ def write_to_channel(message, flush = false)
98
+ if flush
99
+ @channel.write_and_flush(message) #.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
100
+ else
101
+ @channel.write(message)
102
+ end
103
+ rescue EOFError, Errno::ECONNRESET, Errno::EPIPE => e
104
+ terminate_and_release(e.message)
105
+ @log.debug("Shutting down connection pool towards #{@server_address} due to error: #{e.message}")
106
+ @channel_pool.shutdown(&:close)
107
+ @on_pool_shutdow.call
108
+ # should remove routing table entry as well
109
+ raise Exceptions::SessionExpiredException, e.message
110
+ end
111
+
96
112
  def flush_in_event_loop
97
113
  @channel.event_loop.execute do
98
114
  @channel.flush
@@ -103,11 +119,7 @@ module Neo4j::Driver
103
119
  def write_message_in_event_loop(message, handler, flush)
104
120
  @message_dispatcher.enqueue(handler)
105
121
 
106
- if flush
107
- @channel.write_and_flush(message) #.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
108
- else
109
- @channel.write(message)
110
- end
122
+ write_to_channel(message, flush)
111
123
  end
112
124
 
113
125
  def write_messages_in_event_loop(message1, handler1, message2, handler2, flush)
@@ -2,7 +2,7 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Async
4
4
  module Pool
5
- class Controller < ConnectionPool
5
+ class ChannelPool < ConnectionPool
6
6
  def initialize(limit: nil, acquisition_timeout: nil, &block)
7
7
  super(size: limit, timeout: acquisition_timeout, &block)
8
8
  @available = TimedStack.new(@size, &block)
@@ -20,12 +20,12 @@ module Neo4j::Driver
20
20
 
21
21
  begin
22
22
  channel = pool.acquire
23
- @log.debug{"Channel #{channel.object_id} acquired"}
23
+ @log.debug { "Channel #{channel.object_id} acquired" }
24
24
  rescue => error
25
25
  process_acquisition_error(pool, address, error)
26
26
  end
27
27
  assert_not_closed(address, channel, pool)
28
- NetworkConnection.new(channel, pool, @log)
28
+ NetworkConnection.new(channel, pool, @log) { remove(pool) }
29
29
  end
30
30
 
31
31
  def retain_all(addresses_to_retain)
@@ -46,6 +46,12 @@ module Neo4j::Driver
46
46
  end
47
47
  end
48
48
 
49
+ def remove(pool)
50
+ @address_to_pool_lock.with_write_lock do
51
+ @address_to_pool.each { |address, value| @address_to_pool.delete(address) if value == pool }
52
+ end
53
+ end
54
+
49
55
  def in_use_connections(address)
50
56
  @address_to_pool[address]&.size || 0
51
57
  # @netty_channel_tracker.in_use_channel_count(address)
@@ -81,7 +87,7 @@ module Neo4j::Driver
81
87
  # NettyChannelPool returns future failed with TimeoutException if acquire operation takes more than
82
88
  # configured time, translate this exception to a prettier one and re-throw
83
89
  raise Neo4j::Driver::Exceptions::ClientException.new("Unable to acquire connection from the pool within configured maximum time of #{@settings.connection_acquisition_timeout.inspect}")
84
- # elsif pool.closed?
90
+ # elsif pool.closed?
85
91
  # There is a race condition where a thread tries to acquire a connection while the pool is closed by another concurrent thread.
86
92
  # Treat as failed to obtain connection for a direct driver. For a routing driver, this error should be retried.
87
93
  # raise Neo4j::Driver::Exceptions::ServiceUnavailableException, "Connection pool for server #{server_address} is closed while acquiring a connection."
@@ -109,7 +115,7 @@ module Neo4j::Driver
109
115
  end
110
116
 
111
117
  def new_pool(address)
112
- Controller.new(limit: @settings.max_connection_pool_size, acquisition_timeout: @settings.connection_acquisition_timeout) { Channel.new(address, @connector, @log) }
118
+ ChannelPool.new(limit: @settings.max_connection_pool_size, acquisition_timeout: @settings.connection_acquisition_timeout) { Channel.new(address, @connector, @log) }
113
119
  end
114
120
 
115
121
  def get_or_create_pool(address)
@@ -41,13 +41,15 @@ module Neo4j::Driver
41
41
  def supports_multi_db?
42
42
  addresses = @rediscovery.resolve
43
43
  base_error = Exceptions::ServiceUnavailableException.new("Failed to perform multi-databases feature detection with the following servers: #{addresses}")
44
- addresses.lazy.map do |address|
45
- private_suports_multi_db?(address)
44
+ addresses.each do |address|
45
+ return private_suports_multi_db?(address)
46
46
  rescue Exceptions::SecurityException
47
47
  raise
48
48
  rescue => error
49
49
  Util::Futures.combine_errors(base_error, error)
50
- end.find { |result| !result.nil? } or raise base_error
50
+ end
51
+
52
+ raise base_error
51
53
  end
52
54
 
53
55
  private
@@ -12,19 +12,19 @@ module Neo4j::Driver
12
12
 
13
13
  def get_cluster_composition(connection, database_name, bookmark, impersonated_user)
14
14
  runner = if Messaging::Request::MultiDatabaseUtil.supports_route_message?(connection)
15
- @route_message_routing_procedure_runner
16
- elsif Messaging::Request::MultiDatabaseUtil.supports_multi_database?(connection)
17
- @multi_database_routing_procedure_runner
18
- else
19
- @single_database_routing_procedure_runner
20
- end
15
+ @route_message_routing_procedure_runner
16
+ elsif Messaging::Request::MultiDatabaseUtil.supports_multi_database?(connection)
17
+ @multi_database_routing_procedure_runner
18
+ else
19
+ @single_database_routing_procedure_runner
20
+ end
21
21
 
22
22
  process_routing_response(runner.run(connection, database_name, bookmark, impersonated_user))
23
23
  end
24
24
 
25
25
  def process_routing_response(response)
26
26
  unless response.success?
27
- raise response.error.class, "Failed to run '#{invoked_procedure_string(response)}' on server. Please make sure that there is a Neo4j server or cluster up running."
27
+ raise response.error, "Failed to run '#{invoked_procedure_string(response)}' on server. Please make sure that there is a Neo4j server or cluster up running."
28
28
  end
29
29
 
30
30
  records = response.records
@@ -36,7 +36,7 @@ module Neo4j::Driver
36
36
 
37
37
  # failed to parse the record
38
38
  begin
39
- cluster = ClusterComposition.parse( records[0], Time.now)
39
+ cluster = ClusterComposition.parse(records[0], Time.now)
40
40
  rescue Exceptions::Value::ValueException => e
41
41
  raise Exceptions::ProtocolException, "#{PROTOCOL_ERROR_MESSAGE % invoked_procedure_string(response)} unparsable record received. #{e}"
42
42
  end
@@ -17,8 +17,8 @@ module Neo4j::Driver
17
17
  procedure = procedure_query(connection.server_version, database_name)
18
18
  bookmark_holder = bookmark_holder(bookmark)
19
19
  begin
20
- records = run_procedure(delegate, procedure, bookmark_holder)
21
- RoutingProcedureResponse.new(procedure, records: records)
20
+ result = run_procedure(delegate, procedure, bookmark_holder)
21
+ RoutingProcedureResponse.new(procedure, **result.error ? { error: result.error } : { records: result.result! })
22
22
  rescue => error
23
23
  handle_error(procedure, error)
24
24
  ensure
@@ -48,7 +48,7 @@ module Neo4j::Driver
48
48
  connection.protocol
49
49
  .run_in_auto_commit_transaction(connection, procedure, bookmark_holder, TransactionConfig.empty,
50
50
  Handlers::Pulln::FetchSizeUtil::UNLIMITED_FETCH_SIZE)
51
- .async_result.then(&:to_a)
51
+ .async_result.list_async
52
52
  end
53
53
 
54
54
  def release_connection(connection)
@@ -2,7 +2,6 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Cursor
4
4
  class AsyncResultCursorImpl
5
- include Enumerable
6
5
  delegate :consume_async, :next_async, :peek_async, to: :@pull_all_handler
7
6
 
8
7
  def initialize(run_handler, pull_all_handler)
@@ -29,13 +28,7 @@ module Neo4j::Driver
29
28
  end
30
29
  end
31
30
 
32
- def each(&action)
33
- result_holder = Util::ResultHolder.new
34
- internal_for_each_async(result_holder, &action)
35
- result_holder.then { consume_async }
36
- end
37
-
38
- def to_async(&map_function)
31
+ def list_async(&map_function)
39
32
  @pull_all_handler.list_async(&block_given? ? map_function : :itself)
40
33
  end
41
34
 
@@ -49,23 +42,6 @@ module Neo4j::Driver
49
42
  @pull_all_handler.pull_all_failure_async.then { |error| run_error ? nil : error }
50
43
  end
51
44
 
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)
65
- end
66
- end
67
- end
68
-
69
45
  def map_successful_run_completion_async
70
46
  run_error&.then(&Util::ResultHolder.method(:failed)) || Util::ResultHolder.successful(self)
71
47
  end
@@ -34,6 +34,11 @@ module Neo4j::Driver
34
34
  @delegate.each(&action)
35
35
  end
36
36
 
37
+ def list_async(&block)
38
+ assert_not_disposed
39
+ @delegate.list_async(&block)
40
+ end
41
+
37
42
  def discard_all_failure_async
38
43
  @disposed = true
39
44
  @delegate.discard_all_failure_async
@@ -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
- include Enumerable
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
 
@@ -83,12 +82,15 @@ module Neo4j::Driver
83
82
  Util::ResultHolder.successful(@summary)
84
83
  end
85
84
 
86
- def each
87
- pull_all_failure_async.then do
85
+ def list_async(&block)
86
+ pull_all_failure_async.then do |error|
87
+ raise error if error
88
88
  unless @finished
89
89
  raise Exceptions::IllegalStateException, "Can't get records as list because SUCCESS or FAILURE did not arrive"
90
90
  end
91
- @records.each { |record| yield record }
91
+ @records.items.map(&block)
92
+ ensure
93
+ @records.items.clear
92
94
  end
93
95
  end
94
96
 
@@ -3,7 +3,6 @@ module Neo4j::Driver
3
3
  module Handlers
4
4
  module Pulln
5
5
  class AutoPullResponseHandler < BasicPullResponseHandler
6
- include Enumerable
7
6
  delegate :signal, to: :@records
8
7
  LONG_MAX_VALUE = 2 ** 63 - 1
9
8
 
@@ -79,12 +78,14 @@ module Neo4j::Driver
79
78
  completed_with_value_if_no_failure(@summary)
80
79
  end
81
80
 
82
- def each
81
+ def list_async(&block)
83
82
  pull_all_async.then do
84
83
  unless done?
85
84
  raise Exceptions::IllegalStateException, "Can't get records as list because SUCCESS or FAILURE did not arrive"
86
85
  end
87
- @records.each { |record| yield record }
86
+ @records.items.map(&block)
87
+ ensure
88
+ @records.items.clear
88
89
  end
89
90
  end
90
91
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Neo4j
4
4
  module Driver
5
- VERSION = '4.4.0.beta.1'
5
+ VERSION = '4.4.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neo4j-ruby-driver
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0.beta.1
4
+ version: 4.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Heinrich Klobuczek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-25 00:00:00.000000000 Z
11
+ date: 2022-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -287,9 +287,9 @@ files:
287
287
  - ruby/neo4j/driver/internal/async/outbound/chunk_aware_byte_buf_output.rb
288
288
  - ruby/neo4j/driver/internal/async/outbound/outbound_message_handler.rb
289
289
  - ruby/neo4j/driver/internal/async/pool/channel.rb
290
+ - ruby/neo4j/driver/internal/async/pool/channel_pool.rb
290
291
  - ruby/neo4j/driver/internal/async/pool/channel_tracker.rb
291
292
  - ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb
292
- - ruby/neo4j/driver/internal/async/pool/controller.rb
293
293
  - ruby/neo4j/driver/internal/async/pool/netty_channel_health_checker.rb
294
294
  - ruby/neo4j/driver/internal/async/pool/netty_channel_pool.rb
295
295
  - ruby/neo4j/driver/internal/async/pool/network_connection_factory.rb
@@ -496,9 +496,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
496
496
  version: '3.1'
497
497
  required_rubygems_version: !ruby/object:Gem::Requirement
498
498
  requirements:
499
- - - ">"
499
+ - - ">="
500
500
  - !ruby/object:Gem::Version
501
- version: 1.3.1
501
+ version: '0'
502
502
  requirements: []
503
503
  rubygems_version: 3.3.7
504
504
  signing_key: