couchbase 3.8.1 → 3.9.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 (475) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/CMakeLists.txt +16 -1
  4. data/ext/cache/cpm/{CPM_0.42.0.cmake → CPM_0.43.1.cmake} +18 -2
  5. data/ext/cache/extconf_include.rb +6 -6
  6. data/ext/cache/mozilla-ca-bundle.crt +214 -155
  7. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  8. data/ext/couchbase/CMakeLists.txt +130 -21
  9. data/ext/couchbase/cmake/APKBUILD.in +25 -4
  10. data/ext/couchbase/cmake/Bundler.cmake +143 -34
  11. data/ext/couchbase/cmake/CPM.cmake +126 -12
  12. data/ext/couchbase/cmake/Cache.cmake +7 -1
  13. data/ext/couchbase/cmake/CompilerOptions.cmake +1 -1
  14. data/ext/couchbase/cmake/CompilerWarnings.cmake +17 -6
  15. data/ext/couchbase/cmake/GrpcProtobuf.cmake +481 -0
  16. data/ext/couchbase/cmake/OpenSSL.cmake +10 -3
  17. data/ext/couchbase/cmake/Packaging.cmake +519 -65
  18. data/ext/couchbase/cmake/Protostellar.cmake +250 -0
  19. data/ext/couchbase/cmake/Sanitizers.cmake +61 -50
  20. data/ext/couchbase/cmake/StaticAnalyzers.cmake +16 -5
  21. data/ext/couchbase/cmake/TestFramework.cmake +283 -0
  22. data/ext/couchbase/cmake/TestFrameworkAddTests.cmake +51 -0
  23. data/ext/couchbase/cmake/Testing.cmake +27 -9
  24. data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +141 -8
  25. data/ext/couchbase/cmake/VersionInfo.cmake +50 -0
  26. data/ext/couchbase/cmake/build_config.hxx.in +2 -1
  27. data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +101 -23
  28. data/ext/couchbase/cmake/couchbase_cxx_client_static-config.cmake.in +7 -0
  29. data/ext/couchbase/cmake/couchbase_cxx_client_static.pc.in +2 -0
  30. data/ext/couchbase/cmake/gRPC_Generate.cmake +58 -0
  31. data/ext/couchbase/cmake/protobuf_Generate.cmake +69 -0
  32. data/ext/couchbase/cmake/require-git-checkout.cmake +25 -0
  33. data/ext/couchbase/cmake/tarball_glob.txt +49 -0
  34. data/ext/couchbase/core/agent_group.cxx +0 -8
  35. data/ext/couchbase/core/agent_group.hxx +0 -4
  36. data/ext/couchbase/core/analytics_stream.cxx +314 -0
  37. data/ext/couchbase/core/analytics_stream.hxx +129 -0
  38. data/ext/couchbase/core/analytics_stream_component.cxx +245 -0
  39. data/ext/couchbase/core/analytics_stream_component.hxx +67 -0
  40. data/ext/couchbase/core/app_telemetry_meter.cxx +25 -3
  41. data/ext/couchbase/core/app_telemetry_meter.hxx +77 -0
  42. data/ext/couchbase/core/app_telemetry_reporter.cxx +7 -6
  43. data/ext/couchbase/core/bucket.cxx +381 -87
  44. data/ext/couchbase/core/bucket.hxx +105 -25
  45. data/ext/couchbase/core/bucket_unit_test_api.hxx +57 -0
  46. data/ext/couchbase/core/capella.hxx +91 -0
  47. data/ext/couchbase/core/cluster.cxx +1554 -398
  48. data/ext/couchbase/core/cluster.hxx +39 -8
  49. data/ext/couchbase/core/cluster_agent.cxx +0 -8
  50. data/ext/couchbase/core/cluster_agent.hxx +0 -4
  51. data/ext/couchbase/core/cluster_options.hxx +26 -3
  52. data/ext/couchbase/core/collections_component.cxx +39 -15
  53. data/ext/couchbase/core/config_profiles.cxx +1 -1
  54. data/ext/couchbase/core/crud_component.cxx +2 -2
  55. data/ext/couchbase/core/crud_options.hxx +34 -0
  56. data/ext/couchbase/core/crypto/cbcrypto.cc +18 -13
  57. data/ext/couchbase/core/document_id_redaction.hxx +81 -0
  58. data/ext/couchbase/core/error_context/base_error_context.hxx +7 -6
  59. data/ext/couchbase/core/error_context/key_value.cxx +25 -2
  60. data/ext/couchbase/core/error_context/key_value.hxx +60 -33
  61. data/ext/couchbase/core/error_context/key_value_error_context.hxx +16 -15
  62. data/ext/couchbase/core/error_context/search.hxx +5 -0
  63. data/ext/couchbase/core/error_context/search_json.hxx +3 -0
  64. data/ext/couchbase/core/error_context/subdocument_error_context.hxx +19 -18
  65. data/ext/couchbase/core/error_context/view.hxx +5 -0
  66. data/ext/couchbase/core/free_form_http_request.cxx +237 -4
  67. data/ext/couchbase/core/free_form_http_request.hxx +41 -8
  68. data/ext/couchbase/core/http_component.cxx +300 -284
  69. data/ext/couchbase/core/http_component.hxx +0 -4
  70. data/ext/couchbase/core/impl/analytics.cxx +38 -5
  71. data/ext/couchbase/core/impl/analytics.hxx +34 -0
  72. data/ext/couchbase/core/impl/bootstrap_error.hxx +0 -3
  73. data/ext/couchbase/core/impl/collection.cxx +215 -202
  74. data/ext/couchbase/core/impl/collection_manager.cxx +1 -1
  75. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +45 -18
  76. data/ext/couchbase/core/impl/error.cxx +22 -2
  77. data/ext/couchbase/core/impl/internal_analytics_stream_result.hxx +111 -0
  78. data/ext/couchbase/core/impl/internal_query_stream_result.hxx +110 -0
  79. data/ext/couchbase/core/impl/invoke_with_node_id.hxx +15 -7
  80. data/ext/couchbase/core/impl/key_value_error_category.cxx +6 -0
  81. data/ext/couchbase/core/impl/lookup_in_replica.cxx +10 -10
  82. data/ext/couchbase/core/impl/lookup_in_replica.hxx +4 -4
  83. data/ext/couchbase/core/impl/node_id.cxx +49 -13
  84. data/ext/couchbase/core/impl/observability_recorder.cxx +12 -2
  85. data/ext/couchbase/core/impl/observe_poll.cxx +63 -23
  86. data/ext/couchbase/core/impl/public_analytics_stream_result.cxx +372 -0
  87. data/ext/couchbase/core/impl/public_bucket.cxx +48 -2
  88. data/ext/couchbase/core/impl/public_cluster.cxx +325 -25
  89. data/ext/couchbase/core/impl/public_query_stream_result.cxx +380 -0
  90. data/ext/couchbase/core/impl/public_transaction_get_multi_replicas_from_preferred_server_group_result.cxx +42 -0
  91. data/ext/couchbase/core/impl/public_transaction_get_multi_result.cxx +42 -0
  92. data/ext/couchbase/core/impl/query.cxx +76 -7
  93. data/ext/couchbase/core/impl/query.hxx +36 -0
  94. data/ext/couchbase/core/impl/query_index_manager.cxx +54 -1
  95. data/ext/couchbase/core/impl/replica_utils.cxx +101 -0
  96. data/ext/couchbase/core/impl/replica_utils.hxx +64 -0
  97. data/ext/couchbase/core/impl/resolve_node_id.hxx +125 -0
  98. data/ext/couchbase/core/impl/scope.cxx +70 -0
  99. data/ext/couchbase/core/impl/search.cxx +31 -1
  100. data/ext/couchbase/core/impl/transactions.cxx +130 -0
  101. data/ext/couchbase/core/impl/wait_until_ready.cxx +439 -0
  102. data/ext/couchbase/core/impl/wait_until_ready.hxx +110 -0
  103. data/ext/couchbase/core/impl/with_bucket_config_or_timeout.hxx +180 -0
  104. data/ext/couchbase/core/impl/with_cancellation.hxx +11 -3
  105. data/ext/couchbase/core/io/configuration_belongs_to_session.hxx +66 -0
  106. data/ext/couchbase/core/io/dns_client.cxx +122 -45
  107. data/ext/couchbase/core/io/dns_codec.hxx +21 -21
  108. data/ext/couchbase/core/io/dns_config.cxx +21 -6
  109. data/ext/couchbase/core/io/http_command.hxx +149 -121
  110. data/ext/couchbase/core/io/http_error.hxx +107 -0
  111. data/ext/couchbase/core/io/http_parser.cxx +4 -0
  112. data/ext/couchbase/core/io/http_session.cxx +606 -154
  113. data/ext/couchbase/core/io/http_session.hxx +147 -30
  114. data/ext/couchbase/core/io/http_session_manager.hxx +329 -382
  115. data/ext/couchbase/core/io/http_streaming_parser.cxx +4 -0
  116. data/ext/couchbase/core/io/http_streaming_response.cxx +328 -43
  117. data/ext/couchbase/core/io/http_streaming_response.hxx +37 -3
  118. data/ext/couchbase/core/io/mcbp_buffer_pool.hxx +122 -0
  119. data/ext/couchbase/core/io/mcbp_command.hxx +150 -51
  120. data/ext/couchbase/core/io/mcbp_command_id.hxx +45 -0
  121. data/ext/couchbase/core/io/mcbp_message.cxx +9 -1
  122. data/ext/couchbase/core/io/mcbp_message.hxx +19 -0
  123. data/ext/couchbase/core/io/mcbp_output_queue.hxx +150 -0
  124. data/ext/couchbase/core/io/mcbp_parser.cxx +24 -7
  125. data/ext/couchbase/core/io/mcbp_session.cxx +316 -317
  126. data/ext/couchbase/core/io/mcbp_session.hxx +27 -18
  127. data/ext/couchbase/core/io/opaque_ring_table.hxx +145 -0
  128. data/ext/couchbase/core/io/retry_orchestrator.hxx +6 -5
  129. data/ext/couchbase/core/io/stream_deadline.hxx +50 -0
  130. data/ext/couchbase/core/io/streams.cxx +275 -14
  131. data/ext/couchbase/core/io/streams.hxx +53 -0
  132. data/ext/couchbase/core/logger/logger.cxx +36 -0
  133. data/ext/couchbase/core/logger/logger.hxx +46 -6
  134. data/ext/couchbase/core/logger/redaction.hxx +503 -0
  135. data/ext/couchbase/core/management/eventing_status.hxx +10 -0
  136. data/ext/couchbase/core/management/eventing_status_json.hxx +4 -0
  137. data/ext/couchbase/core/mcbp/big_endian.cxx +1 -1
  138. data/ext/couchbase/core/mcbp/codec.cxx +27 -18
  139. data/ext/couchbase/core/mcbp/operation_queue.cxx +2 -2
  140. data/ext/couchbase/core/mcbp/packet.hxx +2 -2
  141. data/ext/couchbase/core/mcbp/queue_request.cxx +23 -6
  142. data/ext/couchbase/core/mcbp/queue_request.hxx +21 -0
  143. data/ext/couchbase/core/meta/features.hxx +13 -0
  144. data/ext/couchbase/core/meta/version.cxx +6 -3
  145. data/ext/couchbase/core/metrics/logging_meter.cxx +5 -10
  146. data/ext/couchbase/core/metrics/meter_wrapper.cxx +63 -33
  147. data/ext/couchbase/core/metrics/meter_wrapper.hxx +55 -3
  148. data/ext/couchbase/core/operations/analytics_response_parsing.cxx +177 -0
  149. data/ext/couchbase/core/operations/analytics_response_parsing.hxx +55 -0
  150. data/ext/couchbase/core/operations/document_analytics.cxx +48 -130
  151. data/ext/couchbase/core/operations/document_analytics.hxx +14 -2
  152. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +15 -7
  153. data/ext/couchbase/core/operations/document_get_any_replica.hxx +19 -8
  154. data/ext/couchbase/core/operations/document_get_projected.cxx +1 -1
  155. data/ext/couchbase/core/{impl/get_replica.cxx → operations/document_get_replica.cxx} +21 -3
  156. data/ext/couchbase/core/{impl/get_replica.hxx → operations/document_get_replica.hxx} +31 -4
  157. data/ext/couchbase/core/operations/document_lookup_in.cxx +10 -10
  158. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +228 -198
  159. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +215 -217
  160. data/ext/couchbase/core/operations/document_query.cxx +108 -221
  161. data/ext/couchbase/core/operations/document_query.hxx +18 -4
  162. data/ext/couchbase/core/operations/document_search.cxx +52 -8
  163. data/ext/couchbase/core/operations/document_search.hxx +3 -0
  164. data/ext/couchbase/core/operations/document_view.cxx +3 -3
  165. data/ext/couchbase/core/operations/management/analytics_dataset_create.cxx +15 -8
  166. data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +4 -0
  167. data/ext/couchbase/core/operations/management/analytics_dataset_drop.cxx +11 -6
  168. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.cxx +3 -2
  169. data/ext/couchbase/core/operations/management/analytics_dataverse_create.cxx +10 -5
  170. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.cxx +10 -5
  171. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.cxx +2 -1
  172. data/ext/couchbase/core/operations/management/analytics_index_create.cxx +33 -8
  173. data/ext/couchbase/core/operations/management/analytics_index_drop.cxx +12 -7
  174. data/ext/couchbase/core/operations/management/analytics_index_get_all.cxx +3 -2
  175. data/ext/couchbase/core/operations/management/analytics_link_connect.cxx +11 -6
  176. data/ext/couchbase/core/operations/management/analytics_link_create.cxx +3 -3
  177. data/ext/couchbase/core/operations/management/analytics_link_disconnect.cxx +10 -4
  178. data/ext/couchbase/core/operations/management/analytics_link_drop.cxx +6 -4
  179. data/ext/couchbase/core/operations/management/analytics_link_get_all.cxx +4 -3
  180. data/ext/couchbase/core/operations/management/analytics_link_replace.cxx +3 -3
  181. data/ext/couchbase/core/operations/management/analytics_link_utils.hxx +1 -1
  182. data/ext/couchbase/core/operations/management/bucket_create.cxx +37 -38
  183. data/ext/couchbase/core/operations/management/bucket_update.cxx +26 -28
  184. data/ext/couchbase/core/operations/management/change_password.cxx +2 -0
  185. data/ext/couchbase/core/operations/management/collection_drop.cxx +5 -1
  186. data/ext/couchbase/core/operations/management/error_utils.cxx +59 -5
  187. data/ext/couchbase/core/operations/management/error_utils.hxx +29 -1
  188. data/ext/couchbase/core/operations/management/eventing_deploy_function.cxx +9 -3
  189. data/ext/couchbase/core/operations/management/eventing_drop_function.cxx +8 -3
  190. data/ext/couchbase/core/operations/management/eventing_get_all_functions.cxx +4 -2
  191. data/ext/couchbase/core/operations/management/eventing_get_function.cxx +5 -3
  192. data/ext/couchbase/core/operations/management/eventing_get_status.cxx +4 -2
  193. data/ext/couchbase/core/operations/management/eventing_pause_function.cxx +9 -3
  194. data/ext/couchbase/core/operations/management/eventing_resume_function.cxx +9 -3
  195. data/ext/couchbase/core/operations/management/eventing_undeploy_function.cxx +9 -3
  196. data/ext/couchbase/core/operations/management/eventing_upsert_function.cxx +9 -3
  197. data/ext/couchbase/core/operations/management/group_drop.cxx +3 -1
  198. data/ext/couchbase/core/operations/management/group_get.cxx +3 -1
  199. data/ext/couchbase/core/operations/management/group_upsert.cxx +11 -8
  200. data/ext/couchbase/core/operations/management/query_index_build.cxx +5 -2
  201. data/ext/couchbase/core/operations/management/query_index_create.cxx +9 -3
  202. data/ext/couchbase/core/operations/management/query_index_drop.cxx +11 -4
  203. data/ext/couchbase/core/operations/management/query_index_get_all.cxx +1 -1
  204. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.cxx +1 -1
  205. data/ext/couchbase/core/operations/management/scope_drop.cxx +5 -1
  206. data/ext/couchbase/core/operations/management/scope_get_all.cxx +6 -1
  207. data/ext/couchbase/core/operations/management/search_get_stats.cxx +10 -0
  208. data/ext/couchbase/core/operations/management/search_index_analyze_document.cxx +3 -2
  209. data/ext/couchbase/core/operations/management/search_index_control_ingest.cxx +4 -3
  210. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.cxx +4 -3
  211. data/ext/couchbase/core/operations/management/search_index_control_query.cxx +4 -3
  212. data/ext/couchbase/core/operations/management/search_index_drop.cxx +2 -2
  213. data/ext/couchbase/core/operations/management/search_index_get.cxx +2 -2
  214. data/ext/couchbase/core/operations/management/search_index_get_documents_count.cxx +3 -2
  215. data/ext/couchbase/core/operations/management/search_index_get_stats.cxx +3 -1
  216. data/ext/couchbase/core/operations/management/search_index_upsert.cxx +2 -2
  217. data/ext/couchbase/core/operations/management/user_drop.cxx +3 -1
  218. data/ext/couchbase/core/operations/management/user_get.cxx +3 -1
  219. data/ext/couchbase/core/operations/management/user_upsert.cxx +12 -9
  220. data/ext/couchbase/core/operations/management/view_index_drop.cxx +1 -1
  221. data/ext/couchbase/core/operations/management/view_index_get.cxx +1 -1
  222. data/ext/couchbase/core/operations/management/view_index_upsert.cxx +1 -1
  223. data/ext/couchbase/core/operations/operation_traits.hxx +18 -0
  224. data/ext/couchbase/core/operations/query_response_parsing.cxx +211 -0
  225. data/ext/couchbase/core/operations/query_response_parsing.hxx +60 -0
  226. data/ext/couchbase/core/operations_fwd.hxx +3 -3
  227. data/ext/couchbase/core/origin.cxx +54 -26
  228. data/ext/couchbase/core/origin.hxx +12 -0
  229. data/ext/couchbase/core/orphan_reporter.cxx +2 -1
  230. data/ext/couchbase/core/platform/random.cc +7 -7
  231. data/ext/couchbase/core/protocol/client_request.cxx +2 -2
  232. data/ext/couchbase/core/protocol/client_request.hxx +38 -21
  233. data/ext/couchbase/core/protocol/client_response.cxx +11 -3
  234. data/ext/couchbase/core/protocol/client_response.hxx +27 -6
  235. data/ext/couchbase/core/protocol/cmd_append.cxx +2 -2
  236. data/ext/couchbase/core/protocol/cmd_cluster_map_change_notification.cxx +2 -2
  237. data/ext/couchbase/core/protocol/cmd_decrement.cxx +6 -6
  238. data/ext/couchbase/core/protocol/cmd_get.cxx +1 -1
  239. data/ext/couchbase/core/protocol/cmd_get_and_lock.cxx +2 -2
  240. data/ext/couchbase/core/protocol/cmd_get_and_touch.cxx +2 -2
  241. data/ext/couchbase/core/protocol/cmd_get_cluster_config.cxx +6 -4
  242. data/ext/couchbase/core/protocol/cmd_get_collection_id.cxx +2 -2
  243. data/ext/couchbase/core/protocol/cmd_get_error_map.cxx +1 -1
  244. data/ext/couchbase/core/protocol/cmd_get_meta.cxx +4 -4
  245. data/ext/couchbase/core/protocol/cmd_get_replica.cxx +1 -1
  246. data/ext/couchbase/core/protocol/cmd_hello.cxx +1 -1
  247. data/ext/couchbase/core/protocol/cmd_increment.cxx +6 -6
  248. data/ext/couchbase/core/protocol/cmd_insert.cxx +4 -4
  249. data/ext/couchbase/core/protocol/cmd_lookup_in.cxx +4 -3
  250. data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +4 -3
  251. data/ext/couchbase/core/protocol/cmd_mutate_in.cxx +10 -9
  252. data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +10 -10
  253. data/ext/couchbase/core/protocol/cmd_observe_seqno.cxx +7 -7
  254. data/ext/couchbase/core/protocol/cmd_prepend.cxx +2 -2
  255. data/ext/couchbase/core/protocol/cmd_remove.cxx +2 -2
  256. data/ext/couchbase/core/protocol/cmd_replace.cxx +4 -4
  257. data/ext/couchbase/core/protocol/cmd_touch.cxx +1 -1
  258. data/ext/couchbase/core/protocol/cmd_upsert.cxx +4 -4
  259. data/ext/couchbase/core/protocol/datatype.hxx +118 -1
  260. data/ext/couchbase/core/protocol/frame_info_utils.cxx +1 -1
  261. data/ext/couchbase/core/protocol/magic.hxx +4 -0
  262. data/ext/couchbase/core/protocol/magic_fmt.hxx +3 -0
  263. data/ext/couchbase/core/protocol/server_request.hxx +3 -1
  264. data/ext/couchbase/core/protocol/status.cxx +1 -1
  265. data/ext/couchbase/core/protostellar/analytics_converter.hxx +171 -0
  266. data/ext/couchbase/core/protostellar/bucket_admin_converter.hxx +301 -0
  267. data/ext/couchbase/core/protostellar/collection_admin_converter.hxx +92 -0
  268. data/ext/couchbase/core/protostellar/component.cxx +2445 -0
  269. data/ext/couchbase/core/protostellar/component.hxx +391 -0
  270. data/ext/couchbase/core/{columnar/bootstrap_notification_subscriber.hxx → protostellar/compression_settings.hxx} +11 -10
  271. data/ext/couchbase/core/protostellar/credentials.cxx +233 -0
  272. data/ext/couchbase/core/protostellar/credentials.hxx +88 -0
  273. data/ext/couchbase/core/protostellar/dispatcher.cxx +57 -0
  274. data/ext/couchbase/core/protostellar/dispatcher.hxx +482 -0
  275. data/ext/couchbase/core/protostellar/error_utils.cxx +293 -0
  276. data/ext/couchbase/core/protostellar/error_utils.hxx +97 -0
  277. data/ext/couchbase/core/protostellar/json_payload.hxx +49 -0
  278. data/ext/couchbase/core/protostellar/kv_converter.cxx +70 -0
  279. data/ext/couchbase/core/protostellar/kv_converter.hxx +600 -0
  280. data/ext/couchbase/core/protostellar/query_converter.hxx +265 -0
  281. data/ext/couchbase/core/protostellar/query_index_admin_converter.hxx +291 -0
  282. data/ext/couchbase/core/protostellar/query_proto.hxx +73 -0
  283. data/ext/couchbase/core/protostellar/search_converter.hxx +244 -0
  284. data/ext/couchbase/core/protostellar/search_index_admin_converter.hxx +156 -0
  285. data/ext/couchbase/core/protostellar/view_converter.hxx +158 -0
  286. data/ext/couchbase/core/query_stream.cxx +447 -0
  287. data/ext/couchbase/core/query_stream.hxx +141 -0
  288. data/ext/couchbase/core/query_stream_component.cxx +243 -0
  289. data/ext/couchbase/core/query_stream_component.hxx +68 -0
  290. data/ext/couchbase/core/range_scan_load_balancer.cxx +15 -8
  291. data/ext/couchbase/core/range_scan_orchestrator.cxx +15 -3
  292. data/ext/couchbase/core/response_handler.hxx +41 -4
  293. data/ext/couchbase/core/row_streamer.cxx +332 -46
  294. data/ext/couchbase/core/row_streamer.hxx +31 -1
  295. data/ext/couchbase/core/row_streamer_options.hxx +55 -0
  296. data/ext/couchbase/core/sasl/client.h +3 -0
  297. data/ext/couchbase/core/search_scoring.hxx +66 -0
  298. data/ext/couchbase/core/stream_error_details.hxx +69 -0
  299. data/ext/couchbase/core/timeout_defaults.hxx +0 -1
  300. data/ext/couchbase/core/topology/capabilities.hxx +6 -0
  301. data/ext/couchbase/core/topology/capabilities_fmt.hxx +3 -0
  302. data/ext/couchbase/core/topology/configuration.cxx +21 -6
  303. data/ext/couchbase/core/topology/configuration.hxx +29 -8
  304. data/ext/couchbase/core/topology/configuration_json.hxx +3 -0
  305. data/ext/couchbase/core/topology/error_map_json.hxx +3 -1
  306. data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +70 -4
  307. data/ext/couchbase/core/tracing/threshold_logging_tracer.hxx +10 -0
  308. data/ext/couchbase/core/transactions/active_transaction_record.cxx +0 -34
  309. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +362 -241
  310. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +24 -3
  311. data/ext/couchbase/core/transactions/error_list.hxx +2 -2
  312. data/ext/couchbase/core/transactions/get_multi_fetch.hxx +160 -0
  313. data/ext/couchbase/core/transactions/get_multi_orchestrator.cxx +326 -125
  314. data/ext/couchbase/core/transactions/get_multi_transaction_id.hxx +62 -0
  315. data/ext/couchbase/core/transactions/internal/atr_entry.hxx +22 -2
  316. data/ext/couchbase/core/transactions/internal/transaction_context.hxx +2 -2
  317. data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +23 -1
  318. data/ext/couchbase/core/transactions/internal/utils.hxx +50 -14
  319. data/ext/couchbase/core/transactions/staged_mutation.cxx +23 -18
  320. data/ext/couchbase/core/transactions/staged_mutation.hxx +15 -4
  321. data/ext/couchbase/core/transactions/transaction_context.cxx +55 -40
  322. data/ext/couchbase/core/transactions/transaction_get_result.hxx +16 -0
  323. data/ext/couchbase/core/transactions/transactions.cxx +3 -55
  324. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +194 -66
  325. data/ext/couchbase/core/transactions/transactions_config.cxx +0 -11
  326. data/ext/couchbase/core/transactions/utils.cxx +10 -0
  327. data/ext/couchbase/core/transactions/waitable_op_list.hxx +15 -4
  328. data/ext/couchbase/core/transactions.hxx +9 -9
  329. data/ext/couchbase/core/utils/byteswap.hxx +166 -9
  330. data/ext/couchbase/core/utils/connection_string.cxx +50 -85
  331. data/ext/couchbase/core/utils/connection_string.hxx +15 -0
  332. data/ext/couchbase/core/{columnar/backoff_calculator.hxx → utils/deadline.hxx} +13 -13
  333. data/ext/couchbase/core/utils/duration_parser.cxx +1 -1
  334. data/ext/couchbase/core/utils/json_streaming_lexer.cxx +48 -5
  335. data/ext/couchbase/core/utils/json_streaming_lexer.hxx +4 -1
  336. data/ext/couchbase/core/utils/movable_function.hxx +301 -52
  337. data/ext/couchbase/core/utils/name_codec.hxx +154 -11
  338. data/ext/couchbase/core/{columnar/retry_info.hxx → utils/process_id.hxx} +18 -13
  339. data/ext/couchbase/core/utils/url_codec.cxx +12 -51
  340. data/ext/couchbase/core/websocket_codec.cxx +3 -29
  341. data/ext/couchbase/couchbase/analytics_options.hxx +21 -10
  342. data/ext/couchbase/couchbase/analytics_row.hxx +105 -0
  343. data/ext/couchbase/couchbase/analytics_stream_result.hxx +266 -0
  344. data/ext/couchbase/couchbase/boolean_query.hxx +3 -3
  345. data/ext/couchbase/couchbase/bucket.hxx +57 -0
  346. data/ext/couchbase/couchbase/cluster.hxx +216 -5
  347. data/ext/couchbase/{core/columnar/security_options.hxx → couchbase/cluster_state.hxx} +18 -14
  348. data/ext/couchbase/couchbase/codec/lenient_json_transcoder.hxx +69 -0
  349. data/ext/couchbase/couchbase/collection.hxx +234 -14
  350. data/ext/couchbase/couchbase/common_durability_options.hxx +18 -3
  351. data/ext/couchbase/couchbase/conjunction_query.hxx +1 -1
  352. data/ext/couchbase/couchbase/create_dataset_analytics_options.hxx +6 -1
  353. data/ext/couchbase/couchbase/date_range_query.hxx +2 -2
  354. data/ext/couchbase/couchbase/decrement_options.hxx +1 -1
  355. data/ext/couchbase/couchbase/disjunction_query.hxx +1 -1
  356. data/ext/couchbase/couchbase/error.hxx +32 -0
  357. data/ext/couchbase/couchbase/error_codes.hxx +32 -0
  358. data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +1 -1
  359. data/ext/couchbase/couchbase/geo_distance_query.hxx +1 -1
  360. data/ext/couchbase/couchbase/geo_polygon_query.hxx +1 -1
  361. data/ext/couchbase/couchbase/get_replica_options.hxx +68 -0
  362. data/ext/couchbase/couchbase/get_replica_result.hxx +5 -3
  363. data/ext/couchbase/couchbase/get_replica_strategy.hxx +161 -0
  364. data/ext/couchbase/couchbase/get_result.hxx +1 -0
  365. data/ext/couchbase/couchbase/increment_options.hxx +1 -1
  366. data/ext/couchbase/couchbase/insert_options.hxx +1 -1
  367. data/ext/couchbase/couchbase/match_phrase_query.hxx +1 -1
  368. data/ext/couchbase/couchbase/match_query.hxx +1 -1
  369. data/ext/couchbase/couchbase/mutate_in_options.hxx +3 -3
  370. data/ext/couchbase/couchbase/network_options.hxx +1 -1
  371. data/ext/couchbase/couchbase/node_id.hxx +42 -14
  372. data/ext/couchbase/couchbase/node_id_for_options.hxx +7 -1
  373. data/ext/couchbase/couchbase/node_ids_options.hxx +8 -2
  374. data/ext/couchbase/couchbase/numeric_range_query.hxx +1 -1
  375. data/ext/couchbase/couchbase/phrase_query.hxx +1 -1
  376. data/ext/couchbase/couchbase/prefix_query.hxx +1 -1
  377. data/ext/couchbase/couchbase/query_options.hxx +23 -12
  378. data/ext/couchbase/couchbase/query_row.hxx +111 -0
  379. data/ext/couchbase/couchbase/query_stream_result.hxx +302 -0
  380. data/ext/couchbase/couchbase/query_string_query.hxx +3 -3
  381. data/ext/couchbase/couchbase/regexp_query.hxx +1 -1
  382. data/ext/couchbase/couchbase/replace_options.hxx +3 -3
  383. data/ext/couchbase/couchbase/result.hxx +14 -3
  384. data/ext/couchbase/couchbase/scan_result_item.hxx +1 -0
  385. data/ext/couchbase/couchbase/scope.hxx +85 -2
  386. data/ext/couchbase/couchbase/search_options.hxx +58 -8
  387. data/ext/couchbase/couchbase/search_scoring.hxx +94 -0
  388. data/ext/couchbase/couchbase/search_scoring_none.hxx +51 -0
  389. data/ext/couchbase/couchbase/search_scoring_reciprocal_rank_fusion.hxx +88 -0
  390. data/ext/couchbase/couchbase/search_scoring_relative_score_fusion.hxx +70 -0
  391. data/ext/couchbase/couchbase/term_range_query.hxx +1 -1
  392. data/ext/couchbase/couchbase/tracing/request_span.hxx +46 -0
  393. data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +23 -21
  394. data/ext/couchbase/couchbase/transactions/transaction_get_multi_result.hxx +24 -19
  395. data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +17 -3
  396. data/ext/couchbase/couchbase/transactions/transactions_config.hxx +4 -2
  397. data/ext/couchbase/couchbase/transactions.hxx +27 -18
  398. data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
  399. data/ext/couchbase/couchbase/vector_query.hxx +1 -1
  400. data/ext/couchbase/couchbase/wait_until_ready_options.hxx +111 -0
  401. data/ext/couchbase/couchbase/wildcard_query.hxx +1 -1
  402. data/ext/extconf.rb +15 -10
  403. data/ext/rcb_analytics.cxx +82 -102
  404. data/ext/rcb_backend.cxx +42 -36
  405. data/ext/rcb_backend.hxx +2 -0
  406. data/ext/rcb_buckets.cxx +47 -59
  407. data/ext/rcb_collections.cxx +42 -52
  408. data/ext/rcb_crud.cxx +345 -224
  409. data/ext/rcb_diagnostics.cxx +117 -27
  410. data/ext/rcb_exceptions.cxx +152 -99
  411. data/ext/rcb_exceptions.hxx +25 -0
  412. data/ext/rcb_extras.cxx +18 -19
  413. data/ext/rcb_hdr_histogram.cxx +19 -4
  414. data/ext/rcb_logger.cxx +202 -27
  415. data/ext/rcb_logger.hxx +12 -0
  416. data/ext/rcb_multi.cxx +40 -40
  417. data/ext/rcb_observability.cxx +7 -5
  418. data/ext/rcb_query.cxx +99 -142
  419. data/ext/rcb_range_scan.cxx +41 -35
  420. data/ext/rcb_search.cxx +98 -99
  421. data/ext/rcb_users.cxx +36 -56
  422. data/ext/rcb_utils.cxx +100 -37
  423. data/ext/rcb_utils.hxx +287 -33
  424. data/ext/rcb_version.cxx +1 -1
  425. data/ext/rcb_views.cxx +55 -51
  426. data/lib/active_support/cache/couchbase_store.rb +77 -12
  427. data/lib/couchbase/bucket.rb +20 -0
  428. data/lib/couchbase/cluster.rb +33 -14
  429. data/lib/couchbase/collection.rb +36 -1
  430. data/lib/couchbase/errors.rb +18 -0
  431. data/lib/couchbase/fork_hooks.rb +16 -7
  432. data/lib/couchbase/get_replica_strategy.rb +89 -0
  433. data/lib/couchbase/logger.rb +1 -1
  434. data/lib/couchbase/management/analytics_index_manager.rb +15 -15
  435. data/lib/couchbase/management/bucket_manager.rb +6 -6
  436. data/lib/couchbase/management/collection_manager.rb +6 -6
  437. data/lib/couchbase/management/query_index_manager.rb +7 -7
  438. data/lib/couchbase/management/search_index_manager.rb +13 -13
  439. data/lib/couchbase/management/user_manager.rb +10 -10
  440. data/lib/couchbase/management/view_index_manager.rb +5 -5
  441. data/lib/couchbase/options.rb +181 -44
  442. data/lib/couchbase/protostellar/bucket.rb +4 -0
  443. data/lib/couchbase/protostellar/cluster.rb +4 -0
  444. data/lib/couchbase/protostellar/collection.rb +4 -0
  445. data/lib/couchbase/protostellar/error_handling.rb +2 -1
  446. data/lib/couchbase/protostellar/request.rb +1 -0
  447. data/lib/couchbase/protostellar/request_generator/kv.rb +16 -2
  448. data/lib/couchbase/protostellar/request_generator/search.rb +17 -1
  449. data/lib/couchbase/protostellar/retry/orchestrator.rb +3 -2
  450. data/lib/couchbase/protostellar/retry/strategies/fail_fast.rb +33 -0
  451. data/lib/couchbase/protostellar/retry/strategies.rb +1 -0
  452. data/lib/couchbase/search_options.rb +95 -6
  453. data/lib/couchbase/version.rb +1 -1
  454. metadata +92 -33
  455. data/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +0 -40
  456. data/ext/couchbase/core/columnar/agent.hxx +0 -71
  457. data/ext/couchbase/core/columnar/agent_config.hxx +0 -59
  458. data/ext/couchbase/core/columnar/background_bootstrap_listener.hxx +0 -42
  459. data/ext/couchbase/core/columnar/backoff_calculator.cxx +0 -62
  460. data/ext/couchbase/core/columnar/columnar_agent.cxx +0 -147
  461. data/ext/couchbase/core/columnar/columnar_agent_config.cxx +0 -48
  462. data/ext/couchbase/core/columnar/columnar_error.cxx +0 -51
  463. data/ext/couchbase/core/columnar/database_management_options.hxx +0 -56
  464. data/ext/couchbase/core/columnar/error.hxx +0 -51
  465. data/ext/couchbase/core/columnar/error_codes.cxx +0 -107
  466. data/ext/couchbase/core/columnar/error_codes.hxx +0 -75
  467. data/ext/couchbase/core/columnar/management_component.cxx +0 -300
  468. data/ext/couchbase/core/columnar/management_component.hxx +0 -56
  469. data/ext/couchbase/core/columnar/query_component.cxx +0 -523
  470. data/ext/couchbase/core/columnar/query_component.hxx +0 -57
  471. data/ext/couchbase/core/columnar/query_options.hxx +0 -59
  472. data/ext/couchbase/core/columnar/query_result.cxx +0 -130
  473. data/ext/couchbase/core/columnar/query_result.hxx +0 -78
  474. data/ext/couchbase/core/io/config_tracker.cxx +0 -687
  475. data/ext/couchbase/core/io/config_tracker.hxx +0 -123
