neo4j-ruby-driver 1.7.4 → 4.4.0

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 (342) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +37 -42
  3. data/lib/loader.rb +5 -3
  4. data/lib/neo4j/driver/auto_closable.rb +2 -2
  5. data/lib/neo4j/driver/exceptions/authentication_exception.rb +6 -1
  6. data/lib/neo4j/driver/exceptions/authorization_expired_exception.rb +14 -0
  7. data/lib/neo4j/driver/{types/bytes.rb → exceptions/certificate_exception.rb} +2 -2
  8. data/lib/neo4j/driver/exceptions/client_exception.rb +3 -0
  9. data/lib/neo4j/driver/exceptions/connection_read_timeout_exception.rb +14 -0
  10. data/lib/neo4j/driver/exceptions/database_exception.rb +3 -0
  11. data/lib/neo4j/driver/exceptions/discovery_exception.rb +16 -0
  12. data/lib/neo4j/driver/exceptions/fatal_discovery_exception.rb +13 -0
  13. data/lib/neo4j/driver/exceptions/protocol_exception.rb +7 -0
  14. data/lib/neo4j/driver/exceptions/result_consumed_exception.rb +13 -0
  15. data/lib/neo4j/driver/exceptions/security_exception.rb +5 -1
  16. data/lib/neo4j/driver/exceptions/service_unavailable_exception.rb +2 -0
  17. data/lib/neo4j/driver/exceptions/session_expired_exception.rb +4 -0
  18. data/lib/neo4j/driver/exceptions/token_expired_exception.rb +15 -0
  19. data/lib/neo4j/driver/exceptions/transaction_nesting_exception.rb +11 -0
  20. data/lib/neo4j/driver/exceptions/transient_exception.rb +3 -0
  21. data/lib/neo4j/driver/exceptions/untrusted_server_exception.rb +1 -0
  22. data/lib/neo4j/driver/exceptions/value/lossy_coercion.rb +15 -0
  23. data/lib/neo4j/driver/exceptions/value/not_multi_valued.rb +13 -0
  24. data/lib/neo4j/driver/exceptions/value/uncoercible.rb +15 -0
  25. data/lib/neo4j/driver/exceptions/value/unsizable.rb +12 -0
  26. data/lib/neo4j/driver/exceptions/value/value_exception.rb +12 -0
  27. data/lib/neo4j/driver/internal/bolt_server_address.rb +97 -0
  28. data/lib/neo4j/driver/internal/duration_normalizer.rb +1 -1
  29. data/lib/neo4j/driver/internal/validator.rb +5 -4
  30. data/{ffi/neo4j/driver/summary/statement_type.rb → lib/neo4j/driver/summary/query_type.rb} +1 -3
  31. data/lib/neo4j/driver/synchronizable.rb +23 -0
  32. data/lib/neo4j/driver/types/time.rb +4 -2
  33. data/lib/neo4j_ruby_driver.rb +5 -10
  34. data/{ffi → ruby}/neo4j/driver/access_mode.rb +2 -2
  35. data/ruby/neo4j/driver/auth_tokens.rb +34 -0
  36. data/ruby/neo4j/driver/bookmark.rb +21 -0
  37. data/ruby/neo4j/driver/config.rb +89 -0
  38. data/ruby/neo4j/driver/graph_database.rb +80 -0
  39. data/ruby/neo4j/driver/internal/async/connection/bolt_protocol_util.rb +51 -0
  40. data/ruby/neo4j/driver/internal/async/connection/bootstrap_factory.rb +22 -0
  41. data/ruby/neo4j/driver/internal/async/connection/channel_attributes.rb +31 -0
  42. data/ruby/neo4j/driver/internal/async/connection/channel_connected_listener.rb +32 -0
  43. data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +83 -0
  44. data/ruby/neo4j/driver/internal/async/connection/channel_pipeline_builder_impl.rb +22 -0
  45. data/ruby/neo4j/driver/internal/async/connection/direct_connection.rb +30 -0
  46. data/ruby/neo4j/driver/internal/async/connection/event_loop_group_factory.rb +83 -0
  47. data/ruby/neo4j/driver/internal/async/connection/handshake_completed_listener.rb +27 -0
  48. data/ruby/neo4j/driver/internal/async/connection/handshake_handler.rb +113 -0
  49. data/ruby/neo4j/driver/internal/async/connection/netty_channel_initializer.rb +57 -0
  50. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver.rb +26 -0
  51. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver_group.rb +19 -0
  52. data/ruby/neo4j/driver/internal/async/connection/routing_connection.rb +36 -0
  53. data/ruby/neo4j/driver/internal/async/connection/stream.rb +12 -0
  54. data/ruby/neo4j/driver/internal/async/connection/stream_reader.rb +16 -0
  55. data/ruby/neo4j/driver/internal/async/connection_context.rb +10 -0
  56. data/ruby/neo4j/driver/internal/async/immutable_connection_context.rb +24 -0
  57. data/ruby/neo4j/driver/internal/async/inbound/byte_buf_input.rb +30 -0
  58. data/ruby/neo4j/driver/internal/async/inbound/channel_error_handler.rb +77 -0
  59. data/ruby/neo4j/driver/internal/async/inbound/chunk_decoder.rb +41 -0
  60. data/ruby/neo4j/driver/internal/async/inbound/connect_timeout_handler.rb +32 -0
  61. data/ruby/neo4j/driver/internal/async/inbound/connection_read_timeout_handler.rb +17 -0
  62. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +171 -0
  63. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_handler.rb +42 -0
  64. data/ruby/neo4j/driver/internal/async/inbound/message_decoder.rb +51 -0
  65. data/ruby/neo4j/driver/internal/async/internal_async_session.rb +98 -0
  66. data/ruby/neo4j/driver/internal/async/internal_async_transaction.rb +13 -0
  67. data/ruby/neo4j/driver/internal/async/leak_logging_network_session.rb +34 -0
  68. data/ruby/neo4j/driver/internal/async/network_connection.rb +194 -0
  69. data/ruby/neo4j/driver/internal/async/network_session.rb +150 -0
  70. data/ruby/neo4j/driver/internal/async/outbound/chunk_aware_byte_buf_output.rb +110 -0
  71. data/ruby/neo4j/driver/internal/async/outbound/outbound_message_handler.rb +39 -0
  72. data/ruby/neo4j/driver/internal/async/pool/channel.rb +62 -0
  73. data/ruby/neo4j/driver/internal/async/pool/channel_pool.rb +31 -0
  74. data/ruby/neo4j/driver/internal/async/pool/channel_tracker.rb +135 -0
  75. data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +156 -0
  76. data/ruby/neo4j/driver/internal/async/pool/netty_channel_health_checker.rb +87 -0
  77. data/ruby/neo4j/driver/internal/async/pool/netty_channel_pool.rb +52 -0
  78. data/ruby/neo4j/driver/internal/async/pool/network_connection_factory.rb +21 -0
  79. data/ruby/neo4j/driver/internal/async/pool/pool_settings.rb +34 -0
  80. data/ruby/neo4j/driver/internal/async/pool/timed_stack.rb +15 -0
  81. data/ruby/neo4j/driver/internal/async/result_cursors_holder.rb +17 -0
  82. data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +212 -0
  83. data/ruby/neo4j/driver/internal/bookmark_holder.rb +9 -0
  84. data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +48 -0
  85. data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +14 -0
  86. data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +122 -0
  87. data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +10 -0
  88. data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +68 -0
  89. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +125 -0
  90. data/ruby/neo4j/driver/internal/cluster/loadbalancing/round_robin_array_index.rb +13 -0
  91. data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +31 -0
  92. data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +147 -0
  93. data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +43 -0
  94. data/ruby/neo4j/driver/internal/cluster/routing_context.rb +77 -0
  95. data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +60 -0
  96. data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +35 -0
  97. data/ruby/neo4j/driver/internal/cluster/routing_settings.rb +24 -0
  98. data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +95 -0
  99. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +121 -0
  100. data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +73 -0
  101. data/ruby/neo4j/driver/internal/connection_settings.rb +16 -0
  102. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +55 -0
  103. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +24 -0
  104. data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +61 -0
  105. data/ruby/neo4j/driver/internal/cursor/result_cursor_factory_impl.rb +24 -0
  106. data/ruby/neo4j/driver/internal/cursor/rx_result_cursor_impl.rb +110 -0
  107. data/ruby/neo4j/driver/internal/database_name_util.rb +37 -0
  108. data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +9 -0
  109. data/ruby/neo4j/driver/internal/default_domain_name_resolver.rb +11 -0
  110. data/ruby/neo4j/driver/internal/direct_connection_provider.rb +40 -0
  111. data/ruby/neo4j/driver/internal/driver_factory.rb +126 -0
  112. data/ruby/neo4j/driver/internal/handlers/begin_tx_response_handler.rb +20 -0
  113. data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +30 -0
  114. data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +25 -0
  115. data/ruby/neo4j/driver/internal/handlers/hello_response_handler.rb +65 -0
  116. data/ruby/neo4j/driver/internal/handlers/init_response_handler.rb +34 -0
  117. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +199 -0
  118. data/ruby/neo4j/driver/internal/handlers/no_op_response_handler.rb +16 -0
  119. data/ruby/neo4j/driver/internal/handlers/ping_response_handler.rb +29 -0
  120. data/ruby/neo4j/driver/internal/handlers/pull_handlers.rb +32 -0
  121. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +168 -0
  122. data/ruby/neo4j/driver/internal/handlers/pulln/basic_pull_response_handler.rb +298 -0
  123. data/ruby/neo4j/driver/internal/handlers/pulln/fetch_size_util.rb +20 -0
  124. data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +34 -0
  125. data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +25 -0
  126. data/ruby/neo4j/driver/internal/handlers/route_message_response_handler.rb +21 -0
  127. data/ruby/neo4j/driver/internal/handlers/routing_response_handler.rb +70 -0
  128. data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +38 -0
  129. data/ruby/neo4j/driver/internal/handlers/session_pull_response_completion_listener.rb +34 -0
  130. data/ruby/neo4j/driver/internal/handlers/transaction_pull_response_completion_listener.rb +20 -0
  131. data/ruby/neo4j/driver/internal/impersonation_util.rb +22 -0
  132. data/ruby/neo4j/driver/internal/internal_bookmark.rb +36 -0
  133. data/ruby/neo4j/driver/internal/internal_database_name.rb +9 -0
  134. data/ruby/neo4j/driver/internal/internal_driver.rb +74 -0
  135. data/ruby/neo4j/driver/internal/internal_entity.rb +20 -0
  136. data/ruby/neo4j/driver/internal/internal_node.rb +21 -0
  137. data/ruby/neo4j/driver/internal/internal_pair.rb +9 -0
  138. data/ruby/neo4j/driver/internal/internal_path.rb +35 -0
  139. data/ruby/neo4j/driver/internal/internal_point2_d.rb +9 -0
  140. data/ruby/neo4j/driver/internal/internal_point3_d.rb +6 -0
  141. data/{ffi → ruby}/neo4j/driver/internal/internal_record.rb +2 -1
  142. data/ruby/neo4j/driver/internal/internal_relationship.rb +26 -0
  143. data/ruby/neo4j/driver/internal/internal_result.rb +49 -0
  144. data/ruby/neo4j/driver/internal/internal_session.rb +81 -0
  145. data/ruby/neo4j/driver/internal/internal_transaction.rb +48 -0
  146. data/ruby/neo4j/driver/internal/logging/channel_activity_logger.rb +29 -0
  147. data/ruby/neo4j/driver/internal/logging/channel_error_logger.rb +17 -0
  148. data/ruby/neo4j/driver/internal/logging/prefixed_logger.rb +19 -0
  149. data/ruby/neo4j/driver/internal/logging/reformatted_logger.rb +17 -0
  150. data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +23 -0
  151. data/ruby/neo4j/driver/internal/messaging/bolt_protocol.rb +30 -0
  152. data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +48 -0
  153. data/ruby/neo4j/driver/internal/messaging/common/common_message_reader.rb +51 -0
  154. data/ruby/neo4j/driver/internal/messaging/common/common_value.rb +31 -0
  155. data/ruby/neo4j/driver/internal/messaging/common/common_value_packer.rb +101 -0
  156. data/ruby/neo4j/driver/internal/messaging/common/common_value_unpacker.rb +234 -0
  157. data/ruby/neo4j/driver/internal/messaging/encode/begin_message_encoder.rb +15 -0
  158. data/ruby/neo4j/driver/internal/messaging/encode/commit_message_encoder.rb +14 -0
  159. data/ruby/neo4j/driver/internal/messaging/encode/discard_all_message_encoder.rb +14 -0
  160. data/ruby/neo4j/driver/internal/messaging/encode/discard_message_encoder.rb +15 -0
  161. data/ruby/neo4j/driver/internal/messaging/encode/goodbye_message_encoder.rb +14 -0
  162. data/ruby/neo4j/driver/internal/messaging/encode/hello_message_encoder.rb +15 -0
  163. data/ruby/neo4j/driver/internal/messaging/encode/init_message_encoder.rb +16 -0
  164. data/ruby/neo4j/driver/internal/messaging/encode/pull_all_message_encoder.rb +14 -0
  165. data/ruby/neo4j/driver/internal/messaging/encode/pull_message_encoder.rb +15 -0
  166. data/ruby/neo4j/driver/internal/messaging/encode/reset_message_encoder.rb +14 -0
  167. data/ruby/neo4j/driver/internal/messaging/encode/rollback_message_encoder.rb +14 -0
  168. data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +24 -0
  169. data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +22 -0
  170. data/ruby/neo4j/driver/internal/messaging/encode/run_message_encoder.rb +16 -0
  171. data/ruby/neo4j/driver/internal/messaging/encode/run_with_metadata_message_encoder.rb +17 -0
  172. data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +25 -0
  173. data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +25 -0
  174. data/ruby/neo4j/driver/internal/messaging/request/commit_message.rb +20 -0
  175. data/ruby/neo4j/driver/internal/messaging/request/discard_all_message.rb +20 -0
  176. data/ruby/neo4j/driver/internal/messaging/request/discard_message.rb +23 -0
  177. data/ruby/neo4j/driver/internal/messaging/request/goodbye_message.rb +20 -0
  178. data/ruby/neo4j/driver/internal/messaging/request/hello_message.rb +31 -0
  179. data/ruby/neo4j/driver/internal/messaging/request/init_message.rb +19 -0
  180. data/ruby/neo4j/driver/internal/messaging/request/message_with_metadata.rb +10 -0
  181. data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +26 -0
  182. data/ruby/neo4j/driver/internal/messaging/request/pull_all_message.rb +23 -0
  183. data/ruby/neo4j/driver/internal/messaging/request/pull_message.rb +22 -0
  184. data/ruby/neo4j/driver/internal/messaging/request/reset_message.rb +32 -0
  185. data/ruby/neo4j/driver/internal/messaging/request/rollback_message.rb +20 -0
  186. data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +28 -0
  187. data/ruby/neo4j/driver/internal/messaging/request/run_message.rb +23 -0
  188. data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +49 -0
  189. data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +24 -0
  190. data/ruby/neo4j/driver/internal/messaging/response/failure_message.rb +40 -0
  191. data/ruby/neo4j/driver/internal/messaging/response/ignored_message.rb +29 -0
  192. data/ruby/neo4j/driver/internal/messaging/response/record_message.rb +33 -0
  193. data/ruby/neo4j/driver/internal/messaging/response/success_message.rb +34 -0
  194. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +82 -0
  195. data/ruby/neo4j/driver/internal/messaging/v3/message_format_v3.rb +17 -0
  196. data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +27 -0
  197. data/ruby/neo4j/driver/internal/messaging/v4/bolt_protocol_v4.rb +29 -0
  198. data/ruby/neo4j/driver/internal/messaging/v4/message_format_v4.rb +17 -0
  199. data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +17 -0
  200. data/ruby/neo4j/driver/internal/messaging/v41/bolt_protocol_v41.rb +25 -0
  201. data/ruby/neo4j/driver/internal/messaging/v42/bolt_protocol_v42.rb +13 -0
  202. data/ruby/neo4j/driver/internal/messaging/v43/bolt_protocol_v43.rb +19 -0
  203. data/ruby/neo4j/driver/internal/messaging/v43/message_format_v43.rb +18 -0
  204. data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +20 -0
  205. data/ruby/neo4j/driver/internal/messaging/v44/bolt_protocol_v44.rb +17 -0
  206. data/ruby/neo4j/driver/internal/messaging/v44/message_format_v44.rb +18 -0
  207. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +15 -0
  208. data/ruby/neo4j/driver/internal/metrics/connection_pool_metrics_listener.rb +34 -0
  209. data/ruby/neo4j/driver/internal/metrics/internal_abstract_metrics.rb +46 -0
  210. data/ruby/neo4j/driver/internal/metrics/internal_connection_pool_metrics.rb +105 -0
  211. data/ruby/neo4j/driver/internal/metrics/internal_metrics.rb +82 -0
  212. data/ruby/neo4j/driver/internal/metrics/internal_metrics_provider.rb +18 -0
  213. data/ruby/neo4j/driver/internal/metrics/listener_event.rb +17 -0
  214. data/ruby/neo4j/driver/internal/metrics/metrics_provider.rb +24 -0
  215. data/ruby/neo4j/driver/internal/metrics/time_recorder_listener_event.rb +15 -0
  216. data/ruby/neo4j/driver/internal/packstream/byte_array_incompatible_packer.rb +12 -0
  217. data/ruby/neo4j/driver/internal/packstream/pack_input.rb +47 -0
  218. data/ruby/neo4j/driver/internal/packstream/pack_output.rb +39 -0
  219. data/ruby/neo4j/driver/internal/packstream/pack_stream.rb +326 -0
  220. data/ruby/neo4j/driver/internal/packstream/pack_type.rb +17 -0
  221. data/ruby/neo4j/driver/internal/read_only_bookmark_holder.rb +13 -0
  222. data/ruby/neo4j/driver/internal/resolved_bolt_server_address.rb +35 -0
  223. data/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +151 -0
  224. data/ruby/neo4j/driver/internal/revocation_strategy.rb +19 -0
  225. data/ruby/neo4j/driver/internal/scheme.rb +32 -0
  226. data/ruby/neo4j/driver/internal/security/internal_auth_token.rb +15 -0
  227. data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +48 -0
  228. data/ruby/neo4j/driver/internal/security_setting.rb +66 -0
  229. data/ruby/neo4j/driver/internal/session_factory_impl.rb +32 -0
  230. data/ruby/neo4j/driver/internal/spi/connection.rb +19 -0
  231. data/ruby/neo4j/driver/internal/spi/connection_pool.rb +9 -0
  232. data/ruby/neo4j/driver/internal/spi/response_handler.rb +23 -0
  233. data/ruby/neo4j/driver/internal/summary/internal_database_info.rb +7 -0
  234. data/ruby/neo4j/driver/internal/summary/internal_input_position.rb +11 -0
  235. data/ruby/neo4j/driver/internal/summary/internal_notification.rb +16 -0
  236. data/ruby/neo4j/driver/internal/summary/internal_plan.rb +41 -0
  237. data/ruby/neo4j/driver/internal/summary/internal_profiled_plan.rb +32 -0
  238. data/ruby/neo4j/driver/internal/summary/internal_result_summary.rb +33 -0
  239. data/ruby/neo4j/driver/internal/summary/internal_server_info.rb +6 -0
  240. data/ruby/neo4j/driver/internal/summary/internal_summary_counters.rb +18 -0
  241. data/ruby/neo4j/driver/internal/svm/netty_substitutions.rb +196 -0
  242. data/ruby/neo4j/driver/internal/svm/z_lib_substitutions.rb +21 -0
  243. data/ruby/neo4j/driver/internal/util/certificate_tool.rb +65 -0
  244. data/ruby/neo4j/driver/internal/util/clock.rb +29 -0
  245. data/ruby/neo4j/driver/internal/util/error_util.rb +104 -0
  246. data/ruby/neo4j/driver/internal/util/extract.rb +123 -0
  247. data/ruby/neo4j/driver/internal/util/format.rb +39 -0
  248. data/ruby/neo4j/driver/internal/util/futures.rb +99 -0
  249. data/ruby/neo4j/driver/internal/util/iterables.rb +35 -0
  250. data/ruby/neo4j/driver/internal/util/lock_util.rb +23 -0
  251. data/ruby/neo4j/driver/internal/util/metadata_extractor.rb +107 -0
  252. data/ruby/neo4j/driver/internal/util/mutex.rb +9 -0
  253. data/ruby/neo4j/driver/internal/util/preconditions.rb +16 -0
  254. data/ruby/neo4j/driver/internal/util/result_holder.rb +72 -0
  255. data/ruby/neo4j/driver/internal/util/server_version.rb +60 -0
  256. data/ruby/neo4j/driver/logging1.rb +51 -0
  257. data/ruby/neo4j/driver/net/server_address.rb +9 -0
  258. data/ruby/neo4j/driver/query.rb +48 -0
  259. data/ruby/neo4j/driver/records.rb +13 -0
  260. data/ruby/neo4j/driver/transaction_config.rb +50 -0
  261. data/ruby/neo4j/driver/values.rb +26 -0
  262. data/{lib → ruby}/neo4j/driver/version.rb +1 -1
  263. data/ruby/neo4j/driver.rb +29 -0
  264. metadata +264 -101
  265. data/ffi/bolt/address.rb +0 -11
  266. data/ffi/bolt/address_resolver.rb +0 -12
  267. data/ffi/bolt/address_set.rb +0 -9
  268. data/ffi/bolt/auth.rb +0 -10
  269. data/ffi/bolt/auto_releasable.rb +0 -22
  270. data/ffi/bolt/boolean.rb +0 -9
  271. data/ffi/bolt/bytes.rb +0 -10
  272. data/ffi/bolt/config.rb +0 -45
  273. data/ffi/bolt/connection.rb +0 -44
  274. data/ffi/bolt/connector.rb +0 -17
  275. data/ffi/bolt/dictionary.rb +0 -15
  276. data/ffi/bolt/error.rb +0 -74
  277. data/ffi/bolt/float.rb +0 -9
  278. data/ffi/bolt/integer.rb +0 -9
  279. data/ffi/bolt/library.rb +0 -12
  280. data/ffi/bolt/lifecycle.rb +0 -9
  281. data/ffi/bolt/list.rb +0 -10
  282. data/ffi/bolt/log.rb +0 -16
  283. data/ffi/bolt/socket_options.rb +0 -14
  284. data/ffi/bolt/status.rb +0 -25
  285. data/ffi/bolt/string.rb +0 -9
  286. data/ffi/bolt/structure.rb +0 -10
  287. data/ffi/bolt/value.rb +0 -35
  288. data/ffi/neo4j/driver/auth_tokens.rb +0 -18
  289. data/ffi/neo4j/driver/config.rb +0 -40
  290. data/ffi/neo4j/driver/graph_database.rb +0 -52
  291. data/ffi/neo4j/driver/internal/async/access_mode_connection.rb +0 -19
  292. data/ffi/neo4j/driver/internal/async/direct_connection.rb +0 -106
  293. data/ffi/neo4j/driver/internal/bolt_server_address.rb +0 -18
  294. data/ffi/neo4j/driver/internal/bookmarks_holder.rb +0 -30
  295. data/ffi/neo4j/driver/internal/direct_connection_provider.rb +0 -28
  296. data/ffi/neo4j/driver/internal/driver_factory.rb +0 -125
  297. data/ffi/neo4j/driver/internal/error_handling.rb +0 -112
  298. data/ffi/neo4j/driver/internal/explicit_transaction.rb +0 -146
  299. data/ffi/neo4j/driver/internal/handlers/pull_all_response_handler.rb +0 -104
  300. data/ffi/neo4j/driver/internal/handlers/response_handler.rb +0 -49
  301. data/ffi/neo4j/driver/internal/handlers/run_response_handler.rb +0 -32
  302. data/ffi/neo4j/driver/internal/handlers/session_pull_all_response_handler.rb +0 -32
  303. data/ffi/neo4j/driver/internal/handlers/transaction_pull_all_response_handler.rb +0 -23
  304. data/ffi/neo4j/driver/internal/internal_driver.rb +0 -45
  305. data/ffi/neo4j/driver/internal/internal_logger.rb +0 -32
  306. data/ffi/neo4j/driver/internal/internal_resolver.rb +0 -31
  307. data/ffi/neo4j/driver/internal/internal_statement_result.rb +0 -52
  308. data/ffi/neo4j/driver/internal/messaging/bolt_protocol.rb +0 -24
  309. data/ffi/neo4j/driver/internal/messaging/v1/bolt_protocol_v1.rb +0 -59
  310. data/ffi/neo4j/driver/internal/messaging/v2/bolt_protocol_v2.rb +0 -16
  311. data/ffi/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +0 -63
  312. data/ffi/neo4j/driver/internal/network_session.rb +0 -129
  313. data/ffi/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +0 -80
  314. data/ffi/neo4j/driver/internal/session_factory_impl.rb +0 -28
  315. data/ffi/neo4j/driver/internal/summary/internal_result_summary.rb +0 -67
  316. data/ffi/neo4j/driver/internal/summary/internal_server_info.rb +0 -19
  317. data/ffi/neo4j/driver/internal/summary/internal_summary_counters.rb +0 -23
  318. data/ffi/neo4j/driver/internal/util/metadata_extractor.rb +0 -15
  319. data/ffi/neo4j/driver/internal/value/base_time_value.rb +0 -22
  320. data/ffi/neo4j/driver/internal/value/date_value.rb +0 -25
  321. data/ffi/neo4j/driver/internal/value/duration_value.rb +0 -27
  322. data/ffi/neo4j/driver/internal/value/local_date_time_value.rb +0 -24
  323. data/ffi/neo4j/driver/internal/value/local_time_value.rb +0 -19
  324. data/ffi/neo4j/driver/internal/value/node_value.rb +0 -18
  325. data/ffi/neo4j/driver/internal/value/offset_time_value.rb +0 -25
  326. data/ffi/neo4j/driver/internal/value/path_value.rb +0 -41
  327. data/ffi/neo4j/driver/internal/value/point2_d_value.rb +0 -24
  328. data/ffi/neo4j/driver/internal/value/point3_d_value.rb +0 -24
  329. data/ffi/neo4j/driver/internal/value/relationship_value.rb +0 -18
  330. data/ffi/neo4j/driver/internal/value/structure_value.rb +0 -42
  331. data/ffi/neo4j/driver/internal/value/time_with_zone_id_value.rb +0 -25
  332. data/ffi/neo4j/driver/internal/value/time_with_zone_offset_value.rb +0 -28
  333. data/ffi/neo4j/driver/internal/value/unbound_relationship_value.rb +0 -18
  334. data/ffi/neo4j/driver/internal/value/value_adapter.rb +0 -101
  335. data/ffi/neo4j/driver/net/server_address.rb +0 -13
  336. data/ffi/neo4j/driver/statement.rb +0 -15
  337. data/ffi/neo4j/driver/types/entity.rb +0 -21
  338. data/ffi/neo4j/driver/types/node.rb +0 -16
  339. data/ffi/neo4j/driver/types/path.rb +0 -35
  340. data/ffi/neo4j/driver/types/relationship.rb +0 -19
  341. data/ffi/neo4j/driver.rb +0 -61
  342. data/lib/neo4j/driver/internal/ruby_signature.rb +0 -18
