neo4j-ruby-driver 1.7.5 → 4.4.0.alpha.2

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 (339) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -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_ruby_driver.rb +5 -10
  33. data/{ffi → ruby}/neo4j/driver/access_mode.rb +2 -2
  34. data/ruby/neo4j/driver/auth_tokens.rb +34 -0
  35. data/ruby/neo4j/driver/bookmark.rb +21 -0
  36. data/ruby/neo4j/driver/config.rb +91 -0
  37. data/ruby/neo4j/driver/graph_database.rb +140 -0
  38. data/ruby/neo4j/driver/internal/async/connection/bolt_protocol_util.rb +51 -0
  39. data/ruby/neo4j/driver/internal/async/connection/bootstrap_factory.rb +22 -0
  40. data/ruby/neo4j/driver/internal/async/connection/channel_attributes.rb +31 -0
  41. data/ruby/neo4j/driver/internal/async/connection/channel_connected_listener.rb +32 -0
  42. data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +77 -0
  43. data/ruby/neo4j/driver/internal/async/connection/channel_pipeline_builder_impl.rb +22 -0
  44. data/ruby/neo4j/driver/internal/async/connection/direct_connection.rb +30 -0
  45. data/ruby/neo4j/driver/internal/async/connection/event_loop_group_factory.rb +83 -0
  46. data/ruby/neo4j/driver/internal/async/connection/handshake_completed_listener.rb +27 -0
  47. data/ruby/neo4j/driver/internal/async/connection/handshake_handler.rb +113 -0
  48. data/ruby/neo4j/driver/internal/async/connection/netty_channel_initializer.rb +57 -0
  49. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver.rb +26 -0
  50. data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver_group.rb +19 -0
  51. data/ruby/neo4j/driver/internal/async/connection/routing_connection.rb +36 -0
  52. data/ruby/neo4j/driver/internal/async/connection/stream.rb +12 -0
  53. data/ruby/neo4j/driver/internal/async/connection/stream_reader.rb +16 -0
  54. data/ruby/neo4j/driver/internal/async/connection_context.rb +10 -0
  55. data/ruby/neo4j/driver/internal/async/immutable_connection_context.rb +24 -0
  56. data/ruby/neo4j/driver/internal/async/inbound/byte_buf_input.rb +30 -0
  57. data/ruby/neo4j/driver/internal/async/inbound/channel_error_handler.rb +77 -0
  58. data/ruby/neo4j/driver/internal/async/inbound/chunk_decoder.rb +41 -0
  59. data/ruby/neo4j/driver/internal/async/inbound/connect_timeout_handler.rb +32 -0
  60. data/ruby/neo4j/driver/internal/async/inbound/connection_read_timeout_handler.rb +17 -0
  61. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +172 -0
  62. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_handler.rb +42 -0
  63. data/ruby/neo4j/driver/internal/async/inbound/message_decoder.rb +51 -0
  64. data/ruby/neo4j/driver/internal/async/internal_async_session.rb +98 -0
  65. data/ruby/neo4j/driver/internal/async/internal_async_transaction.rb +13 -0
  66. data/ruby/neo4j/driver/internal/async/leak_logging_network_session.rb +34 -0
  67. data/ruby/neo4j/driver/internal/async/network_connection.rb +196 -0
  68. data/ruby/neo4j/driver/internal/async/network_session.rb +152 -0
  69. data/ruby/neo4j/driver/internal/async/outbound/chunk_aware_byte_buf_output.rb +110 -0
  70. data/ruby/neo4j/driver/internal/async/outbound/outbound_message_handler.rb +39 -0
  71. data/ruby/neo4j/driver/internal/async/pool/channel.rb +63 -0
  72. data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +149 -0
  73. data/ruby/neo4j/driver/internal/async/pool/controller.rb +25 -0
  74. data/ruby/neo4j/driver/internal/async/pool/netty_channel_health_checker.rb +87 -0
  75. data/ruby/neo4j/driver/internal/async/pool/netty_channel_pool.rb +52 -0
  76. data/ruby/neo4j/driver/internal/async/pool/netty_channel_tracker.rb +137 -0
  77. data/ruby/neo4j/driver/internal/async/pool/network_connection_factory.rb +21 -0
  78. data/ruby/neo4j/driver/internal/async/pool/pool_settings.rb +34 -0
  79. data/ruby/neo4j/driver/internal/async/result_cursors_holder.rb +17 -0
  80. data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +214 -0
  81. data/ruby/neo4j/driver/internal/bookmark_holder.rb +9 -0
  82. data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +58 -0
  83. data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +14 -0
  84. data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +139 -0
  85. data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +13 -0
  86. data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +68 -0
  87. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +159 -0
  88. data/ruby/neo4j/driver/internal/cluster/loadbalancing/round_robin_array_index.rb +13 -0
  89. data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +34 -0
  90. data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +238 -0
  91. data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +43 -0
  92. data/ruby/neo4j/driver/internal/cluster/routing_context.rb +77 -0
  93. data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +64 -0
  94. data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +19 -0
  95. data/ruby/neo4j/driver/internal/cluster/routing_settings.rb +24 -0
  96. data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +116 -0
  97. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +140 -0
  98. data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +76 -0
  99. data/ruby/neo4j/driver/internal/connection_settings.rb +16 -0
  100. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +76 -0
  101. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +29 -0
  102. data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +59 -0
  103. data/ruby/neo4j/driver/internal/cursor/result_cursor_factory_impl.rb +29 -0
  104. data/ruby/neo4j/driver/internal/cursor/rx_result_cursor_impl.rb +110 -0
  105. data/ruby/neo4j/driver/internal/database_name.rb +12 -0
  106. data/ruby/neo4j/driver/internal/database_name_util.rb +37 -0
  107. data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +15 -0
  108. data/ruby/neo4j/driver/internal/default_domain_name_resolver.rb +11 -0
  109. data/ruby/neo4j/driver/internal/direct_connection_provider.rb +40 -0
  110. data/ruby/neo4j/driver/internal/driver_factory.rb +127 -0
  111. data/ruby/neo4j/driver/internal/handlers/begin_tx_response_handler.rb +20 -0
  112. data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +29 -0
  113. data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +25 -0
  114. data/ruby/neo4j/driver/internal/handlers/hello_response_handler.rb +65 -0
  115. data/ruby/neo4j/driver/internal/handlers/init_response_handler.rb +34 -0
  116. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +228 -0
  117. data/ruby/neo4j/driver/internal/handlers/no_op_response_handler.rb +16 -0
  118. data/ruby/neo4j/driver/internal/handlers/ping_response_handler.rb +29 -0
  119. data/ruby/neo4j/driver/internal/handlers/pull_handlers.rb +32 -0
  120. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +174 -0
  121. data/ruby/neo4j/driver/internal/handlers/pulln/basic_pull_response_handler.rb +288 -0
  122. data/ruby/neo4j/driver/internal/handlers/pulln/fetch_size_util.rb +20 -0
  123. data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +34 -0
  124. data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +19 -0
  125. data/ruby/neo4j/driver/internal/handlers/route_message_response_handler.rb +21 -0
  126. data/ruby/neo4j/driver/internal/handlers/routing_response_handler.rb +70 -0
  127. data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +37 -0
  128. data/ruby/neo4j/driver/internal/handlers/session_pull_response_completion_listener.rb +34 -0
  129. data/ruby/neo4j/driver/internal/handlers/transaction_pull_response_completion_listener.rb +20 -0
  130. data/ruby/neo4j/driver/internal/impersonation_util.rb +22 -0
  131. data/ruby/neo4j/driver/internal/internal_bookmark.rb +38 -0
  132. data/ruby/neo4j/driver/internal/internal_database_name.rb +11 -0
  133. data/ruby/neo4j/driver/internal/internal_driver.rb +78 -0
  134. data/ruby/neo4j/driver/internal/internal_entity.rb +22 -0
  135. data/ruby/neo4j/driver/internal/internal_node.rb +21 -0
  136. data/ruby/neo4j/driver/internal/internal_pair.rb +9 -0
  137. data/ruby/neo4j/driver/internal/internal_path.rb +35 -0
  138. data/ruby/neo4j/driver/internal/internal_point2_d.rb +9 -0
  139. data/ruby/neo4j/driver/internal/internal_point3_d.rb +6 -0
  140. data/{ffi → ruby}/neo4j/driver/internal/internal_record.rb +2 -1
  141. data/ruby/neo4j/driver/internal/internal_relationship.rb +26 -0
  142. data/ruby/neo4j/driver/internal/internal_result.rb +60 -0
  143. data/ruby/neo4j/driver/internal/internal_session.rb +81 -0
  144. data/ruby/neo4j/driver/internal/internal_transaction.rb +48 -0
  145. data/ruby/neo4j/driver/internal/logging/channel_activity_logger.rb +29 -0
  146. data/ruby/neo4j/driver/internal/logging/channel_error_logger.rb +17 -0
  147. data/ruby/neo4j/driver/internal/logging/prefixed_logger.rb +19 -0
  148. data/ruby/neo4j/driver/internal/logging/reformatted_logger.rb +17 -0
  149. data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +23 -0
  150. data/ruby/neo4j/driver/internal/messaging/bolt_protocol.rb +30 -0
  151. data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +46 -0
  152. data/ruby/neo4j/driver/internal/messaging/common/common_message_reader.rb +51 -0
  153. data/ruby/neo4j/driver/internal/messaging/common/common_value.rb +31 -0
  154. data/ruby/neo4j/driver/internal/messaging/common/common_value_packer.rb +101 -0
  155. data/ruby/neo4j/driver/internal/messaging/common/common_value_unpacker.rb +234 -0
  156. data/ruby/neo4j/driver/internal/messaging/encode/begin_message_encoder.rb +15 -0
  157. data/ruby/neo4j/driver/internal/messaging/encode/commit_message_encoder.rb +14 -0
  158. data/ruby/neo4j/driver/internal/messaging/encode/discard_all_message_encoder.rb +14 -0
  159. data/ruby/neo4j/driver/internal/messaging/encode/discard_message_encoder.rb +15 -0
  160. data/ruby/neo4j/driver/internal/messaging/encode/goodbye_message_encoder.rb +14 -0
  161. data/ruby/neo4j/driver/internal/messaging/encode/hello_message_encoder.rb +15 -0
  162. data/ruby/neo4j/driver/internal/messaging/encode/init_message_encoder.rb +16 -0
  163. data/ruby/neo4j/driver/internal/messaging/encode/pull_all_message_encoder.rb +14 -0
  164. data/ruby/neo4j/driver/internal/messaging/encode/pull_message_encoder.rb +15 -0
  165. data/ruby/neo4j/driver/internal/messaging/encode/reset_message_encoder.rb +14 -0
  166. data/ruby/neo4j/driver/internal/messaging/encode/rollback_message_encoder.rb +14 -0
  167. data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +18 -0
  168. data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +27 -0
  169. data/ruby/neo4j/driver/internal/messaging/encode/run_message_encoder.rb +16 -0
  170. data/ruby/neo4j/driver/internal/messaging/encode/run_with_metadata_message_encoder.rb +17 -0
  171. data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +22 -0
  172. data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +26 -0
  173. data/ruby/neo4j/driver/internal/messaging/request/commit_message.rb +20 -0
  174. data/ruby/neo4j/driver/internal/messaging/request/discard_all_message.rb +20 -0
  175. data/ruby/neo4j/driver/internal/messaging/request/discard_message.rb +23 -0
  176. data/ruby/neo4j/driver/internal/messaging/request/goodbye_message.rb +20 -0
  177. data/ruby/neo4j/driver/internal/messaging/request/hello_message.rb +31 -0
  178. data/ruby/neo4j/driver/internal/messaging/request/init_message.rb +19 -0
  179. data/ruby/neo4j/driver/internal/messaging/request/message_with_metadata.rb +10 -0
  180. data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +26 -0
  181. data/ruby/neo4j/driver/internal/messaging/request/pull_all_message.rb +23 -0
  182. data/ruby/neo4j/driver/internal/messaging/request/pull_message.rb +22 -0
  183. data/ruby/neo4j/driver/internal/messaging/request/reset_message.rb +32 -0
  184. data/ruby/neo4j/driver/internal/messaging/request/rollback_message.rb +20 -0
  185. data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +33 -0
  186. data/ruby/neo4j/driver/internal/messaging/request/run_message.rb +23 -0
  187. data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +47 -0
  188. data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +24 -0
  189. data/ruby/neo4j/driver/internal/messaging/response/failure_message.rb +40 -0
  190. data/ruby/neo4j/driver/internal/messaging/response/ignored_message.rb +29 -0
  191. data/ruby/neo4j/driver/internal/messaging/response/record_message.rb +33 -0
  192. data/ruby/neo4j/driver/internal/messaging/response/success_message.rb +34 -0
  193. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +79 -0
  194. data/ruby/neo4j/driver/internal/messaging/v3/message_format_v3.rb +17 -0
  195. data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +27 -0
  196. data/ruby/neo4j/driver/internal/messaging/v4/bolt_protocol_v4.rb +29 -0
  197. data/ruby/neo4j/driver/internal/messaging/v4/message_format_v4.rb +17 -0
  198. data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +28 -0
  199. data/ruby/neo4j/driver/internal/messaging/v41/bolt_protocol_v41.rb +25 -0
  200. data/ruby/neo4j/driver/internal/messaging/v42/bolt_protocol_v42.rb +13 -0
  201. data/ruby/neo4j/driver/internal/messaging/v43/bolt_protocol_v43.rb +19 -0
  202. data/ruby/neo4j/driver/internal/messaging/v43/message_format_v43.rb +18 -0
  203. data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +34 -0
  204. data/ruby/neo4j/driver/internal/messaging/v44/bolt_protocol_v44.rb +17 -0
  205. data/ruby/neo4j/driver/internal/messaging/v44/message_format_v44.rb +18 -0
  206. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +26 -0
  207. data/ruby/neo4j/driver/internal/metrics/connection_pool_metrics_listener.rb +34 -0
  208. data/ruby/neo4j/driver/internal/metrics/internal_abstract_metrics.rb +46 -0
  209. data/ruby/neo4j/driver/internal/metrics/internal_connection_pool_metrics.rb +105 -0
  210. data/ruby/neo4j/driver/internal/metrics/internal_metrics.rb +82 -0
  211. data/ruby/neo4j/driver/internal/metrics/internal_metrics_provider.rb +18 -0
  212. data/ruby/neo4j/driver/internal/metrics/listener_event.rb +17 -0
  213. data/ruby/neo4j/driver/internal/metrics/metrics_provider.rb +24 -0
  214. data/ruby/neo4j/driver/internal/metrics/time_recorder_listener_event.rb +15 -0
  215. data/ruby/neo4j/driver/internal/packstream/byte_array_incompatible_packer.rb +12 -0
  216. data/ruby/neo4j/driver/internal/packstream/pack_input.rb +47 -0
  217. data/ruby/neo4j/driver/internal/packstream/pack_output.rb +39 -0
  218. data/ruby/neo4j/driver/internal/packstream/pack_stream.rb +326 -0
  219. data/ruby/neo4j/driver/internal/packstream/pack_type.rb +17 -0
  220. data/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +151 -0
  221. data/ruby/neo4j/driver/internal/revocation_strategy.rb +19 -0
  222. data/ruby/neo4j/driver/internal/scheme.rb +32 -0
  223. data/ruby/neo4j/driver/internal/security/internal_auth_token.rb +15 -0
  224. data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +92 -0
  225. data/ruby/neo4j/driver/internal/security_setting.rb +73 -0
  226. data/ruby/neo4j/driver/internal/session_factory_impl.rb +32 -0
  227. data/ruby/neo4j/driver/internal/spi/connection.rb +19 -0
  228. data/ruby/neo4j/driver/internal/spi/connection_pool.rb +9 -0
  229. data/ruby/neo4j/driver/internal/spi/response_handler.rb +23 -0
  230. data/ruby/neo4j/driver/internal/summary/internal_database_info.rb +7 -0
  231. data/ruby/neo4j/driver/internal/summary/internal_input_position.rb +11 -0
  232. data/ruby/neo4j/driver/internal/summary/internal_notification.rb +16 -0
  233. data/ruby/neo4j/driver/internal/summary/internal_plan.rb +41 -0
  234. data/ruby/neo4j/driver/internal/summary/internal_profiled_plan.rb +32 -0
  235. data/ruby/neo4j/driver/internal/summary/internal_result_summary.rb +33 -0
  236. data/ruby/neo4j/driver/internal/summary/internal_server_info.rb +6 -0
  237. data/ruby/neo4j/driver/internal/summary/internal_summary_counters.rb +18 -0
  238. data/ruby/neo4j/driver/internal/svm/netty_substitutions.rb +196 -0
  239. data/ruby/neo4j/driver/internal/svm/z_lib_substitutions.rb +21 -0
  240. data/ruby/neo4j/driver/internal/util/certificate_tool.rb +65 -0
  241. data/ruby/neo4j/driver/internal/util/clock.rb +29 -0
  242. data/ruby/neo4j/driver/internal/util/error_util.rb +104 -0
  243. data/ruby/neo4j/driver/internal/util/extract.rb +123 -0
  244. data/ruby/neo4j/driver/internal/util/format.rb +39 -0
  245. data/ruby/neo4j/driver/internal/util/futures.rb +99 -0
  246. data/ruby/neo4j/driver/internal/util/iterables.rb +35 -0
  247. data/ruby/neo4j/driver/internal/util/lock_util.rb +23 -0
  248. data/ruby/neo4j/driver/internal/util/metadata_extractor.rb +109 -0
  249. data/ruby/neo4j/driver/internal/util/mutex.rb +9 -0
  250. data/ruby/neo4j/driver/internal/util/preconditions.rb +16 -0
  251. data/ruby/neo4j/driver/internal/util/server_version.rb +60 -0
  252. data/ruby/neo4j/driver/logging1.rb +51 -0
  253. data/ruby/neo4j/driver/net/server_address1.rb +9 -0
  254. data/ruby/neo4j/driver/query.rb +48 -0
  255. data/ruby/neo4j/driver/records.rb +13 -0
  256. data/ruby/neo4j/driver/session_config.rb +15 -0
  257. data/ruby/neo4j/driver/transaction_config.rb +46 -0
  258. data/ruby/neo4j/driver/values.rb +26 -0
  259. data/{lib → ruby}/neo4j/driver/version.rb +1 -1
  260. data/ruby/neo4j/driver.rb +30 -0
  261. metadata +267 -92
  262. data/ffi/bolt/address.rb +0 -11
  263. data/ffi/bolt/address_resolver.rb +0 -12
  264. data/ffi/bolt/address_set.rb +0 -9
  265. data/ffi/bolt/auth.rb +0 -10
  266. data/ffi/bolt/auto_releasable.rb +0 -22
  267. data/ffi/bolt/boolean.rb +0 -9
  268. data/ffi/bolt/bytes.rb +0 -10
  269. data/ffi/bolt/config.rb +0 -45
  270. data/ffi/bolt/connection.rb +0 -44
  271. data/ffi/bolt/connector.rb +0 -17
  272. data/ffi/bolt/dictionary.rb +0 -15
  273. data/ffi/bolt/error.rb +0 -74
  274. data/ffi/bolt/float.rb +0 -9
  275. data/ffi/bolt/integer.rb +0 -9
  276. data/ffi/bolt/library.rb +0 -12
  277. data/ffi/bolt/lifecycle.rb +0 -9
  278. data/ffi/bolt/list.rb +0 -10
  279. data/ffi/bolt/log.rb +0 -16
  280. data/ffi/bolt/socket_options.rb +0 -14
  281. data/ffi/bolt/status.rb +0 -25
  282. data/ffi/bolt/string.rb +0 -9
  283. data/ffi/bolt/structure.rb +0 -10
  284. data/ffi/bolt/value.rb +0 -35
  285. data/ffi/neo4j/driver/auth_tokens.rb +0 -18
  286. data/ffi/neo4j/driver/config.rb +0 -40
  287. data/ffi/neo4j/driver/graph_database.rb +0 -52
  288. data/ffi/neo4j/driver/internal/async/access_mode_connection.rb +0 -19
  289. data/ffi/neo4j/driver/internal/async/direct_connection.rb +0 -106
  290. data/ffi/neo4j/driver/internal/bolt_server_address.rb +0 -18
  291. data/ffi/neo4j/driver/internal/bookmarks_holder.rb +0 -30
  292. data/ffi/neo4j/driver/internal/direct_connection_provider.rb +0 -28
  293. data/ffi/neo4j/driver/internal/driver_factory.rb +0 -126
  294. data/ffi/neo4j/driver/internal/error_handling.rb +0 -112
  295. data/ffi/neo4j/driver/internal/explicit_transaction.rb +0 -146
  296. data/ffi/neo4j/driver/internal/handlers/pull_all_response_handler.rb +0 -104
  297. data/ffi/neo4j/driver/internal/handlers/response_handler.rb +0 -49
  298. data/ffi/neo4j/driver/internal/handlers/run_response_handler.rb +0 -32
  299. data/ffi/neo4j/driver/internal/handlers/session_pull_all_response_handler.rb +0 -32
  300. data/ffi/neo4j/driver/internal/handlers/transaction_pull_all_response_handler.rb +0 -23
  301. data/ffi/neo4j/driver/internal/internal_driver.rb +0 -45
  302. data/ffi/neo4j/driver/internal/internal_logger.rb +0 -32
  303. data/ffi/neo4j/driver/internal/internal_resolver.rb +0 -31
  304. data/ffi/neo4j/driver/internal/internal_statement_result.rb +0 -52
  305. data/ffi/neo4j/driver/internal/messaging/bolt_protocol.rb +0 -24
  306. data/ffi/neo4j/driver/internal/messaging/v1/bolt_protocol_v1.rb +0 -59
  307. data/ffi/neo4j/driver/internal/messaging/v2/bolt_protocol_v2.rb +0 -16
  308. data/ffi/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +0 -63
  309. data/ffi/neo4j/driver/internal/network_session.rb +0 -129
  310. data/ffi/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +0 -80
  311. data/ffi/neo4j/driver/internal/session_factory_impl.rb +0 -28
  312. data/ffi/neo4j/driver/internal/summary/internal_result_summary.rb +0 -67
  313. data/ffi/neo4j/driver/internal/summary/internal_server_info.rb +0 -19
  314. data/ffi/neo4j/driver/internal/summary/internal_summary_counters.rb +0 -23
  315. data/ffi/neo4j/driver/internal/util/metadata_extractor.rb +0 -15
  316. data/ffi/neo4j/driver/internal/value/base_time_value.rb +0 -22
  317. data/ffi/neo4j/driver/internal/value/date_value.rb +0 -25
  318. data/ffi/neo4j/driver/internal/value/duration_value.rb +0 -27
  319. data/ffi/neo4j/driver/internal/value/local_date_time_value.rb +0 -24
  320. data/ffi/neo4j/driver/internal/value/local_time_value.rb +0 -19
  321. data/ffi/neo4j/driver/internal/value/node_value.rb +0 -18
  322. data/ffi/neo4j/driver/internal/value/offset_time_value.rb +0 -25
  323. data/ffi/neo4j/driver/internal/value/path_value.rb +0 -41
  324. data/ffi/neo4j/driver/internal/value/point2_d_value.rb +0 -24
  325. data/ffi/neo4j/driver/internal/value/point3_d_value.rb +0 -24
  326. data/ffi/neo4j/driver/internal/value/relationship_value.rb +0 -18
  327. data/ffi/neo4j/driver/internal/value/structure_value.rb +0 -42
  328. data/ffi/neo4j/driver/internal/value/time_with_zone_id_value.rb +0 -25
  329. data/ffi/neo4j/driver/internal/value/time_with_zone_offset_value.rb +0 -28
  330. data/ffi/neo4j/driver/internal/value/unbound_relationship_value.rb +0 -18
  331. data/ffi/neo4j/driver/internal/value/value_adapter.rb +0 -101
  332. data/ffi/neo4j/driver/net/server_address.rb +0 -13
  333. data/ffi/neo4j/driver/statement.rb +0 -15
  334. data/ffi/neo4j/driver/types/entity.rb +0 -21
  335. data/ffi/neo4j/driver/types/node.rb +0 -16
  336. data/ffi/neo4j/driver/types/path.rb +0 -35
  337. data/ffi/neo4j/driver/types/relationship.rb +0 -19
  338. data/ffi/neo4j/driver.rb +0 -61
  339. data/lib/neo4j/driver/internal/ruby_signature.rb +0 -18
