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,15 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Metrics
4
+ class TimeRecorderListenerEvent
5
+ def start
6
+ @start_time = Util::Clock::System.millis
7
+ end
8
+
9
+ def elapsed
10
+ Util::Clock::System.millis - @start_time
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Packstream
4
+ class ByteArrayIncompatiblePacker
5
+ include PackStream::Packer
6
+ def pack_bytes_header(_size)
7
+ raise PackStream::UnPackable.new('Packing bytes is not supported as the current server this driver connected to does not support unpack bytes.')
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,47 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Packstream
4
+ module PackInput
5
+ def read_char
6
+ read_exactly(1)
7
+ end
8
+
9
+ def read_byte
10
+ read_exactly(1).unpack1('c')
11
+ end
12
+
13
+ def read_ubyte
14
+ read_exactly(1).unpack1('C')
15
+ end
16
+
17
+ def read_short
18
+ read_exactly(2).unpack1('s>')
19
+ end
20
+
21
+ def read_ushort
22
+ read_exactly(2).unpack1('S>')
23
+ end
24
+
25
+ def read_int
26
+ read_exactly(4).unpack1('l>')
27
+ end
28
+
29
+ def read_uint
30
+ read_exactly(4).unpack1('L>')
31
+ end
32
+
33
+ def read_long
34
+ read_exactly(8).unpack1('q>')
35
+ end
36
+
37
+ def read_ulong
38
+ read_exactly(8).unpack1('Q>')
39
+ end
40
+
41
+ def read_double
42
+ read_exactly(8).unpack1('G')
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,39 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Packstream
4
+ module PackOutput
5
+ ## Produce a single byte
6
+ def write_byte(value)
7
+ value.is_a?(String) ? write(value) : write_value(value, 'c')
8
+ end
9
+
10
+ ## Produce a 4-byte signed integer
11
+ def write_short(value)
12
+ write_value(value, 's>')
13
+ end
14
+
15
+ ## Produce a 4-byte signed integer
16
+ def write_int(value)
17
+ write_value(value, 'l>')
18
+ end
19
+
20
+ ## Produce an 8-byte signed integer
21
+ def write_long(value)
22
+ write_value(value, 'q>')
23
+ end
24
+
25
+ ## Produce an 8-byte IEEE 754 "double format" floating-point number
26
+ def write_double(value)
27
+ write_value(value, 'G')
28
+ end
29
+
30
+ private
31
+
32
+ def write_value(value, directive)
33
+ write([value].pack(directive))
34
+ self
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,326 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Packstream
4
+ module PackStream
5
+ module Common
6
+ TINY_STRING = 0x80
7
+ TINY_LIST = 0x90
8
+ TINY_MAP = 0xA0
9
+ TINY_STRUCT = 0xB0
10
+ NULL = 0xC0
11
+ FLOAT_64 = 0xC1
12
+ FALSE = 0xC2
13
+ TRUE = 0xC3
14
+ RESERVED_C4 = 0xC4
15
+ RESERVED_C5 = 0xC5
16
+ RESERVED_C6 = 0xC6
17
+ RESERVED_C7 = 0xC7
18
+ INT_8 = 0xC8
19
+ INT_16 = 0xC9
20
+ INT_32 = 0xCA
21
+ INT_64 = 0xCB
22
+ BYTES_8 = 0xCC
23
+ BYTES_16 = 0xCD
24
+ BYTES_32 = 0xCE
25
+ RESERVED_CF = 0xCF
26
+ STRING_8 = 0xD0
27
+ STRING_16 = 0xD1
28
+ STRING_32 = 0xD2
29
+ RESERVED_D3 = 0xD3
30
+ LIST_8 = 0xD4
31
+ LIST_16 = 0xD5
32
+ LIST_32 = 0xD6
33
+ RESERVED_D7 = 0xD7
34
+ MAP_8 = 0xD8
35
+ MAP_16 = 0xD9
36
+ MAP_32 = 0xDA
37
+ RESERVED_DB = 0xDB
38
+ STRUCT_8 = 0xDC
39
+ STRUCT_16 = 0xDD
40
+ RESERVED_DE = 0xDE
41
+ RESERVED_DF = 0xDF
42
+ RESERVED_E0 = 0xE0
43
+ RESERVED_E1 = 0xE1
44
+ RESERVED_E2 = 0xE2
45
+ RESERVED_E3 = 0xE3
46
+ RESERVED_E4 = 0xE4
47
+ RESERVED_E5 = 0xE5
48
+ RESERVED_E6 = 0xE6
49
+ RESERVED_E7 = 0xE7
50
+ RESERVED_E8 = 0xE8
51
+ RESERVED_E9 = 0xE9
52
+ RESERVED_EA = 0xEA
53
+ RESERVED_EB = 0xEB
54
+ RESERVED_EC = 0xEC
55
+ RESERVED_ED = 0xED
56
+ RESERVED_EE = 0xEE
57
+ RESERVED_EF = 0xEF
58
+ end
59
+
60
+ PLUS_2_TO_THE_63 = 2 ** 63
61
+ PLUS_2_TO_THE_31 = 2147483648
62
+ PLUS_2_TO_THE_16 = 65536
63
+ PLUS_2_TO_THE_15 = 32768
64
+ PLUS_2_TO_THE_8 = 256
65
+ PLUS_2_TO_THE_7 = 128
66
+ MINUS_2_TO_THE_4 = -16
67
+ MINUS_2_TO_THE_7 = -128
68
+ MINUS_2_TO_THE_15 = -32768
69
+ MINUS_2_TO_THE_31 = -2147483648
70
+ MINUS_2_TO_THE_63 = -2 ** 63
71
+
72
+ module Packer
73
+ include Common
74
+ private def pack_raw(data)
75
+ write(data)
76
+ end
77
+
78
+ def pack_null
79
+ write_byte(NULL)
80
+ end
81
+
82
+ def pack(value)
83
+ case value
84
+ when nil
85
+ pack_null
86
+ when TrueClass
87
+ write_byte(TRUE)
88
+ when FalseClass
89
+ write_byte(FALSE)
90
+ when Integer
91
+ pack_integer(value)
92
+ when Float
93
+ pack_float(value)
94
+ when String
95
+ case value.encoding
96
+ when Encoding::BINARY
97
+ pack_bytes(value)
98
+ when Encoding::UTF_8
99
+ pack_string(value)
100
+ else
101
+ pack_string(value.encode(Encoding::UTF_8))
102
+ end
103
+ when Symbol
104
+ pack_string(value.to_s)
105
+ when InternalPath
106
+ unpackable(value)
107
+ when Hash
108
+ pack_map_header(value.size)
109
+ value.each do |key, val|
110
+ pack(key)
111
+ pack(val)
112
+ end
113
+ when Enumerable
114
+ value = value.to_a
115
+ pack_list_header(value.size)
116
+ value.each(&method(:pack))
117
+ when Bookmark
118
+ pack(value.values)
119
+ else
120
+ unpackable(value)
121
+ end
122
+ end
123
+
124
+ private def unpackable(value)
125
+ raise UnPackable, "Cannot pack object #{value}"
126
+ end
127
+
128
+ def pack_integer(value)
129
+ if value >= MINUS_2_TO_THE_4 && value < PLUS_2_TO_THE_7
130
+ write_byte(value)
131
+ elsif value >= MINUS_2_TO_THE_7 && value < MINUS_2_TO_THE_4
132
+ write_byte(INT_8).write_byte(value)
133
+ elsif value >= MINUS_2_TO_THE_15 && value < PLUS_2_TO_THE_15
134
+ write_byte(INT_16).write_short(value)
135
+ elsif value >= MINUS_2_TO_THE_31 && value < PLUS_2_TO_THE_31
136
+ write_byte(INT_32).write_int(value)
137
+ elsif value >= MINUS_2_TO_THE_63 && value < PLUS_2_TO_THE_63
138
+ write_byte(INT_64).write_long(value)
139
+ else
140
+ pack_string(value.to_s)
141
+ end
142
+ end
143
+
144
+ def pack_float(value)
145
+ write_byte(FLOAT_64).write_double(value)
146
+ end
147
+
148
+ private def pack_bytes(value)
149
+ pack_bytes_header(value.bytesize)
150
+ pack_raw(value)
151
+ end
152
+
153
+ private def pack_string(value)
154
+ pack_string_header(value.bytesize)
155
+ pack_raw(value)
156
+ end
157
+
158
+ def pack_bytes_header(size)
159
+ if size < PLUS_2_TO_THE_8
160
+ write_byte(BYTES_8).write_byte(size)
161
+ elsif size < PLUS_2_TO_THE_16
162
+ write_byte(BYTES_16).write_short(size)
163
+ else
164
+ write_byte(BYTES_32).write_int(size)
165
+ end
166
+ end
167
+
168
+ def pack_string_header(size)
169
+ if size < 0x10
170
+ write_byte(TINY_STRING | size)
171
+ elsif size < PLUS_2_TO_THE_8
172
+ write_byte(STRING_8).write_byte(size)
173
+ elsif size < PLUS_2_TO_THE_16
174
+ write_byte(STRING_16).write_short(size)
175
+ else
176
+ write_byte(STRING_32).write_int(size)
177
+ end
178
+ end
179
+
180
+ def pack_list_header(size)
181
+ if size < 0x10
182
+ write_byte(TINY_LIST | size)
183
+ elsif size < PLUS_2_TO_THE_8
184
+ write_byte(LIST_8).write_byte(size)
185
+ elsif size < PLUS_2_TO_THE_16
186
+ write_byte(LIST_16).write_short(size)
187
+ else
188
+ write_byte(LIST_32).write_int(size)
189
+ end
190
+ end
191
+
192
+ def pack_map_header(size)
193
+ if size < 0x10
194
+ write_byte(TINY_MAP | size)
195
+ elsif size < PLUS_2_TO_THE_8
196
+ write_byte(MAP_8).write_byte(size)
197
+ elsif size < PLUS_2_TO_THE_16
198
+ write_byte(MAP_16).write_short(size)
199
+ else
200
+ write_byte(MAP_32).write_int(size)
201
+ end
202
+ end
203
+
204
+ def pack_struct_header(size, signature)
205
+ if size < 0x10
206
+ write_byte(TINY_STRUCT | size).write_byte(signature)
207
+ elsif size size < PLUS_2_TO_THE_8
208
+ write_byte(STRUCT_8).write_byte(size).write_byte(signature)
209
+ elsif size < PLUS_2_TO_THE_16
210
+ write_byte(STRUCT_16).write_short(size).write_byte(signature)
211
+ else
212
+ raise Overflow, "Structures cannot have more than #{PLUS_2_TO_THE_16 - 1} fields"
213
+ end
214
+ end
215
+ end
216
+
217
+ module Unpacker
218
+ include Common
219
+
220
+ def unpack_struct_header
221
+ marker_byte = read_byte
222
+ marker_high_nibble = marker_byte & 0xF0
223
+ marker_low_nibble = marker_byte & 0x0F
224
+
225
+ return marker_low_nibble if marker_high_nibble == TINY_STRUCT
226
+
227
+ case marker_byte
228
+ when STRUCT_8
229
+ unpack_u_int8
230
+ when STRUCT_16
231
+ unpack_u_int16
232
+ else
233
+ raise Unexpected, "Expected a struct, but got: #{marker_byte.to_s(16)}"
234
+ end
235
+ end
236
+
237
+ def unpack_struct_signature
238
+ read_byte
239
+ end
240
+
241
+ def unpack_list_header
242
+ marker_byte = read_byte
243
+ marker_high_nibble = marker_byte & 0xF0
244
+ marker_low_nibble = marker_byte & 0x0F
245
+
246
+ return marker_low_nibble if marker_high_nibble == TINY_LIST
247
+
248
+ case marker_byte
249
+ when LIST_8
250
+ unpack_uint8
251
+ when LIST_16
252
+ unpack_uint16
253
+ when LIST_32
254
+ unpack_uint32
255
+ else
256
+ raise Unexpected, "Expected a list, but got: #{(markerByte & 0xFF).to_s(16)}"
257
+ end
258
+ end
259
+
260
+ def unpack_map_header
261
+ marker_byte = read_byte
262
+ marker_high_nibble = marker_byte & 0xF0
263
+ marker_low_nibble = marker_byte & 0x0F
264
+
265
+ return marker_low_nibble if marker_high_nibble == TINY_MAP
266
+
267
+ case marker_byte
268
+ when MAP_8
269
+ unpack_u_int8
270
+ when MAP_16
271
+ unpack_u_int16
272
+ when MAP_32
273
+ unpack_u_int32
274
+ else
275
+ raise Unexpected, "Expected a map, but got: #{marker_byte.to_s(16)}"
276
+ end
277
+ end
278
+
279
+ def unpack_long(marker_byte)
280
+ return marker_byte if marker_byte >= MINUS_2_TO_THE_4
281
+ marker_byte &= 0xFF
282
+ case marker_byte
283
+ when INT_8
284
+ read_byte
285
+ when INT_16
286
+ read_short
287
+ when INT_32
288
+ read_int
289
+ when INT_64
290
+ read_long
291
+ else
292
+ raise Unexpected, "Expected an integer, but got: #{marker_byte.to_s(16)}"
293
+ end
294
+ end
295
+
296
+ def unpack_double
297
+ read_double
298
+ end
299
+
300
+ def unpack_bytes(size)
301
+ read_exactly(size)
302
+ end
303
+
304
+ def unpack_string(size)
305
+ read_exactly(size).force_encoding(Encoding::UTF_8)
306
+ end
307
+ end
308
+
309
+ class PackStreamException < IOError
310
+ end
311
+
312
+ class EndOfStream < PackStreamException
313
+ end
314
+
315
+ class Overflow < PackStreamException
316
+ end
317
+
318
+ class Unexpected < PackStreamException
319
+ end
320
+
321
+ class UnPackable < PackStreamException
322
+ end
323
+ end
324
+ end
325
+ end
326
+ end
@@ -0,0 +1,17 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Packstream
4
+ class PackType
5
+ NULL = :null
6
+ BOOLEAN = :boolean
7
+ INTEGER = :integer
8
+ FLOAT = :float
9
+ BYTES = :bytes
10
+ STRING = :string
11
+ LIST = :list
12
+ MAP = :map
13
+ STRUCT = :struct
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ class ReadOnlyBookmarkHolder
4
+ attr_reader :bookmark
5
+
6
+ def initialize(bookmark = InternalBookmark.empty)
7
+ @bookmark = bookmark
8
+ end
9
+
10
+ def bookmark=(_value) end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ class ResolvedBoltServerAddress < BoltServerAddress
4
+ MAX_HOST_ADDRESSES_IN_STRING_VALUE = 5
5
+
6
+ def initialize(host, port, *resolved_addresses_arr)
7
+ super(host: host, port: port)
8
+ if resolved_addresses_arr.empty?
9
+ raise ArgumentError,
10
+ 'The resolvedAddressesArr must not be empty, check your DomainNameResolver is compliant with the interface contract'
11
+ end
12
+ @resolved_addresses = resolved_addresses_arr.to_set.freeze
13
+ @string_value = create_string_representation
14
+ end
15
+
16
+ def unicast_stream
17
+ @resolved_addresses
18
+ .map { |address| BoltServerAddress.new(host: host, connection_host: address.ip_address, port: port) }
19
+ end
20
+
21
+ def to_s
22
+ @string_value
23
+ end
24
+
25
+ def attributes
26
+ super + [@resolved_addresses]
27
+ end
28
+
29
+ def create_string_representation
30
+ host_addresses = @resolved_addresses.take(MAX_HOST_ADDRESSES_IN_STRING_VALUE).map(&:ip_address).join(',')
31
+ "#{host}(#{host_addresses}#{',...' if @resolved_addresses.size > MAX_HOST_ADDRESSES_IN_STRING_VALUE}):#{port}"
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j::Driver
4
+ module Internal
5
+ module Retry
6
+ class ExponentialBackoffRetryLogic
7
+ DEFAULT_MAX_RETRY_TIME = 30.seconds
8
+ INITIAL_RETRY_DELAY = 1.second
9
+ RETRY_DELAY_MULTIPLIER = 2.0
10
+ RETRY_DELAY_JITTER_FACTOR = 0.2
11
+
12
+ def initialize(max_retry_time, event_executor_group, logger = nil)
13
+ @max_retry_time = max_retry_time || DEFAULT_MAX_RETRY_TIME
14
+ @event_executor_group = event_executor_group
15
+ @log = logger
16
+ end
17
+
18
+ def retry
19
+ errors = nil
20
+ start_time = nil
21
+ next_delay = INITIAL_RETRY_DELAY
22
+ begin
23
+ yield
24
+ rescue StandardError => error
25
+ if can_retry_on?(error)
26
+ curr_time = Util::Clock::System.time
27
+ start_time ||= curr_time
28
+ elapsed_time = curr_time - start_time
29
+ if elapsed_time < @max_retry_time
30
+ delay_with_jitter = compute_delay_with_jitter(next_delay)
31
+ @log&.warn { "Transaction failed and will be retried in #{delay_with_jitter}ms\n#{error}" }
32
+ sleep(delay_with_jitter)
33
+ next_delay *= RETRY_DELAY_MULTIPLIER
34
+ errors = record_error(error, errors)
35
+ retry
36
+ end
37
+ end
38
+ add_suppressed(error, errors)
39
+ raise error
40
+ end
41
+ end
42
+
43
+ def retry_async(&work)
44
+ result_future = Concurrent::Promises.resolvable_future
45
+ execute_work_in_event_loop(result_future, &work)
46
+ result_future
47
+ end
48
+
49
+ protected
50
+
51
+ def can_retry_on?(error)
52
+ error.is_a?(Exceptions::SessionExpiredException) ||
53
+ error.is_a?(Exceptions::ServiceUnavailableException) ||
54
+ transient_error?(error)
55
+ end
56
+
57
+ private
58
+
59
+ def extract_possible_termination_cause(error)
60
+ # Having a dedicated "TerminatedException" inheriting from ClientException might be a good idea.
61
+ error.is_a? Exceptions::ClientException && error.cause || error
62
+ end
63
+
64
+ def execute_work_in_event_loop(result_future, &work)
65
+ # this is the very first time we execute given work
66
+ event_executor = @event_executor_group.next
67
+
68
+ event_executor.execute do
69
+ execute_work(result_future, -1, INITIAL_RETRY_DELAY, nil, &work)
70
+ end
71
+ end
72
+
73
+ def retry_work_in_event_loop(result_future, error, start_time, delay, errors, &work)
74
+ # work has failed before, we need to schedule retry with the given delay
75
+ event_executor = event_executor_group.next
76
+
77
+ delay_with_jitter = compute_delay_with_jitter(delay)
78
+ @log.warn("Async transaction failed and is scheduled to retry in " + delay_with_jitter + "s", error);
79
+
80
+ event_executor.schedule(->() { execute_work(result_future, start_time, delay * multiplier, errors, &work) },
81
+ DurationNormalizer.milliseconds(delay_with_jitter),
82
+ java.util.concurrent.TimeUnit::MILLISECONDS)
83
+ end
84
+
85
+ def execute_work(result_future, start_time, retry_delay, errors, &work)
86
+ begin
87
+ work_stage = work.call
88
+ rescue StandardError => error
89
+ # work failed in a sync way, attempt to schedule a retry
90
+ retry_on_error(result_future, start_time, retry_delay, error, errors, &work)
91
+ return
92
+ end
93
+
94
+ work_stage.on_resolution do |fulfilled, result, completion_error|
95
+ error = Futures.completion_exception_cause(completion_error)
96
+ if error
97
+ # work failed in async way, attempt to schedule a retry
98
+ retry_on_error(result_future, work, start_time, retry_delay, error, errors)
99
+ else
100
+ result_future.fulfill(result)
101
+ end
102
+ end
103
+ end
104
+
105
+ def retry_on_error(result_future, start_time, retry_delay, throwable, errors, &work)
106
+ error = extract_possible_termination_cause(throwable)
107
+ if can_retry_on?(error)
108
+ current_time = Util::Clock::System.time
109
+ start_time ||= current_time
110
+
111
+ elapsed_time = current_time - start_time
112
+ if elapsed_time < @max_retry_time
113
+ errors = record_error(error, errors)
114
+ retry_work_in_event_loop(result_future, error, start_time, retry_delay, errors, &work)
115
+ return
116
+ end
117
+ end
118
+
119
+ add_suppressed(throwable, errors)
120
+ result_future.reject(throwable)
121
+ end
122
+
123
+ def compute_delay_with_jitter(delay)
124
+ jitter = delay * RETRY_DELAY_JITTER_FACTOR
125
+ min = delay - jitter
126
+ max = delay + jitter
127
+ @rand ||= Random.new
128
+ @rand.rand(min..max)
129
+ end
130
+
131
+ def transient_error?(error)
132
+ # Retries should not happen when transaction was explicitly terminated by the user.
133
+ # Termination of transaction might result in two different error codes depending on where it was
134
+ # terminated. These are really client errors but classification on the server is not entirely correct and
135
+ # they are classified as transient.
136
+ error.is_a?(Exceptions::TransientException) &&
137
+ !%w[Neo.TransientError.Transaction.Terminated Neo.TransientError.Transaction.LockClientStopped]
138
+ .include?(error.code)
139
+ end
140
+
141
+ def record_error(error, errors)
142
+ (errors || []) << error
143
+ end
144
+
145
+ def add_suppressed(error, suppressed_errors)
146
+ suppressed_errors&.reject(&error.method(:equal?))&.each(&error.method(:add_suppressed)) if error.is_a? Exceptions::Neo4jException
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neo4j::Driver::Internal
4
+ module RevocationStrategy
5
+ # Don't do any OCSP revocation checks, regardless whether there are stapled revocation statuses or not.
6
+ NO_CHECKS = :no_checks
7
+
8
+ # Verify OCSP revocation checks when the revocation status is stapled to the certificate, continue if not.
9
+ VERIFY_IF_PRESENT = :verify_if_present
10
+
11
+ # Require stapled revocation status and verify OCSP revocation checks,
12
+ # fail if no revocation status is stapled to the certificate.
13
+ STRICT = :strict
14
+
15
+ def self.requires_revocation_checking?(revocation_strategy)
16
+ revocation_strategy == STRICT || revocation_strategy == VERIFY_IF_PRESENT
17
+ end
18
+ end
19
+ end