neo4jrb/neo4j-ruby-driver

MRI Driver produces RuntimeError

danielmconrad opened this issue · 7 comments

Database:
Neo4j 3.5, 4.4

Gems:

gem 'activegraph', '11.1.0.alpha.2'
gem 'neo4j-ruby-driver', '4.4.0.alpha.7'

Error:

RuntimeError: can't add a new key into hash during iteration

File /usr/local/bundle/gems/async-pool-0.3.10/lib/async/pool/controller.rb line 255 in create_resource
File /usr/local/bundle/gems/async-pool-0.3.10/lib/async/pool/controller.rb line 305 in get_resource
File /usr/local/bundle/gems/async-pool-0.3.10/lib/async/pool/controller.rb line 271 in block in available_resource
File /usr/local/bundle/gems/async-2.0.3/lib/async/semaphore.rb line 83 in acquire
File /usr/local/bundle/gems/async-pool-0.3.10/lib/async/pool/controller.rb line 270 in available_resource
File /usr/local/bundle/gems/async-pool-0.3.10/lib/async/pool/controller.rb line 236 in wait_for_resource
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/async/pool/controller.rb line 18 in block in wait_for_resource
File /usr/local/bundle/gems/async-2.0.3/lib/async/scheduler.rb line 290 in with_timeout
File /usr/local/bundle/gems/async-2.0.3/lib/async/task.rb line 97 in with_timeout
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/async/pool/controller.rb line 18 in wait_for_resource
File /usr/local/bundle/gems/async-pool-0.3.10/lib/async/pool/controller.rb line 96 in acquire
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb line 22 in acquire
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/direct_connection_provider.rb line 36 in private_acquire_connection
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/direct_connection_provider.rb line 15 in acquire_connection
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/async/network_session.rb line 98 in acquire_connection
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/async/network_session.rb line 34 in begin_transaction_async
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/internal_session.rb line 66 in private_begin_transaction
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/internal_session.rb line 56 in block in transaction
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb line 23 in retry
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/internal_session.rb line 55 in transaction
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/lib/neo4j/driver/synchronizable.rb line 16 in block (4 levels) in with_sync_wrapper
File /usr/local/bundle/gems/async-2.0.3/lib/kernel/sync.rb line 36 in Sync
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/lib/neo4j/driver/synchronizable.rb line 16 in block (3 levels) in with_sync_wrapper
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/ruby/neo4j/driver/internal/internal_session.rb line 45 in write_transaction
File /usr/local/bundle/gems/activegraph-11.1.0.alpha.2/lib/active_graph/transactions.rb line 43 in run_transaction_work
File /usr/local/bundle/gems/activegraph-11.1.0.alpha.2/lib/active_graph/transactions.rb line 37 in block in send_transaction
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/lib/neo4j/driver/auto_closable.rb line 19 in block (3 levels) in with_block_definer
File /usr/local/bundle/gems/neo4j-ruby-driver-4.4.0.alpha.7/lib/neo4j/driver/synchronizable.rb line 16 in block (4 levels) in with_sync_wrapper
File /usr/local/bundle/gems/async-2.0.3/lib/async/task.rb line 255 in block in schedule

Is it possible you are trying to acquire a new connection while closing the connection pool?

@ioquatix I see you opened socketry/async-pool#14. Were you able to reproduce the second error?

NoMethodError:
undefined method `zero?' for nil:NilClass

				if usage.zero?
				        ^^^^^^

No sorry I have not had time, but will check it next week.

Do have a repro script I can use?

@ioquatix

Is it possible you are trying to acquire a new connection while closing the connection pool?

Yes, it is well possible. We store the pool as an instance variable of effectively a singleton. So multiple threads are accessing the pool. However, if I understood you correctly when exiting the async block the connection pool is closed. So the current pattern is that we constantly create new pools. But until the pool is closed threads can request a new resource in an async context. I know that is not ideal and we are trying to replace async-pool with a different implementation.

Async::Pool is not thread safe and not designed to be used across threads. You should use per-thread pool (e.g. use the thread-local gem), or use thread safe pool.

Confirmed this is no longer an issue with 4.4.0.alpha.9.