@@ -0,0 +1,137 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ module Pool
5
+ class NettyChannelTracker
6
+ attr_reader :lock, :read, :write, :address_to_in_use_channel_count, :address_to_idle_channel_count, :log,
7
+ :metrics_listener, :close_listener, :all_channels
8
+
9
+ def initialize(metrics_listener, logger, options = {},event_executor = nil, channels = nil)
10
+ @metrics_listener = metrics_listener
11
+ @log = logger
12
+ @all_channels = options[:channels] ? channels : Java::IoNettyChannelGroup::DefaultChannelGroup.new("all-connections", options[:event_executor])
13
+ @lock = java.util.concurrent.locks.ReentrantReadWriteLock.new
14
+ @read = lock.read_lock
15
+ @write = lock.write_lock
16
+ @close_listener = -> (future) { channel_closed(future.channel) }
17
+ end
18
+
19
+ def channel_released(channel)
20
+ do_in_write_lock do
21
+ decrement_in_use(channel)
22
+ increment_idle(channel)
23
+ channel.close_future.add_listener(close_listener)
24
+ end
25
+
26
+ log.debug("Channel [0x#{channel.id}] acquired from the pool. Local address: #{channel.local_address}, remote address: #{channel.remote_address}")
27
+ end
28
+
29
+ def channel_created(channel, creating_event = nil)
30
+ if creating_event.nil?
31
+ raise Neo4j::Driver::Exceptions::IllegalStateException.new('Untraceable channel created.')
32
+ else
33
+ # when it is created, we count it as idle as it has not been acquired out of the pool
34
+ do_in_write_lock(->() { increment_idle(channel) })
35
+
36
+ metrics_listener.after_created(Connection::ChannelAttributes.pool_id(channel), creating_event)
37
+ all_channels.add(channel)
38
+ log.debug( "Channel [0x#{channel.id}] created. Local address: #{channel.local_address}, remote address: #{channel.remote_address}")
39
+ end
40
+ end
41
+
42
+ def channel_creating(pool_id)
43
+ creating_event = metrics_listener.create_listener_event
44
+ metrics_listener.before_creating(pool_id, creating_event)
45
+ creating_event
46
+ end
47
+
48
+ def channel_failed_to_create(pool_id)
49
+ metrics_listener.after_failed_to_create(pool_id)
50
+ end
51
+
52
+ def channel_closed(channel)
53
+ do_in_write_lock(-> () { decrement_idle(channel) })
54
+ metrics_listener.after_closed(Connection::ChannelAttributes.pool_id(channel))
55
+ end
56
+
57
+ def in_use_channel_count(address)
58
+ retrieve_in_read_lock(-> () { address_to_in_use_channel_count.get_or_default(address, 0) })
59
+ end
60
+
61
+ def idle_channel_count(address)
62
+ retrieve_in_read_lock(-> () { address_to_idle_channel_count.get_or_default(address, 0) })
63
+ end
64
+
65
+ def prepare_to_close_channels
66
+ all_channels.each do |channel|
67
+ protocol = Messaging::BoltProtocol.for_channel(channel)
68
+ begin
69
+ protocol.prepare_to_close_channel(channel)
70
+ rescue Exception => e
71
+ # only logging it
72
+ log.debug( "Failed to prepare to close Channel #{channel} due to error #{e.get_message}. It is safe to ignore this error as the channel will be closed despite if it is successfully prepared to close or not.")
73
+ end
74
+ end
75
+ end
76
+
77
+
78
+ private
79
+
80
+ def increment_in_use(channel)
81
+ increment(channel, address_to_in_use_channel_count)
82
+ end
83
+
84
+ def decrement_in_use(channel)
85
+ address = Connection::ChannelAttributes.server_address(channel)
86
+
87
+ unless address_to_in_use_channel_count.contains_key(address)
88
+ raise Neo4j::Driver::Exceptions::IllegalStateException.new("No count exists for address '#{address}' in the 'in use' count")
89
+ end
90
+
91
+ count = address_to_in_use_channel_count.get(address)
92
+ address_to_in_use_channel_count.put(address, count - 1)
93
+ end
94
+
95
+ def increment_idle(channel)
96
+ increment(channel, address_to_idle_channel_count)
97
+ end
98
+
99
+ def decrement_idle(channel)
100
+ address = Connection::ChannelAttributes.server_address(channel)
101
+
102
+ unless address_to_idle_channel_count.contains_key(address)
103
+ raise Neo4j::Driver::Exceptions::IllegalStateException.new("No count exists for address '#{address}' in the 'idle' count")
104
+ end
105
+
106
+ count = address_to_idle_channel_count.get(address)
107
+ address_to_idle_channel_count.put(address, count - 1)
108
+ end
109
+
110
+ def increment(channel, count_map)
111
+ address = Connection::ChannelAttributes.server_address(channel)
112
+ count = count_map.compute_if_absent(address, -> (k) { 0 })
113
+ count_map.put(address, count + 1)
114
+ end
115
+
116
+ def do_in_write_lock(work)
117
+ begin
118
+ write.lock
119
+ work.run
120
+ ensure
121
+ write.unlock
122
+ end
123
+ end
124
+
125
+ def retrieve_in_read_lock(work)
126
+ begin
127
+ read.lock
128
+ work.get
129
+ ensure
130
+ read.unlock
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,21 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ module Pool
5
+ class NetworkConnectionFactory
6
+ attr_reader :clock, :metrics_listener, :logger
7
+
8
+ def initialize(clock, metrics_listener, logger)
9
+ @clock = clock
10
+ @metrics_listener = metrics_listener
11
+ @logger = logger
12
+ end
13
+
14
+ def create_connection(channel, pool)
15
+ NetworkConnection.new(channel, pool, clock, metrics_listener, @logger)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ module Pool
5
+ class PoolSettings
6
+ attr_reader :max_connection_pool_size, :connection_acquisition_timeout, :max_connection_lifetime,
7
+ :idle_time_before_connection_test
8
+
9
+ NOT_CONFIGURED = nil
10
+ DEFAULT_MAX_CONNECTION_POOL_SIZE = 100
11
+ DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST = NOT_CONFIGURED
12
+ DEFAULT_MAX_CONNECTION_LIFETIME = 1.hour
13
+ DEFAULT_CONNECTION_ACQUISITION_TIMEOUT = 60.seconds
14
+
15
+ def initialize(max_connection_pool_size, connection_acquisition_timeout, max_connection_lifetime,
16
+ idle_time_before_connection_test)
17
+ @max_connection_pool_size = max_connection_pool_size
18
+ @connection_acquisition_timeout = connection_acquisition_timeout
19
+ @max_connection_lifetime = max_connection_lifetime
20
+ @idle_time_before_connection_test = idle_time_before_connection_test
21
+ end
22
+
23
+ def idle_time_before_connection_test_enabled?
24
+ idle_time_before_connection_test&.send(:>=, 0)
25
+ end
26
+
27
+ def max_connection_lifetime_enabled?
28
+ max_connection_lifetime&.send(:>, 0)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ class ResultCursorsHolder < Array
5
+ def retrieve_not_consumed_error
6
+ retrieve_all_failures.find { |failure| failure }
7
+ end
8
+
9
+ private
10
+
11
+ def retrieve_all_failures
12
+ map(&:discard_all_failure_async)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,214 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Async
4
+ class UnmanagedTransaction
5
+ class State
6
+ # The transaction is running with no explicit success or failure marked
7
+ ACTIVE = 'active'
8
+
9
+ # This transaction has been terminated either because of explicit {@link Session#reset()} or because of a fatal connection error.
10
+ TERMINATED = 'terminated'
11
+
12
+ # This transaction has successfully committed
13
+ COMMITTED = 'committed'
14
+
15
+ # This transaction has been rolled back
16
+ ROLLED_BACK = 'rolled_back'
17
+ end
18
+
19
+ CANT_COMMIT_COMMITTED_MSG = "Can't commit, transaction has been committed"
20
+ CANT_ROLLBACK_COMMITTED_MSG = "Can't rollback, transaction has been committed"
21
+ CANT_COMMIT_ROLLED_BACK_MSG = "Can't commit, transaction has been rolled back"
22
+ CANT_ROLLBACK_ROLLED_BACK_MSG = "Can't rollback, transaction has been rolled back"
23
+ CANT_COMMIT_ROLLING_BACK_MSG = "Can't commit, transaction has been requested to be rolled back"
24
+ CANT_ROLLBACK_COMMITTING_MSG = "Can't rollback, transaction has been requested to be committed"
25
+ OPEN_STATES = [State::ACTIVE, State::TERMINATED]
26
+ attr :connection
27
+
28
+ def initialize(connection, bookmark_holder, fetch_size, result_cursors = ResultCursorsHolder.new)
29
+ @connection = connection
30
+ @protocol = connection.protocol
31
+ @bookmark_holder = bookmark_holder
32
+ @result_cursors = result_cursors
33
+ @fetch_size = fetch_size
34
+ @lock = Util::Mutex.new
35
+ @state = State::ACTIVE
36
+ end
37
+
38
+ def begin_async(initial_bookmark, config)
39
+ @protocol.begin_transaction(@connection, initial_bookmark, config)
40
+ self
41
+ rescue Neo4j::Driver::Exceptions::AuthorizationExpiredException
42
+ @connection.terminate_and_release(Neo4j::Driver::Exceptions::AuthorizationExpiredException::DESCRIPTION)
43
+ raise
44
+ rescue Neo4j::Driver::Exceptions::ConnectionReadTimeoutException => begin_error
45
+ @connection.terminate_and_release(begin_error.message)
46
+ raise
47
+ rescue
48
+ @connection.release
49
+ raise
50
+ end
51
+
52
+ def close_async(commit = false, complete_with_null_if_not_open = true)
53
+ @lock.synchronize do
54
+ if complete_with_null_if_not_open && !open?
55
+ nil
56
+ elsif @state == State::COMMITTED
57
+ raise Neo4j::Driver::Exceptions::ClientException, commit ? CANT_COMMIT_COMMITTED_MSG : CANT_ROLLBACK_COMMITTED_MSG
58
+ elsif @state == State::ROLLED_BACK
59
+ raise Neo4j::Driver::Exceptions::ClientException, commit ? CANT_COMMIT_ROLLED_BACK_MSG : CANT_ROLLBACK_ROLLED_BACK_MSG
60
+ else
61
+ if commit
62
+ if @rollback_pending
63
+ raise Neo4j::Driver::Exceptions::ClientException, CANT_COMMIT_ROLLING_BACK_MSG
64
+ elsif @commit_pending
65
+ @commit_pending
66
+ else
67
+ @commit_pending = true
68
+ nil
69
+ end
70
+ else
71
+ if @commit_pending
72
+ raise Neo4j::Driver::Exceptions::ClientException, CANT_ROLLBACK_COMMITTING_MSG
73
+ elsif @rollback_pending
74
+ @rollback_pending
75
+ else
76
+ @rollback_pending = true
77
+ nil
78
+ end
79
+ end
80
+ end
81
+ end ||
82
+ begin
83
+ if commit
84
+ target_future = @commit_pending
85
+ target_action = lambda { |throwable|
86
+ do_commit_async(throwable)
87
+ handle_commit_or_rollback(throwable)
88
+ }
89
+ else
90
+ target_future = @rollback_pending
91
+ target_action = lambda { |throwable|
92
+ do_rollback_async
93
+ handle_commit_or_rollback(throwable)
94
+ }
95
+ end
96
+
97
+ @result_cursors.retrieve_not_consumed_error.then(&target_action)
98
+ handle_transaction_completion(commit, nil)
99
+ target_future
100
+ rescue => throwable
101
+ handle_transaction_completion(commit, throwable)
102
+ end
103
+ end
104
+
105
+ def commit_async
106
+ close_async(true, false)
107
+ end
108
+
109
+ def rollback_async
110
+ close_async(false, false)
111
+ end
112
+
113
+ def run_async(query)
114
+ ensure_can_run_queries
115
+ cursor = @protocol.run_in_unmanaged_transaction(@connection, query, self, @fetch_size).async_result
116
+ @result_cursors << cursor
117
+ cursor.map_successful_run_completion_async
118
+ end
119
+
120
+ def run_rx(query)
121
+ ensure_can_run_queries
122
+ cursor_stage = @protocol.run_in_unmanaged_transaction(@connection, query, self, @fetch_size).rx_result
123
+ @result_cursors << cursor_stage
124
+ cursor_stage
125
+ end
126
+
127
+ def open?
128
+ OPEN_STATES.include?(@lock.synchronize { @state })
129
+ end
130
+
131
+ def mark_terminated(cause)
132
+ @lock.synchronize do
133
+ if @state == State::TERMINATED
134
+ add_suppressed_when_not_captured(@cause_of_termination, cause) if @cause_of_termination
135
+ else
136
+ @state = State::TERMINATED
137
+ @cause_of_termination = cause
138
+ end
139
+ end
140
+ end
141
+
142
+ def ensure_can_run_queries
143
+ @lock.synchronize do
144
+ case @state
145
+ when State::COMMITTED
146
+ raise Neo4j::Driver::Exceptions::ClientException, 'Cannot run more queries in this transaction, it has been committed'
147
+ when State::ROLLED_BACK
148
+ raise Neo4j::Driver::Exceptions::ClientException, 'Cannot run more queries in this transaction, it has been rolled back'
149
+ when State::TERMINATED
150
+ # TODO clunky positional arguments of Neo4jException#initialize, move to named parameters
151
+ raise Neo4j::Driver::Exceptions::ClientException, 'Cannot run more queries in this transaction, it has either experienced an fatal error or was explicitly terminated'#, # TODO should be able to pass @cause_of_termination
152
+ end
153
+ end
154
+ end
155
+
156
+ private
157
+
158
+ def add_suppressed_when_not_captured(current_cause, new_cause)
159
+ if current_cause != new_cause
160
+ none_match = current_cause.get_suppressed.none? { |suppressed| suppressed == new_cause }
161
+
162
+ if none_match
163
+ current_cause.add_suppressed(new_cause)
164
+ end
165
+ end
166
+ end
167
+
168
+ def do_commit_async(cursor_failure)
169
+ exception = @lock.synchronize do
170
+ if @state == State::TERMINATED
171
+ Neo4j::Driver::Exceptions::ClientException.new(
172
+ "Transaction can't be committed. It has been rolled back either because of an error or explicit termination",
173
+ cursor_failure != @cause_of_termination ? @cause_of_termination : nil)
174
+ end
175
+ end
176
+
177
+ if exception
178
+ Util::Futures.failed_future(exception)
179
+ else
180
+ @protocol.commit_transaction(@connection, @bookmark_holder)
181
+ end
182
+ end
183
+
184
+ def do_rollback_async
185
+ if @lock.synchronize { @state } == State::TERMINATED
186
+ Util::Futures.completed_with_null
187
+ else
188
+ @protocol.rollback_transaction(@connection)
189
+ end
190
+ end
191
+
192
+ def handle_commit_or_rollback(cursor_failure)
193
+ lambda { |_fulfilled, _value, commit_or_rollback_error|
194
+ combined_error = Util::Futures.combined_error(cursor_failure, commit_or_rollback_error)
195
+ raise combined_error if combined_error
196
+ }
197
+ end
198
+
199
+ def handle_transaction_completion(commit_attempt, throwable)
200
+ @lock.synchronize { @state = commit_attempt && throwable.nil? ? State::COMMITTED : State::ROLLED_BACK }
201
+
202
+ case throwable
203
+ when Neo4j::Driver::Exceptions::AuthorizationExpiredException
204
+ @connection.terminate_and_release(Neo4j::Driver::Exceptions::AuthorizationExpiredException::DESCRIPTION)
205
+ when Neo4j::Driver::Exceptions::ConnectionReadTimeoutException
206
+ @connection.terminate_and_release(throwable.message)
207
+ else
208
+ @connection.release # release in background
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,9 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ class BookmarkHolder
4
+ NO_OP = Class.new(DefaultBookmarkHolder) do
5
+ def bookmark=(_value) end
6
+ end.new
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,58 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cluster
4
+ class ClusterComposition < Struct.new(:expiration_timestamp, :readers, :writers, :routers, :database_name)
5
+ private
6
+
7
+ MAX_LONG = 2 ^ 63 - 1
8
+ MAX_TTL = MAX_LONG / 1000
9
+
10
+ public
11
+
12
+ def initialize(expiration_timestamp:, database_name:, readers: [], writers: [], routers: [])
13
+ super(expiration_timestamp, readers, writers, routers, database_name)
14
+ end
15
+
16
+ def has_writers?
17
+ @writers.present?
18
+ end
19
+
20
+ def has_routers_and_readers?
21
+ @routers.present? && @readers.present?
22
+ end
23
+
24
+ def self.parse(record, now)
25
+ return if record.nil?
26
+ new(expiration_timestamp: expiration_timestamp(now, record), database_name: record['db'],
27
+ **record['servers'].to_h { |value| [servers(value['role']), BoltServerAddress.new(value['addresses'])] })
28
+ end
29
+
30
+ private
31
+
32
+ def self.expiration_timestamp(now, record)
33
+ ttl = record['ttl']
34
+ expiration_timestamp = now + ttl * 1000
35
+
36
+ if ttl < 0 || ttl >= MAX_TTL || expiration_timestamp < 0
37
+ expiration_timestamp = MAX_LONG
38
+ end
39
+
40
+ expiration_timestamp
41
+ end
42
+
43
+ def servers(role)
44
+ case role
45
+ when 'READ'
46
+ :readers
47
+ when 'WRITE'
48
+ :writers
49
+ when 'ROUTE'
50
+ :routers
51
+ else
52
+ raise ArgumentError, "invalid server role: #{role}"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,14 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cluster
4
+ class ClusterCompositionLookupResult
5
+ attr_reader :composition, :resolved_initial_routers
6
+
7
+ def initialize(composition, resolved_initial_routers = nil)
8
+ @composition = composition
9
+ @resolved_initial_routers = resolved_initial_routers
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,139 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cluster
4
+ class ClusterRoutingTable
5
+ MIN_ROUTERS = 1
6
+
7
+ attr_reader :database_name
8
+
9
+ def initialize(of_database, clock, routing_addresses)
10
+ @database_name = of_database
11
+ @clock = clock
12
+ @expiration_timestamp = clock.millis - 1
13
+ @routers = routing_addresses.freeze
14
+ @table_lock = java.util.concurrent.locks.ReentrantReadWriteLock.new
15
+ @prefer_initial_router = true
16
+ @disused = {}
17
+ @readers = []
18
+ @writers = []
19
+ end
20
+
21
+ def stale_for?(mode)
22
+ Util::LockUtil.execute_with_lock(@table_lock.read_lock) do
23
+ @expiration_timestamp < @clock.millis ||
24
+ routers.size < MIN_ROUTERS ||
25
+ (mode == AccessMode::READ && @readers.size == 0) ||
26
+ (mode == AccessMode::WRITE && @writers.size == 0)
27
+ end
28
+ end
29
+
30
+ def has_been_stale_for?(extra_time)
31
+ total_time = Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @expiration_timestamp }) + extra_time
32
+
33
+ total_time = java.lang.Long::MAX_VALUE if total_time < 0
34
+
35
+ total_time < @clock.millis
36
+ end
37
+
38
+ def update(cluster)
39
+ Util::LockUtil.execute_with_lock(@table_lock.write_lock) do
40
+ @expiration_timestamp = cluster.expiration_timestamp
41
+ @readers = new_with_reused_addresses(@readers, @disused, cluster.readers)
42
+ @writers = new_with_reused_addresses(@writers, @disused, cluster.writers)
43
+ @routers = new_with_reused_addresses(@routers, @disused, cluster.routers)
44
+ @disused.clear
45
+ @prefer_initial_router = !cluster.has_writers?
46
+ end
47
+ end
48
+
49
+ def forget(address)
50
+ Util::LockUtil.execute_with_lock(@table_lock.write_lock) do
51
+ @routers = new_without_address_if_present(@routers, address)
52
+ @readers = new_without_address_if_present(@readers, address)
53
+ @writers = new_without_address_if_present(@writers, address)
54
+ @disused << address
55
+ end
56
+ end
57
+
58
+ def readers
59
+ Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @readers })
60
+ end
61
+
62
+ def writers
63
+ Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @writers })
64
+ end
65
+
66
+ def routers
67
+ Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @routers })
68
+ end
69
+
70
+ def servers
71
+ Util::LockUtil.execute_with_lock(@table_lock.write_lock) do
72
+ servers = []
73
+ servers << (@readers)
74
+ servers << (@writers)
75
+ servers << (@routers)
76
+ servers << (@disused)
77
+ end
78
+ end
79
+
80
+ def forget_writer(to_remove)
81
+ Util::LockUtil.execute_with_lock(@table_lock.write_lock) do
82
+ @writers = new_without_address_if_present(@writers, to_remove)
83
+ @disused << to_remove
84
+ end
85
+ end
86
+
87
+ def replace_router_if_present(old_router, new_router)
88
+ Util::LockUtil.execute_with_lock(@table_lock.write_lock, -> () { @routers = new_with_address_replaced_if_present(@routers, old_router, new_router) } )
89
+ end
90
+
91
+ def prefer_initial_router
92
+ Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @prefer_initial_router })
93
+ end
94
+
95
+ def expiration_timestamp
96
+ Util::LockUtil.execute_with_lock(@table_lock.read_lock, -> () { @expiration_timestamp })
97
+ end
98
+
99
+ def to_s
100
+ Util::LockUtil.execute_with_lock(@table_lock.read_lock) do
101
+ "Ttl #{@expiration_timestamp}, currentTime #{@clock.millis}, routers #{@routers}, writers #{@writers}, readers #{@readers}, database '#{database_name.description}'"
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def new_without_address_if_present(addresses, address_to_skip)
108
+ new_list = []
109
+
110
+ addresses.each do |address|
111
+ new_list << address unless address.eql?(address_to_skip)
112
+ end
113
+
114
+ new_list.freeze
115
+ end
116
+
117
+ def new_with_address_replaced_if_present(addresses, old_address, new_address)
118
+ new_list = []
119
+
120
+ addresses.each { |address| new_list << address.eql?(old_address) ? new_address : address }
121
+
122
+ new_list.freeze
123
+ end
124
+
125
+ def new_with_reused_addresses(current_addresses, disused_addresses, new_addresses)
126
+ new_list = java.util.stream.Stream.concat(current_addresses.stream, disused_addresses.stream)
127
+ .filter(-> (address) { new_addresses.remove(to_bolt_server_address(address)) })
128
+ .collect(java.util.stream.Collectors.to_collection(-> () { Array.new(new_addresses.size) }))
129
+ new_list << new_addresses
130
+ new_list.freeze
131
+ end
132
+
133
+ def to_bolt_server_address(address)
134
+ BoltServerAddress.class.eql?(address.class) ? address : BoltServerAddress.new(address.host, address.port)
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,13 @@
1
+ module Neo4j::Driver
2
+ module Internal
3
+ module Cluster
4
+ class IdentityResolver
5
+ IDENTITY_RESOLVER = new
6
+
7
+ def resolve(initial_router)
8
+ java.util.Collections.singleton(initial_router)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end