@@ -1,687 +0,0 @@
1
- /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
- /*
3
- * Copyright 2020-Present Couchbase, Inc.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- #include "config_tracker.hxx"
19
-
20
- #include <couchbase/build_config.hxx>
21
-
22
- #include "core/impl/bootstrap_state_listener.hxx"
23
- #include "core/logger/logger.hxx"
24
- #include "core/origin.hxx"
25
- #include "core/protocol/client_request.hxx"
26
- #include "core/protocol/cmd_get_cluster_config.hxx"
27
- #include "core/utils/join_strings.hxx"
28
- #include "http_session_manager.hxx"
29
- #include "mcbp_session.hxx"
30
-
31
- #include <asio/steady_timer.hpp>
32
- #include <spdlog/fmt/bundled/chrono.h>
33
-
34
- namespace couchbase::core::io
35
- {
36
-
37
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
38
- class cluster_config_tracker_impl
39
- : public std::enable_shared_from_this<cluster_config_tracker_impl>
40
- , public config_listener
41
- , public columnar::background_bootstrap_listener
42
- {
43
- #else
44
- class cluster_config_tracker_impl
45
- : public std::enable_shared_from_this<cluster_config_tracker_impl>
46
- , public config_listener
47
- {
48
- #endif
49
- public:
50
- cluster_config_tracker_impl(std::string client_id,
51
- couchbase::core::origin origin,
52
- asio::io_context& ctx,
53
- tls_context_provider& tls,
54
- std::shared_ptr<impl::bootstrap_state_listener> state_listener,
55
- std::vector<protocol::hello_feature> supported_features = {})
56
- : client_id_{ std::move(client_id) }
57
- , origin_{ std::move(origin) }
58
- , ctx_{ ctx }
59
- , tls_{ tls }
60
- , heartbeat_timer_(ctx_)
61
- , heartbeat_interval_{ origin_.options().config_poll_floor >
62
- origin_.options().config_poll_interval
63
- ? origin_.options().config_poll_floor
64
- : origin_.options().config_poll_interval }
65
- , state_listener_{ std::move(state_listener) }
66
- , supported_features_{ std::move(supported_features) }
67
- {
68
- log_prefix_ = fmt::format("[{}/-]", client_id_);
69
- }
70
-
71
- void close()
72
- {
73
- if (bool expected_state{ false }; !closed_.compare_exchange_strong(expected_state, true)) {
74
- return;
75
- }
76
- heartbeat_timer_.cancel();
77
- if (state_listener_ != nullptr) {
78
- state_listener_->unregister_config_listener(shared_from_this());
79
- }
80
-
81
- {
82
- const std::scoped_lock lock(config_listeners_mutex_);
83
- config_listeners_.clear();
84
- }
85
-
86
- std::vector<io::mcbp_session> old_sessions;
87
- {
88
- const std::scoped_lock lock(sessions_mutex_);
89
- std::swap(old_sessions, sessions_);
90
- }
91
- for (auto& session : old_sessions) {
92
- session.stop(retry_reason::do_not_retry);
93
- }
94
- }
95
-
96
- void create_sessions(
97
- utils::movable_function<
98
- void(std::error_code, const topology::configuration&, const cluster_options&)>&& handler)
99
- {
100
- io::mcbp_session new_session =
101
- origin_.options().enable_tls
102
- ? io::mcbp_session(client_id_, {}, ctx_, tls_, origin_, state_listener_)
103
- : io::mcbp_session(client_id_, {}, ctx_, origin_, state_listener_);
104
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
105
- new_session.add_background_bootstrap_listener(shared_from_this());
106
- #endif
107
- new_session.bootstrap([self = shared_from_this(), new_session, h = std::move(handler)](
108
- std::error_code ec, const topology::configuration& cfg) mutable {
109
- if (!ec) {
110
- if (self->origin_.options().network == "auto") {
111
- self->origin_.options().network = cfg.select_network(new_session.bootstrap_hostname());
112
- if (self->origin_.options().network == "default") {
113
- CB_LOG_DEBUG(R"({} detected network is "{}")",
114
- new_session.log_prefix(),
115
- self->origin_.options().network);
116
- } else {
117
- CB_LOG_INFO(R"({} detected network is "{}")",
118
- new_session.log_prefix(),
119
- self->origin_.options().network);
120
- }
121
- }
122
- if (self->origin_.options().network != "default") {
123
- self->origin_.set_nodes_from_config(cfg);
124
- CB_LOG_INFO(
125
- "replace list of bootstrap nodes with addresses of alternative network \"{}\": [{}]",
126
- self->origin_.options().network,
127
- utils::join_strings(self->origin_.get_nodes(), ","));
128
- }
129
-
130
- new_session.on_configuration_update(self);
131
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
132
- self->notify_bootstrap_success(new_session.id());
133
- #endif
134
- new_session.on_stop([id = new_session.id(), self]() {
135
- self->remove_session(id);
136
- });
137
- {
138
- const std::scoped_lock lock(self->sessions_mutex_);
139
- self->sessions_.emplace_back(std::move(new_session));
140
- }
141
- self->update_config(cfg);
142
- self->poll_config({});
143
- } else {
144
- // don't need to stop the session as if we hit this point the session will stop itself
145
- CB_LOG_WARNING(R"({} failed to bootstrap cluster session ec={}")",
146
- new_session.log_prefix(),
147
- ec.message());
148
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
149
- if (new_session.last_bootstrap_error().has_value()) {
150
- self->notify_bootstrap_error(std::move(new_session).last_bootstrap_error().value());
151
- } else {
152
- self->notify_bootstrap_error(
153
- { ec, ec.message(), new_session.bootstrap_hostname(), new_session.bootstrap_port() });
154
- }
155
- #endif
156
- }
157
- h(ec, cfg, self->origin_.options());
158
- });
159
- }
160
-
161
- void on_configuration_update(std::shared_ptr<config_listener> handler)
162
- {
163
- const std::scoped_lock lock(config_listeners_mutex_);
164
- config_listeners_.emplace_back(std::move(handler));
165
- }
166
-
167
- [[nodiscard]] auto supported_features() const -> std::vector<protocol::hello_feature>
168
- {
169
- if (!supported_features_.empty()) {
170
- return supported_features_;
171
- }
172
- std::vector<io::mcbp_session> sessions;
173
- std::vector<protocol::hello_feature> supported_features;
174
- {
175
- const std::scoped_lock lock(sessions_mutex_);
176
- sessions = sessions_;
177
- }
178
- for (const auto& session : sessions) {
179
- if (supported_features.empty()) {
180
- supported_features = session.supported_features();
181
- } else {
182
- // TODO(JC): this seems like a larger problem....
183
- if (supported_features != session.supported_features()) {
184
- CB_LOG_WARNING("Supported features mismatch between sessions.");
185
- }
186
- }
187
- }
188
- return supported_features;
189
- }
190
-
191
- void register_state_listener()
192
- {
193
- if (state_listener_) {
194
- state_listener_->register_config_listener(shared_from_this());
195
- }
196
- }
197
-
198
- void update_config(topology::configuration config) override
199
- {
200
- update_cluster_config(config);
201
- }
202
-
203
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
204
- void notify_bootstrap_error(const impl::bootstrap_error& error) override
205
- {
206
- std::set<std::shared_ptr<columnar::bootstrap_notification_subscriber>> subscribers;
207
- {
208
- const std::scoped_lock lock(bootstrap_notification_subscribers_mutex_);
209
- subscribers = bootstrap_notification_subscribers_;
210
- }
211
- for (const auto& subscriber : subscribers) {
212
- subscriber->notify_bootstrap_error(error);
213
- }
214
- }
215
-
216
- void notify_bootstrap_success(const std::string& session_id) override
217
- {
218
- std::set<std::shared_ptr<columnar::bootstrap_notification_subscriber>> subscribers;
219
- {
220
- const std::scoped_lock lock(bootstrap_notification_subscribers_mutex_);
221
- subscribers = bootstrap_notification_subscribers_;
222
- }
223
- for (const auto& subscriber : subscribers) {
224
- subscriber->notify_bootstrap_success(session_id);
225
- }
226
- }
227
-
228
- void register_bootstrap_notification_subscriber(
229
- std::shared_ptr<columnar::bootstrap_notification_subscriber> subscriber) override
230
- {
231
- const std::scoped_lock lock(bootstrap_notification_subscribers_mutex_);
232
- bootstrap_notification_subscribers_.insert(subscriber);
233
- }
234
-
235
- void unregister_bootstrap_notification_subscriber(
236
- std::shared_ptr<columnar::bootstrap_notification_subscriber> subscriber) override
237
- {
238
- const std::scoped_lock lock(bootstrap_notification_subscribers_mutex_);
239
- bootstrap_notification_subscribers_.erase(subscriber);
240
- }
241
- #endif
242
-
243
- [[nodiscard]] auto has_config() const -> bool
244
- {
245
- return configured_;
246
- }
247
-
248
- [[nodiscard]] auto config() -> std::optional<topology::configuration>
249
- {
250
- const std::scoped_lock lock(config_mutex_);
251
- return config_;
252
- }
253
-
254
- private:
255
- void diff_nodes(const std::vector<topology::configuration::node>& lhs,
256
- const std::vector<topology::configuration::node>& rhs,
257
- std::vector<topology::configuration::node>& output)
258
- {
259
- for (const auto& re : rhs) {
260
- bool known = false;
261
- const auto& rhost = re.hostname_for(origin_.options().network);
262
- const auto rport = re.port_or(
263
- origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
264
- for (const auto& le : lhs) {
265
- const auto& lhost = le.hostname_for(origin_.options().network);
266
- const auto lport = le.port_or(
267
- origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
268
- if (rhost == lhost && rport == lport) {
269
- known = true;
270
- break;
271
- }
272
- }
273
- if (!known) {
274
- output.push_back(re);
275
- }
276
- }
277
- }
278
-
279
- void fetch_config()
280
- {
281
- if (closed_) {
282
- return;
283
- }
284
- std::optional<io::mcbp_session> session{};
285
- {
286
- const std::scoped_lock lock(sessions_mutex_);
287
-
288
- if (sessions_.empty()) {
289
- CB_LOG_DEBUG(R"({} unable to find connected session (sessions_ is empty), retry in {})",
290
- log_prefix_,
291
- heartbeat_interval_);
292
- return;
293
- }
294
-
295
- const std::size_t start = heartbeat_next_index_.fetch_add(1);
296
- std::size_t i = start;
297
- do {
298
- const std::size_t session_idx = i % sessions_.size();
299
- if (sessions_[session_idx].is_bootstrapped() && sessions_[session_idx].supports_gcccp()) {
300
- session = sessions_[session_idx];
301
- }
302
- i = heartbeat_next_index_.fetch_add(1);
303
- } while (start % sessions_.size() != i % sessions_.size());
304
- }
305
- if (session) {
306
- protocol::client_request<protocol::get_cluster_config_request_body> req;
307
- req.opaque(session->next_opaque());
308
- session->write_and_flush(req.data());
309
- } else {
310
- CB_LOG_DEBUG(R"({} unable to find connected session with GCCCP support, retry in {})",
311
- log_prefix_,
312
- heartbeat_interval_);
313
- }
314
- }
315
-
316
- void poll_config(std::error_code ec)
317
- {
318
- if (ec == asio::error::operation_aborted || closed_) {
319
- return;
320
- }
321
-
322
- if (heartbeat_timer_.expiry() > std::chrono::steady_clock::now()) {
323
- return;
324
- }
325
-
326
- fetch_config();
327
-
328
- heartbeat_timer_.expires_after(heartbeat_interval_);
329
- return heartbeat_timer_.async_wait([self = shared_from_this()](std::error_code e) {
330
- if (e == asio::error::operation_aborted) {
331
- return;
332
- }
333
- self->poll_config(e);
334
- });
335
- }
336
-
337
- auto should_update_config(const topology::configuration& config) -> bool
338
- {
339
- if (!config_) {
340
- CB_LOG_DEBUG("{} initialize configuration rev={}", log_prefix_, config.rev_str());
341
- } else {
342
- if (config.force) {
343
- CB_LOG_DEBUG("{} forced to accept configuration rev={}", log_prefix_, config.rev_str());
344
- } else if (config_ < config) {
345
- CB_LOG_DEBUG("{} will update the configuration old={} -> new={}",
346
- log_prefix_,
347
- config_->rev_str(),
348
- config.rev_str());
349
- } else {
350
- return false;
351
- }
352
- }
353
- return true;
354
- }
355
-
356
- void update_config_sessions(const topology::configuration& config)
357
- {
358
- const std::scoped_lock lock(sessions_mutex_);
359
- std::vector<io::mcbp_session> new_sessions{};
360
-
361
- for (const auto& node : config.nodes) {
362
- const auto& hostname = node.hostname_for(origin_.options().network);
363
- auto port = node.port_or(
364
- origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
365
- if (port == 0) {
366
- continue;
367
- }
368
-
369
- bool reused_session{ false };
370
- for (auto it = sessions_.begin(); it != sessions_.end(); ++it) {
371
- CB_LOG_DEBUG(R"({} rev={}, checking cluster session="{}", address="{}:{}")",
372
- log_prefix_,
373
- config.rev_str(),
374
- it->id(),
375
- it->bootstrap_hostname(),
376
- it->bootstrap_port());
377
- if (it->bootstrap_hostname() == hostname && it->bootstrap_port_number() == port) {
378
- CB_LOG_DEBUG(R"({} rev={}, preserve cluster session="{}", address="{}:{}")",
379
- log_prefix_,
380
- config.rev_str(),
381
- it->id(),
382
- it->bootstrap_hostname(),
383
- it->bootstrap_port());
384
- new_sessions.emplace_back(std::move(*it));
385
- reused_session = true;
386
- sessions_.erase(it);
387
- break;
388
- }
389
- }
390
- if (reused_session) {
391
- continue;
392
- }
393
-
394
- const couchbase::core::origin origin(
395
- origin_.credentials(), hostname, port, origin_.options());
396
- io::mcbp_session session =
397
- origin_.options().enable_tls
398
- ? io::mcbp_session(client_id_, node.node_uuid, ctx_, tls_, origin, state_listener_)
399
- : io::mcbp_session(client_id_, node.node_uuid, ctx_, origin, state_listener_);
400
- CB_LOG_DEBUG(R"({} rev={}, add cluster session="{}", address="{}:{}")",
401
- log_prefix_,
402
- config.rev_str(),
403
- session.id(),
404
- hostname,
405
- port);
406
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
407
- session.add_background_bootstrap_listener(shared_from_this());
408
- #endif
409
- session.bootstrap([self = shared_from_this(), session](std::error_code err,
410
- topology::configuration cfg) mutable {
411
- if (err) {
412
- CB_LOG_WARNING(R"({} failed to bootstrap cluster session="{}", address="{}:{}", ec={})",
413
- session.log_prefix(),
414
- session.id(),
415
- session.bootstrap_hostname(),
416
- session.bootstrap_port(),
417
- err.message());
418
- return self->remove_session(session.id());
419
- }
420
- self->update_config(std::move(cfg));
421
- session.on_configuration_update(self);
422
- session.on_stop([id = session.id(), self]() {
423
- self->remove_session(id);
424
- });
425
- });
426
- new_sessions.emplace_back(std::move(session));
427
- }
428
- std::swap(sessions_, new_sessions);
429
-
430
- for (auto it = new_sessions.begin(); it != new_sessions.end(); ++it) {
431
- CB_LOG_DEBUG(R"({} rev={}, drop cluster session="{}", address="{}:{}")",
432
- log_prefix_,
433
- config.rev_str(),
434
- it->id(),
435
- it->bootstrap_hostname(),
436
- it->bootstrap_port());
437
- asio::post(asio::bind_executor(ctx_, [session = std::move(*it)]() mutable {
438
- return session.stop(retry_reason::do_not_retry);
439
- }));
440
- }
441
- }
442
-
443
- void update_cluster_config(const topology::configuration& config)
444
- {
445
- std::vector<topology::configuration::node> added{};
446
- std::vector<topology::configuration::node> removed{};
447
- {
448
- const std::scoped_lock lock(config_mutex_);
449
- if (!should_update_config(config)) {
450
- return;
451
- }
452
- if (auto current_config = config_; current_config) {
453
- diff_nodes(current_config->nodes, config.nodes, added);
454
- diff_nodes(config.nodes, current_config->nodes, removed);
455
- } else {
456
- added = config.nodes;
457
- }
458
- config_.reset();
459
- config_ = config;
460
- configured_ = true;
461
-
462
- {
463
- const std::scoped_lock listeners_lock(config_listeners_mutex_);
464
- for (const auto& listener : config_listeners_) {
465
- listener->update_config(*config_);
466
- }
467
- }
468
- }
469
- if (!added.empty() || !removed.empty()) {
470
- update_config_sessions(config);
471
- }
472
- }
473
-
474
- void restart_sessions()
475
- {
476
- const std::scoped_lock lock(config_mutex_, sessions_mutex_);
477
-
478
- std::optional<topology::configuration> current_config = config_;
479
- if (!current_config.has_value()) {
480
- return;
481
- }
482
-
483
- for (std::size_t index = 0; index < current_config->nodes.size(); ++index) {
484
- const auto& node = current_config->nodes[index];
485
-
486
- const auto& hostname = node.hostname_for(origin_.options().network);
487
- auto port = node.port_or(
488
- origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
489
- if (port == 0) {
490
- continue;
491
- }
492
-
493
- auto ptr =
494
- std::find_if(sessions_.begin(), sessions_.end(), [&hostname, &port](const auto& session) {
495
- return session.bootstrap_hostname() == hostname &&
496
- session.bootstrap_port_number() == port;
497
- });
498
- if (ptr != sessions_.end()) {
499
- continue;
500
- }
501
- const couchbase::core::origin origin(
502
- origin_.credentials(), hostname, port, origin_.options());
503
- io::mcbp_session session =
504
- origin_.options().enable_tls
505
- ? io::mcbp_session(client_id_, node.node_uuid, ctx_, tls_, origin, state_listener_)
506
- : io::mcbp_session(client_id_, node.node_uuid, ctx_, origin, state_listener_);
507
- CB_LOG_DEBUG(R"({} rev={}, restart cluster session="{}", address="{}:{}")",
508
- log_prefix_,
509
- current_config->rev_str(),
510
- session.id(),
511
- hostname,
512
- port);
513
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
514
- session.add_background_bootstrap_listener(shared_from_this());
515
- #endif
516
- session.bootstrap([self = shared_from_this(), session](std::error_code err,
517
- topology::configuration cfg) mutable {
518
- if (err) {
519
- return self->remove_session(session.id());
520
- }
521
- self->update_config(std::move(cfg));
522
- session.on_configuration_update(self);
523
- session.on_stop([id = session.id(), self]() {
524
- self->remove_session(id);
525
- });
526
- });
527
- sessions_.emplace_back(std::move(session));
528
- }
529
- }
530
-
531
- void remove_session(const std::string& id)
532
- {
533
- bool found{ false };
534
- const std::scoped_lock lock(sessions_mutex_);
535
- for (auto ptr = sessions_.cbegin(); ptr != sessions_.cend();) {
536
- if (ptr->id() == id) {
537
- CB_LOG_DEBUG(
538
- R"({} removed cluster session id="{}", address="{}", bootstrap_address="{}:{}")",
539
- log_prefix_,
540
- ptr->id(),
541
- ptr->remote_address(),
542
- ptr->bootstrap_hostname(),
543
- ptr->bootstrap_port());
544
- ptr = sessions_.erase(ptr);
545
- found = true;
546
- } else {
547
- ptr = std::next(ptr);
548
- }
549
- }
550
-
551
- if (found) {
552
- asio::post(asio::bind_executor(ctx_, [self = shared_from_this()]() {
553
- return self->restart_sessions();
554
- }));
555
- }
556
- }
557
-
558
- const std::string client_id_;
559
- couchbase::core::origin origin_{};
560
- std::string log_prefix_{};
561
- asio::io_context& ctx_;
562
- tls_context_provider& tls_;
563
-
564
- asio::steady_timer heartbeat_timer_;
565
- std::chrono::milliseconds heartbeat_interval_;
566
- std::atomic_size_t heartbeat_next_index_{ 0 };
567
-
568
- std::atomic_bool configured_{ false };
569
- std::atomic_bool closed_{ false };
570
-
571
- const std::shared_ptr<impl::bootstrap_state_listener> state_listener_;
572
- const std::vector<protocol::hello_feature> supported_features_;
573
-
574
- std::mutex config_listeners_mutex_{};
575
- std::vector<std::shared_ptr<config_listener>> config_listeners_{};
576
-
577
- mutable std::mutex config_mutex_{};
578
- std::optional<topology::configuration> config_{};
579
-
580
- std::vector<io::mcbp_session> sessions_{};
581
- mutable std::mutex sessions_mutex_{};
582
-
583
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
584
- std::set<std::shared_ptr<columnar::bootstrap_notification_subscriber>>
585
- bootstrap_notification_subscribers_{};
586
- std::mutex bootstrap_notification_subscribers_mutex_;
587
- #endif
588
- };
589
-
590
- cluster_config_tracker::cluster_config_tracker(
591
- std::string client_id,
592
- couchbase::core::origin origin,
593
- asio::io_context& ctx,
594
- tls_context_provider& tls,
595
- std::shared_ptr<impl::bootstrap_state_listener> state_listener)
596
- : impl_{ std::make_shared<cluster_config_tracker_impl>(std::move(client_id),
597
- std::move(origin),
598
- ctx,
599
- tls,
600
- std::move(state_listener)) }
601
- {
602
- }
603
-
604
- cluster_config_tracker::~cluster_config_tracker()
605
- {
606
- impl_->close();
607
- }
608
-
609
- void
610
- cluster_config_tracker::close()
611
- {
612
- return impl_->close();
613
- }
614
-
615
- void
616
- cluster_config_tracker::create_sessions(
617
- utils::movable_function<
618
- void(std::error_code, const topology::configuration&, const cluster_options&)>&& handler)
619
- {
620
- return impl_->create_sessions(std::move(handler));
621
- }
622
-
623
- void
624
- cluster_config_tracker::on_configuration_update(std::shared_ptr<config_listener> handler)
625
- {
626
- return impl_->on_configuration_update(std::move(handler));
627
- }
628
-
629
- void
630
- cluster_config_tracker::register_state_listener()
631
- {
632
- return impl_->register_state_listener();
633
- }
634
-
635
- void
636
- cluster_config_tracker::update_config(topology::configuration config)
637
- {
638
- return impl_->update_config(std::move(config));
639
- }
640
-
641
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
642
- void
643
- cluster_config_tracker::notify_bootstrap_error(const impl::bootstrap_error& error)
644
- {
645
- return impl_->notify_bootstrap_error(error);
646
- }
647
-
648
- void
649
- cluster_config_tracker::notify_bootstrap_success(const std::string& session_id)
650
- {
651
- return impl_->notify_bootstrap_success(session_id);
652
- }
653
-
654
- void
655
- cluster_config_tracker::register_bootstrap_notification_subscriber(
656
- std::shared_ptr<columnar::bootstrap_notification_subscriber> subscriber)
657
- {
658
- return impl_->register_bootstrap_notification_subscriber(std::move(subscriber));
659
- }
660
-
661
- void
662
- cluster_config_tracker::unregister_bootstrap_notification_subscriber(
663
- std::shared_ptr<columnar::bootstrap_notification_subscriber> subscriber)
664
- {
665
- return impl_->unregister_bootstrap_notification_subscriber(std::move(subscriber));
666
- }
667
- #endif
668
-
669
- auto
670
- cluster_config_tracker::has_config() const -> bool
671
- {
672
- return impl_->has_config();
673
- }
674
-
675
- auto
676
- cluster_config_tracker::config() const -> std::optional<topology::configuration>
677
- {
678
- return impl_->config();
679
- }
680
-
681
- auto
682
- cluster_config_tracker::supported_features() const -> std::vector<protocol::hello_feature>
683
- {
684
- return impl_->supported_features();
685
- }
686
-
687
- } // namespace couchbase::core::io