@@ -0,0 +1,171 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ module Inbound
5
+ class InboundMessageDispatcher
6
+ attr_reader :fatal_error_occurred, :current_error
7
+
8
+ def initialize(channel, logger)
9
+ @handlers = []
10
+ @channel = Validator.require_non_nil!(channel)
11
+ @log = Logging::ChannelActivityLogger.new(channel, logger, self.class)
12
+ @error_log = Logging::ChannelErrorLogger.new(channel, logger)
13
+ end
14
+
15
+ def enqueue(handler)
16
+ if fatal_error_occurred
17
+ handler.on_failure(@current_error)
18
+ else
19
+ @handlers << handler
20
+ update_auto_read_managing_handler_if_needed(handler)
21
+ end
22
+ end
23
+
24
+ def set_before_last_handler_hook(before_last_handler_hook)
25
+ unless @channel.event_loop.in_event_loop
26
+ raise Neo4j::Driver::Exceptions::IllegalStateException.new('This method may only be called in the EventLoop')
27
+ end
28
+ @before_last_handler_hook = before_last_handler_hook
29
+ end
30
+
31
+ def queued_handlers_count
32
+ @handlers.size
33
+ end
34
+
35
+ def handle_success_message(meta)
36
+ @log.debug("S: SUCCESS #{meta}")
37
+ invoke_before_last_handler_hook(HandlerHook::SUCCESS)
38
+ handler = remove_handler
39
+ handler.on_success(meta)
40
+ end
41
+
42
+ def handle_record_message(fields)
43
+ @log.debug { "S: RECORD #{fields}" }
44
+
45
+ (@handlers.first or
46
+ raise Exceptions::IllegalStateException,
47
+ "No handler exists to handle RECORD message with fields #{fields}")
48
+ .on_record(fields)
49
+ end
50
+
51
+ def handle_failure_message(code:, message:)
52
+ @log.debug("S: FAILURE #{code}, '#{message}'")
53
+ @current_error = Util::ErrorUtil.new_neo4j_error(code, message)
54
+
55
+ # we should not continue using channel after a fatal error
56
+ # fire error event back to the pipeline and avoid sending RESET
57
+
58
+ # return @channel.pipeline.fire_exception_caught(current_error) if Util::ErrorUtil.fatal?(current_error)
59
+ raise @current_error if Util::ErrorUtil.fatal?(@current_error) # TODO clarify
60
+
61
+ if @current_error.is_a?(Exceptions::AuthorizationExpiredException)
62
+ # TODO: ??????
63
+ # Connection::ChannelAttributes.authorization_state_listener(@channel).on_expired(@current_error, @channel)
64
+ else
65
+ # write a RESET to "acknowledge" the failure
66
+ enqueue(Handlers::ResetResponseHandler.new(self))
67
+ @channel.write_and_flush(Messaging::Request::ResetMessage::RESET)
68
+ end
69
+
70
+ invoke_before_last_handler_hook(HandlerHook::FAILURE)
71
+ handler = remove_handler
72
+ handler.on_failure(@current_error)
73
+ end
74
+
75
+ def handle_ignored_message
76
+ @log.debug('S: IGNORED')
77
+ handler = remove_handler
78
+
79
+ if @current_error
80
+ error = @current_error
81
+ else
82
+ @log.warn("Received IGNORED message for handler #{handler} but error is missing and RESET is not in progress. Current handlers #{@handlers}")
83
+ error = Exceptions::ClientException.new('Database ignored the request')
84
+ end
85
+
86
+ handler.on_failure(error)
87
+ end
88
+
89
+ def handle_channel_inactive(cause)
90
+ # report issue if the connection has not been terminated as a result of a graceful shutdown request from its
91
+ # parent pool
92
+ if !@gracefully_closed
93
+ handle_channel_error(cause)
94
+ else
95
+ @channel.close
96
+ end
97
+ end
98
+
99
+ def handle_channel_error(error)
100
+ if @current_error
101
+ # we already have an error, this new error probably is caused by the existing one, thus we chain the new error on this current error
102
+ Util::ErrorUtil.add_suppressed(@current_error, error)
103
+ else
104
+ @current_error = error
105
+ end
106
+
107
+ @fatal_error_occurred = true
108
+
109
+ while !@handlers.empty?
110
+ handler = remove_handler
111
+ handler.on_failure(@current_error)
112
+ end
113
+
114
+ @error_log.trace_or_debug('Closing channel because of a failure', error)
115
+ @channel.close
116
+ end
117
+
118
+ def clear_current_error
119
+ @current_error = nil
120
+ end
121
+
122
+ def prepare_to_close_channel
123
+ @gracefully_closed = true
124
+ end
125
+
126
+ def remove_handler
127
+ handler = @handlers.shift
128
+
129
+ if handler == @auto_read_managing_handler
130
+ # the auto-read managing handler is being removed
131
+ # make sure this dispatcher does not hold on to a removed handler
132
+ update_auto_read_managing_handler(nil)
133
+ end
134
+ handler
135
+ end
136
+
137
+ private
138
+
139
+ def update_auto_read_managing_handler_if_needed(handler)
140
+ if handler.can_manage_auto_read?
141
+ update_auto_read_managing_handler(handler)
142
+ end
143
+ end
144
+
145
+ def update_auto_read_managing_handler(new_handler)
146
+ if @auto_read_managing_handler
147
+
148
+ # there already exists a handler that manages channel's auto-read
149
+ # make it stop because new managing handler is being added and there should only be a single such handler
150
+ @auto_read_managing_handler.disable_auto_read_management
151
+
152
+ # restore the default value of auto-read
153
+ @channel.auto_read = true
154
+ end
155
+
156
+ @auto_read_managing_handler = new_handler
157
+ end
158
+
159
+ def invoke_before_last_handler_hook(message_type)
160
+ @before_last_handler_hook&.run(message_type) if @handlers.size == 1
161
+ end
162
+
163
+ module HandlerHook
164
+ SUCCESS = :success
165
+ FAILURE = :failure
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,42 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ module Inbound
5
+ class InboundMessageHandler #< org.neo4j.driver.internal.shaded.io.netty.channel.SimpleChannelInboundHandler
6
+ def initialize(message_format, logger)
7
+ @input = ByteBufInput.new
8
+ @reader = message_format.new_reader(input)
9
+ @logger = logger
10
+ end
11
+
12
+ def handler_added(ctx)
13
+ @message_dispatcher = Validator::require_non_nil!(connection.ChannelAttributes.message_dispatcher(ctx.channel))
14
+ @log = Logging::ChannelActivityLogger.new(ctx.channel, logger, self.class)
15
+ end
16
+
17
+ def handler_removed(_ctx)
18
+ @message_dispatcher = nil
19
+ @log = nil
20
+ end
21
+
22
+ def channel_read0(_ctx, msg)
23
+ if message_dispatcher.fatal_error_occurred
24
+ return @log.warn( "Message ignored because of the previous fatal error. Channel will be closed. Message:\n#{org.neo4j.driver.internal.shaded.io.netty.buffer.ByteBufUtil.hex_dump(msg)}")
25
+ end
26
+
27
+ @log.debug( "S: #{org.neo4j.driver.internal.shaded.io.netty.buffer.ByteBufUtil.hex_dump(msg)}") if @log.is_trace_enabled?
28
+
29
+ @input.start(msg)
30
+ begin
31
+ @reader.read(@message_dispatcher)
32
+ rescue StandardError => error
33
+ org.neo4j.driver.internal.shaded.io.netty.handler.codec.DecoderException.new("Failed to read inbound message:\n#{org.neo4j.driver.internal.shaded.io.netty.buffer.ByteBufUtil.hex_dump(msg)}\n", error)
34
+ ensure
35
+ @input.stop
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,51 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ module Inbound
5
+ class MessageDecoder #< org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder
6
+ class << self
7
+ def determine_default_cumulator
8
+ value = ENV['message_decoder_cumulator']
9
+ # 'merge' == value ? org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder::MERGE_CUMULATOR : org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder::COMPOSITE_CUMULATOR
10
+ end
11
+ end
12
+
13
+ DEFAULT_CUMULATOR = determine_default_cumulator
14
+
15
+ def initialize
16
+ set_cumulator(DEFAULT_CUMULATOR)
17
+ end
18
+
19
+ def channel_read(ctx, msg)
20
+ if msg.is_a?(org.neo4j.driver.internal.shaded.io.netty.buffer.ByteBuf)
21
+
22
+ # on every read check if input buffer is empty or not
23
+ # if it is empty then it's a message boundary and full message is in the buffer
24
+ @read_message_boundary = msg.readable_bytes == 0
25
+ end
26
+
27
+ org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channel_read(ctx, msg)
28
+ end
29
+
30
+ def decode(ctx, inward, out)
31
+ if @read_message_boundary
32
+
33
+ # now we have a complete message in the input buffer
34
+
35
+ # increment ref count of the buffer and create it's duplicate that shares the content
36
+ # duplicate will be the output of this decoded and input for the next one
37
+ message_buf = inward.retained_duplicate
38
+
39
+ # signal that whole message was read by making input buffer seem like it was fully read/consumed
40
+ inward.reader_index(inward.readable_bytes)
41
+
42
+ # pass the full message to the next handler in the pipeline
43
+ out.add(message_buf)
44
+ @read_message_boundary = false
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,98 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ class InternalAsyncSession
5
+ def initialize(session)
6
+ @session = session
7
+ end
8
+
9
+ delegate :last_bookmark, :close_async, to: :@session
10
+
11
+ def run_async(query, parameters = {}, config = {})
12
+ @session.run_async(org.neo4j.driver.Query.new(query, **parameters), **config)
13
+ end
14
+
15
+ def begin_transaction_async(**config)
16
+ @session.begin_transaction_async(**config).then(&InternalAsyncTransaction.method(:new))
17
+ end
18
+
19
+ def read_transaction_async(**config, &work)
20
+ transaction_async(org.neo4j.driver.AccessMode::READ, **config, &work)
21
+ end
22
+
23
+ def write_transaction_async(**config, &work)
24
+ transaction_async(org.neo4j.driver.AccessMode::WRITE, **config, &work)
25
+ end
26
+
27
+ private
28
+
29
+ def transaction_async(mode, **config, &work)
30
+ @session.retry_logic.retry_async do
31
+ result_future = java.util.concurrent.CompletableFuture.new
32
+ tx_future = @session.begin_transaction_async(mode, ** config)
33
+
34
+ tx_future.when_complete do |tx, completion_error|
35
+ error = Util::Futures.completion_exception_cause(completion_error)
36
+
37
+ if !error.nil?
38
+ result_future.complete_exceptionally(error)
39
+ else
40
+ execute_work(result_future, tx, &work)
41
+ end
42
+ end
43
+ result_future
44
+ end
45
+ end
46
+
47
+ def execute_work(result_future, tx, &work)
48
+ work_future = safe_execute_work(tx, &work)
49
+
50
+ work_future.when_complete do |result, completion_error|
51
+ error = Util::Futures.completion_exception_cause(completion_error)
52
+
53
+ if !error.nil?
54
+ close_tx_after_failed_transaction_work(tx, result_future, error)
55
+ else
56
+ close_tx_after_succeeded_transaction_work(tx, result_future, result)
57
+ end
58
+ end
59
+ end
60
+
61
+ def safe_execute_work(tx)
62
+ # given work might fail in both async and sync way
63
+ # async failure will result in a failed future being returned
64
+ # sync failure will result in an exception being thrown
65
+ begin
66
+ result = yield InternalAsyncTransaction.new(tx)
67
+
68
+ # protect from given transaction function returning null
69
+ result == nil ? Util::Futures.completed_with_null : result
70
+ rescue StandardError => work_error
71
+ # work threw an exception, wrap it in a future and proceed
72
+ Util::Futures.failed_future(work_error)
73
+ end
74
+ end
75
+
76
+ def close_tx_after_failed_transaction_work(tx, result_future, error)
77
+ tx.close_async.when_complete do |_ignored, rollback_error|
78
+ error.add_suppressed(rollback_error) unless rollback_error.nil?
79
+
80
+ result_future.complete_exceptionally(error)
81
+ end
82
+ end
83
+
84
+ def close_tx_after_succeeded_transaction_work(tx, result_future, result)
85
+ tx.close_async(true).when_complete do |_ignored, completion_error|
86
+ commit_error = Util::Futures.completion_exception_cause(completion_error)
87
+
88
+ if !commit_error.nil?
89
+ result_future.complete_exceptionally(commit_error)
90
+ else
91
+ result_future.complete(result)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,13 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ class InternalAsyncTransaction
5
+ delegate :run_async, :commit_async, :rollback_async, :open?, to: :@tx
6
+
7
+ def initialize(tx)
8
+ @tx = tx
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ class LeakLoggingNetworkSession < NetworkSession
5
+ def initialize(connection_provider, retry_logic, database_name, mode, bookmark_holder, impersonated_user, fetch_size, logger)
6
+ super
7
+ @stack_trace = capture_stack_trace
8
+ end
9
+
10
+ def finalize
11
+ log_leak_if_needed
12
+ super
13
+ end
14
+
15
+ private
16
+
17
+ def log_leak_if_needed
18
+ is_open = Util::Futures.blocking_get(current_connection_is_open)
19
+ if is_open
20
+ @log.error do
21
+ "Neo4j Session object leaked, please ensure that your application fully consumes results in "\
22
+ "Sessions or explicitly calls `close` on Sessions before disposing of the objects.\n"\
23
+ "Session was created at:\n#{@stack_trace}"
24
+ end
25
+ end
26
+ end
27
+
28
+ def capture_stack_trace
29
+ Thread.current.backtrace.join("\n")
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,194 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ class NetworkConnection
5
+ include Spi::Connection
6
+ delegate :protocol, to: :@channel
7
+
8
+ attr_reader :server_agent, :server_address, :server_version
9
+
10
+ def initialize(channel, channel_pool, logger, &on_pool_shutdown)
11
+ @log = logger
12
+ @channel = channel
13
+ @message_dispatcher = channel.attributes[:message_dispatcher]
14
+ @server_agent = channel.attributes[:server_agent]
15
+ @server_address = channel.attributes[:server_address]
16
+ @server_version = channel.attributes[:server_version]
17
+ @protocol = Messaging::BoltProtocol.for_channel(channel)
18
+ @channel_pool = channel_pool
19
+ @on_pool_shutdow = on_pool_shutdown
20
+ # @release_future = java.util.concurrent.CompletableFuture.new
21
+ # @clock = clock
22
+ # @connection_read_timeout = Connection::ChannelAttributes.connection_read_timeout(channel) || nil
23
+ @status = Concurrent::AtomicReference.new(Status::OPEN)
24
+ end
25
+
26
+ def open?
27
+ @status.get == Status::OPEN
28
+ end
29
+
30
+ def enable_auto_read
31
+ @channel.auto_read = true if open?
32
+ end
33
+
34
+ def disable_auto_read
35
+ @channel.auto_read = false if open?
36
+ end
37
+
38
+ def flush
39
+ flush_in_event_loop if verify_open(nil, nil)
40
+ end
41
+
42
+ def write(message1, handler1, message2 = nil, handler2 = nil)
43
+ if message2.nil? && handler2.nil?
44
+ write_message_in_event_loop(message1, handler1, false) if verify_open(handler1, nil)
45
+ else
46
+ write_messages_in_event_loop(message1, handler1, message2, handler2, false) if verify_open(handler1, handler2)
47
+ end
48
+ end
49
+
50
+ def write_and_flush(message1, handler1, message2 = nil, handler2 = nil)
51
+ if message2.nil? && handler2.nil?
52
+ write_message_in_event_loop(message1, handler1, true) if verify_open(handler1, nil)
53
+ else
54
+ write_messages_in_event_loop(message1, handler1, message2, handler2, true) if verify_open(handler1, handler2)
55
+ end
56
+ end
57
+
58
+ def reset
59
+ result = java.util.concurrent.CompletableFuture.new
60
+ handler = Handlers::ResetResponseHandler.new(@message_dispatcher, result)
61
+ write_reset_message_if_needed(handler, true)
62
+ result
63
+ end
64
+
65
+ def release
66
+ if @status.compare_and_set(Status::OPEN, Status::RELEASED)
67
+ handler = Handlers::ChannelReleasingResetResponseHandler.new(@channel, @channel_pool, @message_dispatcher, @log, @release)
68
+ write_reset_message_if_needed(handler, false)
69
+ # @metrics_listener.after_connection_released(Connection::ChannelAttributes.pool_id(@channel), @in_use_event)
70
+ # end
71
+ # @release_future
72
+ end
73
+ end
74
+
75
+ def terminate_and_release(reason)
76
+ if @status.compare_and_set(Status::OPEN, Status::TERMINATED)
77
+ @channel.attributes[:termination_reason] = reason
78
+ @channel.close rescue nil
79
+ @channel_pool.release(@channel)
80
+ # @metrics_listener.after_connection_released(Connection::ChannelAttributes.pool_id(@channel), @in_use_event)
81
+ end
82
+ end
83
+
84
+ private
85
+
86
+ def write_reset_message_if_needed(reset_handler, is_session_reset)
87
+ if is_session_reset && !open?
88
+ reset_handler.on_success
89
+ else
90
+ # auto-read could've been disabled, re-enable it to automatically receive response for RESET
91
+ @channel.auto_read = true
92
+ @message_dispatcher.enqueue(reset_handler)
93
+ write_to_channel(Messaging::Request::ResetMessage::RESET, true)
94
+ end
95
+ end
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
+
112
+ def flush_in_event_loop
113
+ @channel.event_loop.execute do
114
+ @channel.flush
115
+ register_connection_read_timeout(@channel)
116
+ end
117
+ end
118
+
119
+ def write_message_in_event_loop(message, handler, flush)
120
+ @message_dispatcher.enqueue(handler)
121
+
122
+ write_to_channel(message, flush)
123
+ end
124
+
125
+ def write_messages_in_event_loop(message1, handler1, message2, handler2, flush)
126
+ @channel.event_loop.execute do
127
+ @message_dispatcher.enqueue(handler1)
128
+ @message_dispatcher.enqueue(handler2)
129
+
130
+ @channel.write(message1, channel.void_promise)
131
+
132
+ if flush
133
+ @channel.write_and_flush(message2).add_listener(-> (_future) { register_connection_read_timeout(@channel) })
134
+ else
135
+ @channel.write(message2, @channel.void_promise)
136
+ end
137
+ end
138
+ end
139
+
140
+ def verify_open(handler1, handler2)
141
+ connection_status = @status.get
142
+
143
+ case connection_status
144
+ when 'open'
145
+ true
146
+ when 'released'
147
+ error = Neo4j::Driver::Exceptions::IllegalStateException.new("Connection has been released to the pool and can't be used")
148
+
149
+ handler1.on_failure(error) unless handler1.nil?
150
+
151
+ handler2.on_failure(error) unless handler2.nil?
152
+
153
+ false
154
+ when 'terminated'
155
+ terminated_error = Neo4j::Driver::Exceptions::IllegalStateException.new("Connection has been terminated and can't be used")
156
+
157
+ handler1.on_failure(terminated_error) unless handler1.nil?
158
+
159
+ handler2.on_failure(terminated_error) unless handler2.nil?
160
+
161
+ false
162
+ else
163
+ raise Neo4j::Driver::Exceptions::IllegalStateException.new("Unknown status: #{connection_status}")
164
+ end
165
+ end
166
+
167
+ def register_connection_read_timeout(channel)
168
+ if !channel.event_loop.in_event_loop
169
+ raise Neo4j::Driver::Exceptions::IllegalStateException.new('This method may only be called in the EventLoop')
170
+ end
171
+
172
+ if !@connection_read_timeout.nil? && @connection_read_timeout_handler.nil?
173
+ connection_read_timeout_handler = Inbound::ConnectionReadTimeoutHandler.new(@connection_read_timeout, java.util.concurrent.TimeUnit::SECONDS)
174
+ channel.pipeline.add_first(connection_read_timeout_handler)
175
+ @log.debug('Added ConnectionReadTimeoutHandler')
176
+
177
+ @message_dispatcher.set_before_last_handler_hook do |message_type|
178
+ channel.pipeline.remove(connection_read_timeout_handler)
179
+ connection_read_timeout_handler = nil
180
+ @message_dispatcher.set_before_last_handler_hook(nil)
181
+ log.debug('Removed ConnectionReadTimeoutHandler')
182
+ end
183
+ end
184
+ end
185
+
186
+ class Status
187
+ OPEN = 'open'
188
+ RELEASED = 'released'
189
+ TERMINATED = 'terminated'
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end