couchbase 3.7.0 → 3.8.1

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 (349) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/ext/CMakeLists.txt +4 -1
  4. data/ext/cache/extconf_include.rb +4 -3
  5. data/ext/cache/mozilla-ca-bundle.crt +66 -665
  6. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  7. data/ext/couchbase/CMakeLists.txt +26 -11
  8. data/ext/couchbase/cmake/APKBUILD.in +17 -1
  9. data/ext/couchbase/cmake/Bundler.cmake +9 -1
  10. data/ext/couchbase/cmake/Cache.cmake +48 -19
  11. data/ext/couchbase/cmake/CompilerOptions.cmake +3 -1
  12. data/ext/couchbase/cmake/OpenSSL.cmake +10 -2
  13. data/ext/couchbase/cmake/Packaging.cmake +48 -8
  14. data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +43 -1
  15. data/ext/couchbase/cmake/build_config.hxx.in +2 -0
  16. data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +18 -0
  17. data/ext/couchbase/cmake/tarball_glob.txt +10 -0
  18. data/ext/couchbase/core/app_telemetry_meter.cxx +1 -0
  19. data/ext/couchbase/core/app_telemetry_reporter.cxx +45 -43
  20. data/ext/couchbase/core/app_telemetry_reporter.hxx +4 -3
  21. data/ext/couchbase/core/bucket.cxx +128 -13
  22. data/ext/couchbase/core/bucket.hxx +12 -2
  23. data/ext/couchbase/core/cluster.cxx +304 -152
  24. data/ext/couchbase/core/cluster.hxx +32 -0
  25. data/ext/couchbase/core/cluster_credentials.cxx +25 -0
  26. data/ext/couchbase/core/cluster_credentials.hxx +5 -0
  27. data/ext/couchbase/core/cluster_label_listener.cxx +72 -0
  28. data/ext/couchbase/core/cluster_label_listener.hxx +46 -0
  29. data/ext/couchbase/core/cluster_options.hxx +4 -0
  30. data/ext/couchbase/core/deprecation_utils.hxx +26 -0
  31. data/ext/couchbase/core/error.hxx +27 -0
  32. data/ext/couchbase/core/error_context/base_error_context.hxx +32 -0
  33. data/ext/couchbase/core/error_context/key_value.cxx +1 -0
  34. data/ext/couchbase/core/error_context/key_value.hxx +23 -0
  35. data/ext/couchbase/core/error_context/key_value_error_context.hxx +35 -0
  36. data/ext/couchbase/core/error_context/subdocument_error_context.hxx +41 -0
  37. data/ext/couchbase/core/free_form_http_request.hxx +0 -2
  38. data/ext/couchbase/core/http_component.cxx +12 -48
  39. data/ext/couchbase/core/impl/analytics.cxx +3 -2
  40. data/ext/couchbase/core/impl/analytics.hxx +2 -1
  41. data/ext/couchbase/core/impl/analytics_index_manager.cxx +249 -137
  42. data/ext/couchbase/core/impl/binary_collection.cxx +239 -128
  43. data/ext/couchbase/core/impl/bucket_manager.cxx +87 -35
  44. data/ext/couchbase/core/impl/collection.cxx +914 -372
  45. data/ext/couchbase/core/impl/collection_manager.cxx +89 -49
  46. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +4 -4
  47. data/ext/couchbase/core/impl/error.cxx +49 -17
  48. data/ext/couchbase/core/impl/error.hxx +15 -10
  49. data/ext/couchbase/core/impl/get_all_replicas.hxx +1 -1
  50. data/ext/couchbase/core/impl/get_any_replica.hxx +2 -1
  51. data/ext/couchbase/core/impl/get_replica.hxx +2 -0
  52. data/ext/couchbase/core/impl/invoke_with_node_id.hxx +44 -0
  53. data/ext/couchbase/core/impl/lookup_in_replica.hxx +1 -1
  54. data/ext/couchbase/core/impl/node_id.cxx +110 -0
  55. data/ext/couchbase/core/impl/node_id.hxx +40 -0
  56. data/ext/couchbase/core/impl/observability_recorder.cxx +161 -0
  57. data/ext/couchbase/core/impl/observability_recorder.hxx +77 -0
  58. data/ext/couchbase/core/impl/observe_seqno.hxx +2 -0
  59. data/ext/couchbase/core/impl/public_bucket.cxx +31 -7
  60. data/ext/couchbase/core/impl/public_cluster.cxx +107 -19
  61. data/ext/couchbase/core/impl/query.cxx +6 -3
  62. data/ext/couchbase/core/impl/query.hxx +3 -1
  63. data/ext/couchbase/core/impl/query_index_manager.cxx +267 -102
  64. data/ext/couchbase/core/impl/scope.cxx +53 -11
  65. data/ext/couchbase/core/impl/search.cxx +8 -4
  66. data/ext/couchbase/core/impl/search.hxx +6 -2
  67. data/ext/couchbase/core/impl/search_index_manager.cxx +131 -41
  68. data/ext/couchbase/core/impl/with_cancellation.hxx +75 -0
  69. data/ext/couchbase/core/io/config_tracker.cxx +9 -9
  70. data/ext/couchbase/core/io/config_tracker.hxx +2 -1
  71. data/ext/couchbase/core/io/http_command.hxx +98 -49
  72. data/ext/couchbase/core/io/http_context.hxx +2 -0
  73. data/ext/couchbase/core/io/http_session.cxx +23 -10
  74. data/ext/couchbase/core/io/http_session.hxx +17 -9
  75. data/ext/couchbase/core/io/http_session_manager.hxx +245 -270
  76. data/ext/couchbase/core/io/http_traits.hxx +0 -7
  77. data/ext/couchbase/core/io/mcbp_command.hxx +123 -44
  78. data/ext/couchbase/core/io/mcbp_session.cxx +251 -26
  79. data/ext/couchbase/core/io/mcbp_session.hxx +9 -1
  80. data/ext/couchbase/core/io/mcbp_traits.hxx +0 -8
  81. data/ext/couchbase/core/io/streams.cxx +3 -3
  82. data/ext/couchbase/core/io/streams.hxx +3 -2
  83. data/ext/couchbase/core/meta/features.hxx +15 -0
  84. data/ext/couchbase/core/meta/version.cxx +13 -0
  85. data/ext/couchbase/core/meta/version.hxx +3 -0
  86. data/ext/couchbase/core/metrics/constants.hxx +23 -0
  87. data/ext/couchbase/core/metrics/logging_meter.cxx +5 -5
  88. data/ext/couchbase/core/metrics/meter_wrapper.cxx +65 -63
  89. data/ext/couchbase/core/metrics/meter_wrapper.hxx +12 -10
  90. data/ext/couchbase/core/operations/document_analytics.hxx +0 -5
  91. data/ext/couchbase/core/operations/document_append.hxx +0 -4
  92. data/ext/couchbase/core/operations/document_decrement.hxx +0 -5
  93. data/ext/couchbase/core/operations/document_exists.hxx +0 -7
  94. data/ext/couchbase/core/operations/document_get.hxx +0 -7
  95. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +89 -29
  96. data/ext/couchbase/core/operations/document_get_and_lock.hxx +0 -9
  97. data/ext/couchbase/core/operations/document_get_and_touch.hxx +0 -9
  98. data/ext/couchbase/core/operations/document_get_any_replica.hxx +83 -2
  99. data/ext/couchbase/core/operations/document_get_projected.cxx +3 -4
  100. data/ext/couchbase/core/operations/document_get_projected.hxx +0 -9
  101. data/ext/couchbase/core/operations/document_increment.hxx +0 -5
  102. data/ext/couchbase/core/operations/document_insert.hxx +0 -4
  103. data/ext/couchbase/core/operations/document_lookup_in.hxx +0 -9
  104. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +50 -4
  105. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +121 -43
  106. data/ext/couchbase/core/operations/document_mutate_in.hxx +0 -5
  107. data/ext/couchbase/core/operations/document_prepend.hxx +0 -4
  108. data/ext/couchbase/core/operations/document_query.cxx +12 -12
  109. data/ext/couchbase/core/operations/document_query.hxx +0 -4
  110. data/ext/couchbase/core/operations/document_remove.hxx +0 -4
  111. data/ext/couchbase/core/operations/document_replace.hxx +0 -4
  112. data/ext/couchbase/core/operations/document_search.hxx +0 -7
  113. data/ext/couchbase/core/operations/document_touch.hxx +0 -7
  114. data/ext/couchbase/core/operations/document_unlock.hxx +0 -6
  115. data/ext/couchbase/core/operations/document_upsert.hxx +0 -4
  116. data/ext/couchbase/core/operations/document_view.cxx +2 -0
  117. data/ext/couchbase/core/operations/document_view.hxx +10 -13
  118. data/ext/couchbase/core/operations/http_noop.hxx +2 -0
  119. data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +2 -0
  120. data/ext/couchbase/core/operations/management/analytics_dataset_drop.hxx +2 -0
  121. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.hxx +2 -0
  122. data/ext/couchbase/core/operations/management/analytics_dataverse_create.hxx +2 -0
  123. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.hxx +2 -0
  124. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.hxx +2 -0
  125. data/ext/couchbase/core/operations/management/analytics_index_create.hxx +2 -0
  126. data/ext/couchbase/core/operations/management/analytics_index_drop.hxx +2 -0
  127. data/ext/couchbase/core/operations/management/analytics_index_get_all.hxx +2 -0
  128. data/ext/couchbase/core/operations/management/analytics_link_connect.hxx +2 -0
  129. data/ext/couchbase/core/operations/management/analytics_link_create.hxx +2 -0
  130. data/ext/couchbase/core/operations/management/analytics_link_disconnect.hxx +2 -0
  131. data/ext/couchbase/core/operations/management/analytics_link_drop.hxx +2 -0
  132. data/ext/couchbase/core/operations/management/analytics_link_get_all.hxx +2 -0
  133. data/ext/couchbase/core/operations/management/analytics_link_replace.hxx +2 -0
  134. data/ext/couchbase/core/operations/management/bucket_create.hxx +2 -0
  135. data/ext/couchbase/core/operations/management/bucket_describe.hxx +2 -0
  136. data/ext/couchbase/core/operations/management/bucket_drop.hxx +2 -0
  137. data/ext/couchbase/core/operations/management/bucket_flush.hxx +2 -0
  138. data/ext/couchbase/core/operations/management/bucket_get.hxx +2 -0
  139. data/ext/couchbase/core/operations/management/bucket_get_all.hxx +2 -0
  140. data/ext/couchbase/core/operations/management/bucket_update.hxx +2 -0
  141. data/ext/couchbase/core/operations/management/change_password.hxx +2 -0
  142. data/ext/couchbase/core/operations/management/cluster_describe.hxx +2 -0
  143. data/ext/couchbase/core/operations/management/cluster_developer_preview_enable.hxx +2 -0
  144. data/ext/couchbase/core/operations/management/collection_create.cxx +11 -11
  145. data/ext/couchbase/core/operations/management/collection_create.hxx +2 -0
  146. data/ext/couchbase/core/operations/management/collection_drop.cxx +11 -11
  147. data/ext/couchbase/core/operations/management/collection_drop.hxx +2 -0
  148. data/ext/couchbase/core/operations/management/collection_update.cxx +11 -11
  149. data/ext/couchbase/core/operations/management/collection_update.hxx +2 -0
  150. data/ext/couchbase/core/operations/management/collections_manifest_get.hxx +2 -0
  151. data/ext/couchbase/core/operations/management/error_utils.cxx +13 -7
  152. data/ext/couchbase/core/operations/management/eventing_deploy_function.hxx +2 -0
  153. data/ext/couchbase/core/operations/management/eventing_drop_function.hxx +2 -0
  154. data/ext/couchbase/core/operations/management/eventing_get_all_functions.hxx +2 -0
  155. data/ext/couchbase/core/operations/management/eventing_get_function.hxx +2 -0
  156. data/ext/couchbase/core/operations/management/eventing_get_status.hxx +2 -0
  157. data/ext/couchbase/core/operations/management/eventing_pause_function.hxx +2 -0
  158. data/ext/couchbase/core/operations/management/eventing_resume_function.hxx +2 -0
  159. data/ext/couchbase/core/operations/management/eventing_undeploy_function.hxx +2 -0
  160. data/ext/couchbase/core/operations/management/eventing_upsert_function.hxx +2 -0
  161. data/ext/couchbase/core/operations/management/freeform.hxx +2 -0
  162. data/ext/couchbase/core/operations/management/group_drop.hxx +2 -0
  163. data/ext/couchbase/core/operations/management/group_get.hxx +2 -0
  164. data/ext/couchbase/core/operations/management/group_get_all.hxx +2 -0
  165. data/ext/couchbase/core/operations/management/group_upsert.hxx +2 -0
  166. data/ext/couchbase/core/operations/management/query_index_build.hxx +2 -0
  167. data/ext/couchbase/core/operations/management/query_index_build_deferred.hxx +68 -30
  168. data/ext/couchbase/core/operations/management/query_index_create.cxx +5 -4
  169. data/ext/couchbase/core/operations/management/query_index_create.hxx +2 -0
  170. data/ext/couchbase/core/operations/management/query_index_drop.cxx +7 -6
  171. data/ext/couchbase/core/operations/management/query_index_drop.hxx +2 -0
  172. data/ext/couchbase/core/operations/management/query_index_get_all.hxx +4 -3
  173. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.hxx +2 -1
  174. data/ext/couchbase/core/operations/management/role_get_all.hxx +2 -0
  175. data/ext/couchbase/core/operations/management/scope_create.cxx +12 -13
  176. data/ext/couchbase/core/operations/management/scope_create.hxx +2 -0
  177. data/ext/couchbase/core/operations/management/scope_drop.cxx +8 -9
  178. data/ext/couchbase/core/operations/management/scope_drop.hxx +2 -0
  179. data/ext/couchbase/core/operations/management/scope_get_all.hxx +2 -0
  180. data/ext/couchbase/core/operations/management/search_get_stats.hxx +2 -0
  181. data/ext/couchbase/core/operations/management/search_index_analyze_document.hxx +2 -0
  182. data/ext/couchbase/core/operations/management/search_index_control_ingest.hxx +2 -0
  183. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.hxx +2 -0
  184. data/ext/couchbase/core/operations/management/search_index_control_query.hxx +2 -0
  185. data/ext/couchbase/core/operations/management/search_index_drop.hxx +2 -0
  186. data/ext/couchbase/core/operations/management/search_index_get.hxx +2 -0
  187. data/ext/couchbase/core/operations/management/search_index_get_all.hxx +2 -0
  188. data/ext/couchbase/core/operations/management/search_index_get_documents_count.hxx +2 -0
  189. data/ext/couchbase/core/operations/management/search_index_get_stats.hxx +2 -0
  190. data/ext/couchbase/core/operations/management/search_index_upsert.hxx +2 -0
  191. data/ext/couchbase/core/operations/management/user_drop.hxx +2 -0
  192. data/ext/couchbase/core/operations/management/user_get.hxx +2 -0
  193. data/ext/couchbase/core/operations/management/user_get_all.hxx +2 -0
  194. data/ext/couchbase/core/operations/management/user_upsert.hxx +2 -0
  195. data/ext/couchbase/core/operations/management/view_index_drop.hxx +2 -0
  196. data/ext/couchbase/core/operations/management/view_index_get.hxx +2 -0
  197. data/ext/couchbase/core/operations/management/view_index_get_all.hxx +2 -0
  198. data/ext/couchbase/core/operations/management/view_index_upsert.hxx +2 -0
  199. data/ext/couchbase/core/operations/operation_traits.hxx +6 -0
  200. data/ext/couchbase/core/operations.hxx +0 -1
  201. data/ext/couchbase/core/operations_fwd.hxx +8 -0
  202. data/ext/couchbase/core/origin.cxx +67 -12
  203. data/ext/couchbase/core/origin.hxx +13 -8
  204. data/ext/couchbase/core/orphan_reporter.cxx +164 -0
  205. data/ext/couchbase/core/orphan_reporter.hxx +65 -0
  206. data/ext/couchbase/core/sasl/CMakeLists.txt +1 -0
  207. data/ext/couchbase/core/sasl/client.cc +6 -0
  208. data/ext/couchbase/core/sasl/mechanism.cc +2 -1
  209. data/ext/couchbase/core/sasl/mechanism.h +2 -1
  210. data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.cc +41 -0
  211. data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.h +47 -0
  212. data/ext/couchbase/core/tls_context_provider.cxx +44 -0
  213. data/ext/couchbase/core/tls_context_provider.hxx +44 -0
  214. data/ext/couchbase/core/topology/configuration.cxx +21 -0
  215. data/ext/couchbase/core/topology/configuration.hxx +28 -0
  216. data/ext/couchbase/core/tracing/attribute_helpers.hxx +45 -0
  217. data/ext/couchbase/core/tracing/constants.hxx +148 -68
  218. data/ext/couchbase/core/tracing/threshold_logging_options.hxx +0 -3
  219. data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +122 -170
  220. data/ext/couchbase/core/tracing/tracer_wrapper.cxx +17 -24
  221. data/ext/couchbase/core/tracing/tracer_wrapper.hxx +8 -10
  222. data/ext/couchbase/core/tracing/wrapper_sdk_tracer.cxx +114 -0
  223. data/ext/couchbase/core/tracing/wrapper_sdk_tracer.hxx +85 -0
  224. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +16 -14
  225. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +4 -4
  226. data/ext/couchbase/core/transactions/transactions.cxx +1 -1
  227. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +1 -2
  228. data/ext/couchbase/core/utils/byteswap.hxx +12 -0
  229. data/ext/couchbase/core/utils/concurrent_fixed_priority_queue.hxx +102 -0
  230. data/ext/couchbase/core/utils/connection_string.cxx +2 -0
  231. data/ext/couchbase/core/utils/contains_string.cxx +61 -0
  232. data/ext/couchbase/core/utils/contains_string.hxx +26 -0
  233. data/ext/couchbase/couchbase/certificate_authenticator.hxx +1 -0
  234. data/ext/couchbase/couchbase/cluster.hxx +47 -0
  235. data/ext/couchbase/couchbase/cluster_options.hxx +16 -0
  236. data/ext/couchbase/couchbase/collection.hxx +133 -15
  237. data/ext/couchbase/couchbase/error.hxx +16 -0
  238. data/ext/couchbase/couchbase/error_codes.hxx +48 -48
  239. data/ext/couchbase/couchbase/jwt_authenticator.hxx +52 -0
  240. data/ext/couchbase/couchbase/metrics/meter.hxx +2 -1
  241. data/ext/couchbase/couchbase/metrics/otel_meter.hxx +75 -80
  242. data/ext/couchbase/couchbase/network_options.hxx +19 -0
  243. data/ext/couchbase/couchbase/node_id.hxx +123 -0
  244. data/ext/couchbase/couchbase/node_id_for_options.hxx +61 -0
  245. data/ext/couchbase/couchbase/node_ids_options.hxx +62 -0
  246. data/ext/couchbase/couchbase/password_authenticator.hxx +1 -0
  247. data/ext/couchbase/couchbase/result.hxx +42 -0
  248. data/ext/couchbase/couchbase/tracing/otel_tracer.hxx +15 -17
  249. data/ext/couchbase/couchbase/tracing/request_span.hxx +2 -2
  250. data/ext/couchbase.cxx +4 -0
  251. data/ext/extconf.rb +1 -0
  252. data/ext/rcb_analytics.cxx +157 -47
  253. data/ext/rcb_backend.cxx +118 -71
  254. data/ext/rcb_buckets.cxx +39 -16
  255. data/ext/rcb_collections.cxx +36 -12
  256. data/ext/rcb_crud.cxx +589 -294
  257. data/ext/rcb_hdr_histogram.cxx +219 -0
  258. data/ext/rcb_hdr_histogram.hxx +28 -0
  259. data/ext/rcb_logger.cxx +15 -17
  260. data/ext/rcb_multi.cxx +142 -59
  261. data/ext/rcb_observability.cxx +132 -0
  262. data/ext/rcb_observability.hxx +49 -0
  263. data/ext/rcb_query.cxx +77 -27
  264. data/ext/rcb_search.cxx +92 -31
  265. data/ext/rcb_users.cxx +69 -26
  266. data/ext/rcb_utils.cxx +91 -0
  267. data/ext/rcb_utils.hxx +141 -168
  268. data/ext/rcb_views.cxx +36 -12
  269. data/lib/active_support/cache/couchbase_store.rb +6 -6
  270. data/lib/couchbase/authenticator.rb +14 -0
  271. data/lib/couchbase/binary_collection.rb +37 -22
  272. data/lib/couchbase/bucket.rb +46 -31
  273. data/lib/couchbase/cluster.rb +146 -61
  274. data/lib/couchbase/collection.rb +257 -186
  275. data/lib/couchbase/datastructures/couchbase_list.rb +82 -50
  276. data/lib/couchbase/datastructures/couchbase_map.rb +87 -50
  277. data/lib/couchbase/datastructures/couchbase_queue.rb +65 -38
  278. data/lib/couchbase/datastructures/couchbase_set.rb +58 -41
  279. data/lib/couchbase/deprecations.rb +1 -1
  280. data/lib/couchbase/diagnostics.rb +8 -8
  281. data/lib/couchbase/errors.rb +7 -1
  282. data/lib/couchbase/json_transcoder.rb +1 -1
  283. data/lib/couchbase/management/analytics_index_manager.rb +90 -59
  284. data/lib/couchbase/management/bucket_manager.rb +73 -45
  285. data/lib/couchbase/management/collection_manager.rb +86 -43
  286. data/lib/couchbase/management/collection_query_index_manager.rb +56 -33
  287. data/lib/couchbase/management/query_index_manager.rb +88 -36
  288. data/lib/couchbase/management/scope_search_index_manager.rb +119 -52
  289. data/lib/couchbase/management/search_index_manager.rb +401 -178
  290. data/lib/couchbase/management/user_manager.rb +343 -174
  291. data/lib/couchbase/management/view_index_manager.rb +166 -73
  292. data/lib/couchbase/metrics/logging_meter.rb +108 -0
  293. data/lib/couchbase/metrics/logging_value_recorder.rb +50 -0
  294. data/lib/couchbase/metrics/meter.rb +27 -0
  295. data/lib/couchbase/metrics/noop_meter.rb +30 -0
  296. data/lib/couchbase/metrics/noop_value_recorder.rb +27 -0
  297. data/lib/couchbase/metrics/value_recorder.rb +25 -0
  298. data/lib/couchbase/options.rb +71 -5
  299. data/lib/couchbase/protostellar/client.rb +0 -2
  300. data/lib/couchbase/protostellar/cluster.rb +7 -0
  301. data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_pb.rb +54 -0
  302. data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_services_pb.rb +51 -0
  303. data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_pb.rb +5 -24
  304. data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_services_pb.rb +16 -0
  305. data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_pb.rb +5 -24
  306. data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_services_pb.rb +16 -0
  307. data/lib/couchbase/protostellar/generated/admin/query/v1/query_pb.rb +5 -24
  308. data/lib/couchbase/protostellar/generated/admin/query/v1/query_services_pb.rb +18 -0
  309. data/lib/couchbase/protostellar/generated/admin/search/v1/search_pb.rb +2 -23
  310. data/lib/couchbase/protostellar/generated/admin/search/v1/search_services_pb.rb +23 -0
  311. data/lib/couchbase/protostellar/generated/analytics/v1/analytics_pb.rb +4 -25
  312. data/lib/couchbase/protostellar/generated/analytics/v1/analytics_services_pb.rb +10 -0
  313. data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_pb.rb +6 -25
  314. data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_services_pb.rb +18 -0
  315. data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_pb.rb +46 -0
  316. data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_services_pb.rb +56 -0
  317. data/lib/couchbase/protostellar/generated/kv/v1/kv_pb.rb +3 -26
  318. data/lib/couchbase/protostellar/generated/kv/v1/kv_services_pb.rb +47 -0
  319. data/lib/couchbase/protostellar/generated/query/v1/query_pb.rb +4 -26
  320. data/lib/couchbase/protostellar/generated/query/v1/query_services_pb.rb +10 -0
  321. data/lib/couchbase/protostellar/generated/routing/v2/routing_pb.rb +26 -0
  322. data/lib/couchbase/protostellar/generated/routing/v2/routing_services_pb.rb +43 -0
  323. data/lib/couchbase/protostellar/generated/search/v1/search_pb.rb +5 -26
  324. data/lib/couchbase/protostellar/generated/search/v1/search_services_pb.rb +11 -0
  325. data/lib/couchbase/protostellar/generated/transactions/v1/transactions_pb.rb +2 -23
  326. data/lib/couchbase/protostellar/generated/transactions/v1/transactions_services_pb.rb +30 -0
  327. data/lib/couchbase/protostellar/generated/view/v1/view_pb.rb +2 -23
  328. data/lib/couchbase/protostellar/generated/view/v1/view_services_pb.rb +9 -0
  329. data/lib/couchbase/protostellar/request_generator/admin/collection.rb +4 -2
  330. data/lib/couchbase/protostellar/request_generator/admin/query.rb +2 -0
  331. data/lib/couchbase/protostellar/request_generator/kv.rb +1 -1
  332. data/lib/couchbase/protostellar/scope.rb +4 -0
  333. data/lib/couchbase/scope.rb +62 -48
  334. data/lib/couchbase/search_options.rb +18 -18
  335. data/lib/couchbase/tracing/noop_span.rb +29 -0
  336. data/lib/couchbase/tracing/noop_tracer.rb +29 -0
  337. data/lib/couchbase/tracing/request_span.rb +34 -0
  338. data/lib/couchbase/tracing/request_tracer.rb +28 -0
  339. data/lib/couchbase/tracing/threshold_logging_span.rb +112 -0
  340. data/lib/couchbase/tracing/threshold_logging_tracer.rb +231 -0
  341. data/lib/couchbase/utils/hdr_histogram.rb +55 -0
  342. data/lib/couchbase/utils/observability.rb +263 -0
  343. data/lib/couchbase/utils/observability_constants.rb +200 -0
  344. data/lib/couchbase/utils/stdlib_logger_adapter.rb +1 -3
  345. data/lib/couchbase/version.rb +1 -1
  346. data/lib/couchbase.rb +2 -2
  347. metadata +72 -8
  348. data/lib/couchbase/protostellar/generated/routing/v1/routing_pb.rb +0 -52
  349. data/lib/couchbase/protostellar/generated/routing/v1/routing_services_pb.rb +0 -30
@@ -19,8 +19,14 @@
19
19
 
20
20
  #include <couchbase/error_codes.hxx>
21
21
 
22
- #include <mutex>
22
+ #include "core/metrics/constants.hxx"
23
+ #include "core/tracing/constants.hxx"
24
+
25
+ #include <map>
26
+ #include <memory>
27
+ #include <string>
23
28
  #include <system_error>
29
+ #include <utility>
24
30
 
25
31
  namespace couchbase::core::metrics
26
32
  {
@@ -57,32 +63,10 @@ extract_error_name(std::error_code ec) -> std::string
57
63
  }
58
64
 
59
65
  auto
60
- service_to_string(service_type s) -> std::string
61
- {
62
- switch (s) {
63
- case service_type::analytics:
64
- return "analytics";
65
- case service_type::search:
66
- return "search";
67
- case service_type::key_value:
68
- return "kv";
69
- case service_type::management:
70
- return "management";
71
- case service_type::eventing:
72
- return "eventing";
73
- case service_type::query:
74
- return "query";
75
- case service_type::view:
76
- return "views";
77
- }
78
- return {};
79
- }
80
-
81
- auto
82
- get_standardized_outcome(std::error_code ec) -> std::string
66
+ get_standardized_error_type(std::error_code ec) -> std::string
83
67
  {
84
68
  if (!ec) {
85
- return "Success";
69
+ return {};
86
70
  }
87
71
 
88
72
  // SDK-specific errors
@@ -95,39 +79,62 @@ get_standardized_outcome(std::error_code ec) -> std::string
95
79
  return "CryptoError";
96
80
  }
97
81
 
98
- return snake_case_to_camel_case(extract_error_name(ec));
82
+ static const std::array<const std::error_category*, 12> cb_categories = {
83
+ &impl::common_category(), &impl::key_value_category(),
84
+ &impl::query_category(), &impl::analytics_category(),
85
+ &impl::search_category(), &impl::view_category(),
86
+ &impl::management_category(), &impl::field_level_encryption_category(),
87
+ &impl::network_category(), &impl::streaming_json_lexer_category(),
88
+ &impl::transaction_category(), &impl::transaction_op_category(),
89
+ };
90
+
91
+ if (std::any_of(
92
+ cb_categories.begin(), cb_categories.end(), [&ec](const std::error_category* cat) -> bool {
93
+ return &ec.category() == cat;
94
+ })) {
95
+ return snake_case_to_camel_case(extract_error_name(ec));
96
+ }
97
+
98
+ return "_OTHER";
99
99
  }
100
100
  } // namespace
101
101
 
102
102
  auto
103
103
  metric_attributes::encode() const -> std::map<std::string, std::string>
104
104
  {
105
- std::map<std::string, std::string> tags = { { "db.couchbase.service",
106
- service_to_string(service) },
107
- { "db.operation", operation },
108
- { "outcome", get_standardized_outcome(ec) } };
105
+ std::map<std::string, std::string> tags = {
106
+ { tracing::attributes::reserved::target_unit, "s" },
107
+ { tracing::attributes::common::system, "couchbase" },
108
+ { tracing::attributes::op::service, service },
109
+ { tracing::attributes::op::operation_name, operation },
110
+ };
109
111
 
110
112
  if (internal.cluster_name.has_value()) {
111
- tags.emplace("db.couchbase.cluster_name", internal.cluster_name.value());
113
+ tags.emplace(tracing::attributes::common::cluster_name, internal.cluster_name.value());
112
114
  }
113
115
  if (internal.cluster_uuid.has_value()) {
114
- tags.emplace("db.couchbase.cluster_uuid", internal.cluster_uuid.value());
116
+ tags.emplace(tracing::attributes::common::cluster_uuid, internal.cluster_uuid.value());
115
117
  }
116
118
  if (bucket_name) {
117
- tags.emplace("db.name", bucket_name.value());
119
+ tags.emplace(tracing::attributes::op::bucket_name, bucket_name.value());
118
120
  }
119
121
  if (scope_name) {
120
- tags.emplace("db.couchbase.scope", scope_name.value());
122
+ tags.emplace(tracing::attributes::op::scope_name, scope_name.value());
121
123
  }
122
124
  if (collection_name) {
123
- tags.emplace("db.couchbase.collection", collection_name.value());
125
+ tags.emplace(tracing::attributes::op::collection_name, collection_name.value());
126
+ }
127
+ if (ec) {
128
+ tags.emplace(tracing::attributes::op::error_type, get_standardized_error_type(ec));
124
129
  }
125
130
 
126
131
  return tags;
127
132
  }
128
133
 
129
- meter_wrapper::meter_wrapper(std::shared_ptr<couchbase::metrics::meter> meter)
134
+ meter_wrapper::meter_wrapper(std::shared_ptr<couchbase::metrics::meter> meter,
135
+ std::shared_ptr<cluster_label_listener> label_listener)
130
136
  : meter_{ std::move(meter) }
137
+ , cluster_label_listener_{ std::move(label_listener) }
131
138
  {
132
139
  }
133
140
 
@@ -143,46 +150,41 @@ meter_wrapper::stop()
143
150
  meter_->stop();
144
151
  }
145
152
 
153
+ void
154
+ meter_wrapper::record_value(const std::map<std::string, std::string>& raw_attrs,
155
+ std::chrono::microseconds duration)
156
+ {
157
+ meter_->get_value_recorder(operation_meter_name, raw_attrs)->record_value(duration.count());
158
+ }
159
+
146
160
  void
147
161
  meter_wrapper::record_value(metric_attributes attrs,
148
162
  std::chrono::steady_clock::time_point start_time)
149
163
  {
150
- static const std::string meter_name{ "db.couchbase.operations" };
151
-
152
- {
153
- const std::shared_lock lock{ cluster_labels_mutex_ };
154
-
155
- if (cluster_name_) {
156
- attrs.internal.cluster_name = cluster_name_;
157
- }
158
- if (cluster_uuid_) {
159
- attrs.internal.cluster_uuid = cluster_uuid_;
160
- }
164
+ auto [cluster_name, cluster_uuid] = cluster_label_listener_->cluster_labels();
165
+ if (cluster_name) {
166
+ attrs.internal.cluster_name = cluster_name;
167
+ }
168
+ if (cluster_uuid) {
169
+ attrs.internal.cluster_uuid = cluster_uuid;
161
170
  }
162
171
 
163
- auto tags = attrs.encode();
164
- meter_->get_value_recorder(meter_name, tags)
165
- ->record_value(std::chrono::duration_cast<std::chrono::microseconds>(
166
- std::chrono::steady_clock::now() - start_time)
167
- .count());
172
+ record_value(attrs.encode(),
173
+ std::chrono::duration_cast<std::chrono::microseconds>(
174
+ std::chrono::steady_clock::now() - start_time));
168
175
  }
169
176
 
170
- void
171
- meter_wrapper::update_config(topology::configuration config)
177
+ auto
178
+ meter_wrapper::wrapped() -> std::shared_ptr<couchbase::metrics::meter>
172
179
  {
173
- const std::scoped_lock<std::shared_mutex> lock{ cluster_labels_mutex_ };
174
- if (config.cluster_uuid.has_value()) {
175
- cluster_uuid_ = config.cluster_uuid;
176
- }
177
- if (config.cluster_name.has_value()) {
178
- cluster_name_ = config.cluster_name;
179
- }
180
+ return meter_;
180
181
  }
181
182
 
182
183
  auto
183
- meter_wrapper::create(std::shared_ptr<couchbase::metrics::meter> meter)
184
+ meter_wrapper::create(std::shared_ptr<couchbase::metrics::meter> meter,
185
+ std::shared_ptr<cluster_label_listener> label_listener)
184
186
  -> std::shared_ptr<meter_wrapper>
185
187
  {
186
- return std::make_shared<meter_wrapper>(std::move(meter));
188
+ return std::make_shared<meter_wrapper>(std::move(meter), std::move(label_listener));
187
189
  }
188
190
  } // namespace couchbase::core::metrics
@@ -26,14 +26,15 @@
26
26
  #include <chrono>
27
27
  #include <map>
28
28
  #include <optional>
29
- #include <shared_mutex>
30
29
  #include <string>
31
30
  #include <system_error>
32
31
 
32
+ #include "core/cluster_label_listener.hxx"
33
+
33
34
  namespace couchbase::core::metrics
34
35
  {
35
36
  struct metric_attributes {
36
- couchbase::core::service_type service;
37
+ std::string service;
37
38
  std::string operation;
38
39
  std::error_code ec;
39
40
  std::optional<std::string> bucket_name{};
@@ -48,26 +49,27 @@ struct metric_attributes {
48
49
  [[nodiscard]] auto encode() const -> std::map<std::string, std::string>;
49
50
  };
50
51
 
51
- class meter_wrapper : public config_listener
52
+ class meter_wrapper
52
53
  {
53
54
  public:
54
- explicit meter_wrapper(std::shared_ptr<couchbase::metrics::meter> meter);
55
+ explicit meter_wrapper(std::shared_ptr<couchbase::metrics::meter> meter,
56
+ std::shared_ptr<cluster_label_listener> label_listener);
55
57
 
56
58
  void start();
57
59
  void stop();
58
60
 
59
61
  void record_value(metric_attributes attrs, std::chrono::steady_clock::time_point start_time);
62
+ void record_value(const std::map<std::string, std::string>& raw_attrs,
63
+ std::chrono::microseconds duration);
60
64
 
61
- void update_config(topology::configuration config) override;
65
+ [[nodiscard]] auto wrapped() -> std::shared_ptr<couchbase::metrics::meter>;
62
66
 
63
- [[nodiscard]] static auto create(std::shared_ptr<couchbase::metrics::meter> meter)
67
+ [[nodiscard]] static auto create(std::shared_ptr<couchbase::metrics::meter> meter,
68
+ std::shared_ptr<cluster_label_listener> label_listener)
64
69
  -> std::shared_ptr<meter_wrapper>;
65
70
 
66
71
  private:
67
72
  std::shared_ptr<couchbase::metrics::meter> meter_;
68
-
69
- std::optional<std::string> cluster_name_{};
70
- std::optional<std::string> cluster_uuid_{};
71
- std::shared_mutex cluster_labels_mutex_{};
73
+ std::shared_ptr<cluster_label_listener> cluster_label_listener_;
72
74
  };
73
75
  } // namespace couchbase::core::metrics
@@ -114,11 +114,6 @@ struct analytics_request {
114
114
  } // namespace couchbase::core::operations
115
115
  namespace couchbase::core::io::http_traits
116
116
  {
117
- template<>
118
- struct supports_parent_span<couchbase::core::operations::analytics_request>
119
- : public std::true_type {
120
- };
121
-
122
117
  template<>
123
118
  struct supports_readonly<couchbase::core::operations::analytics_request> : public std::true_type {
124
119
  };
@@ -76,8 +76,4 @@ namespace couchbase::core::io::mcbp_traits
76
76
  template<>
77
77
  struct supports_durability<couchbase::core::operations::append_request> : public std::true_type {
78
78
  };
79
-
80
- template<>
81
- struct supports_parent_span<couchbase::core::operations::append_request> : public std::true_type {
82
- };
83
79
  } // namespace couchbase::core::io::mcbp_traits
@@ -79,9 +79,4 @@ namespace couchbase::core::io::mcbp_traits
79
79
  template<>
80
80
  struct supports_durability<couchbase::core::operations::decrement_request> : public std::true_type {
81
81
  };
82
-
83
- template<>
84
- struct supports_parent_span<couchbase::core::operations::decrement_request>
85
- : public std::true_type {
86
- };
87
82
  } // namespace couchbase::core::io::mcbp_traits
@@ -67,10 +67,3 @@ struct exists_request {
67
67
  };
68
68
 
69
69
  } // namespace couchbase::core::operations
70
-
71
- namespace couchbase::core::io::mcbp_traits
72
- {
73
- template<>
74
- struct supports_parent_span<couchbase::core::operations::exists_request> : public std::true_type {
75
- };
76
- } // namespace couchbase::core::io::mcbp_traits
@@ -57,10 +57,3 @@ struct get_request {
57
57
  const encoded_response_type& encoded) const -> get_response;
58
58
  };
59
59
  } // namespace couchbase::core::operations
60
-
61
- namespace couchbase::core::io::mcbp_traits
62
- {
63
- template<>
64
- struct supports_parent_span<couchbase::core::operations::get_request> : public std::true_type {
65
- };
66
- } // namespace couchbase::core::io::mcbp_traits
@@ -17,14 +17,18 @@
17
17
 
18
18
  #pragma once
19
19
 
20
+ #include <couchbase/error_codes.hxx>
21
+ #include <couchbase/node_id.hxx>
22
+
20
23
  #include "core/error_context/key_value.hxx"
21
24
  #include "core/impl/get_replica.hxx"
22
25
  #include "core/impl/replica_utils.hxx"
23
26
  #include "core/logger/logger.hxx"
24
27
  #include "core/operations/document_get.hxx"
25
28
  #include "core/operations/operation_traits.hxx"
29
+ #include "core/public_fwd.hxx"
30
+ #include "core/tracing/constants.hxx"
26
31
  #include "core/utils/movable_function.hxx"
27
- #include "couchbase/error_codes.hxx"
28
32
 
29
33
  #include <memory>
30
34
  #include <mutex>
@@ -37,6 +41,7 @@ struct get_all_replicas_response {
37
41
  couchbase::cas cas{};
38
42
  std::uint32_t flags{};
39
43
  bool replica{ true };
44
+ couchbase::node_id dispatched_to_node_id{};
40
45
  };
41
46
  key_value_error_context ctx{};
42
47
  std::vector<entry> entries{};
@@ -54,6 +59,7 @@ struct get_all_replicas_request {
54
59
  core::document_id id;
55
60
  std::optional<std::chrono::milliseconds> timeout{};
56
61
  couchbase::read_preference read_preference{ couchbase::read_preference::no_preference };
62
+ std::shared_ptr<couchbase::tracing::request_span> parent_span{ nullptr };
57
63
 
58
64
  template<typename Core, typename Handler>
59
65
  void execute(Core core, Handler handler)
@@ -64,6 +70,7 @@ struct get_all_replicas_request {
64
70
  id = id,
65
71
  timeout = timeout,
66
72
  read_preference = read_preference,
73
+ parent_span = std::move(parent_span),
67
74
  h = std::forward<Handler>(handler)](
68
75
  std::error_code ec, std::shared_ptr<topology::configuration> config) mutable {
69
76
  if (ec) {
@@ -104,11 +111,40 @@ struct get_all_replicas_request {
104
111
  auto ctx = std::make_shared<replica_context>(std::move(h), nodes.size());
105
112
 
106
113
  for (const auto& node : nodes) {
114
+ auto subop_span = core->tracer()->create_span(
115
+ node.is_replica ? tracing::operation::mcbp_get_replica : tracing::operation::mcbp_get,
116
+ parent_span);
117
+
118
+ if (subop_span->uses_tags()) {
119
+ subop_span->add_tag(tracing::attributes::op::service, tracing::service::key_value);
120
+ subop_span->add_tag(tracing::attributes::op::operation_name,
121
+ node.is_replica ? tracing::operation::mcbp_get_replica
122
+ : tracing::operation::mcbp_get);
123
+ subop_span->add_tag(tracing::attributes::op::bucket_name, id.bucket());
124
+ subop_span->add_tag(tracing::attributes::op::scope_name, id.scope());
125
+ subop_span->add_tag(tracing::attributes::op::collection_name, id.collection());
126
+ }
127
+
107
128
  if (node.is_replica) {
108
129
  document_id replica_id{ id };
109
130
  replica_id.node_index(node.index);
110
131
  core->execute(
111
- impl::get_replica_request{ std::move(replica_id), timeout }, [ctx](auto&& resp) {
132
+ impl::get_replica_request{
133
+ std::move(replica_id),
134
+ timeout,
135
+ {},
136
+ {},
137
+ {},
138
+ subop_span,
139
+ },
140
+ [ctx, subop_span](auto&& resp) {
141
+ {
142
+ if (subop_span->uses_tags()) {
143
+ subop_span->add_tag(tracing::attributes::op::retry_count,
144
+ resp.ctx.retry_attempts());
145
+ }
146
+ subop_span->end();
147
+ }
112
148
  handler_type local_handler{};
113
149
  {
114
150
  std::scoped_lock lock(ctx->mutex_);
@@ -122,8 +158,12 @@ struct get_all_replicas_request {
122
158
  return;
123
159
  }
124
160
  } else {
125
- ctx->result_.emplace_back(get_all_replicas_response::entry{
126
- std::move(resp.value), resp.cas, resp.flags, true /* replica */ });
161
+ ctx->result_.emplace_back(
162
+ get_all_replicas_response::entry{ std::move(resp.value),
163
+ resp.cas,
164
+ resp.flags,
165
+ true /* replica */,
166
+ resp.ctx.last_dispatched_to_node_id() });
127
167
  }
128
168
  if (ctx->expected_responses_ == 0) {
129
169
  ctx->done_ = true;
@@ -139,36 +179,56 @@ struct get_all_replicas_request {
139
179
  }
140
180
  });
141
181
  } else {
142
- core->execute(get_request{ document_id{ id }, {}, {}, timeout }, [ctx](auto&& resp) {
143
- handler_type local_handler{};
144
- {
145
- std::scoped_lock lock(ctx->mutex_);
146
- if (ctx->done_) {
147
- return;
182
+ core->execute(
183
+ get_request{
184
+ document_id{ id },
185
+ {},
186
+ {},
187
+ timeout,
188
+ {},
189
+ subop_span,
190
+ },
191
+ [ctx, subop_span](auto&& resp) {
192
+ {
193
+ if (subop_span->uses_tags()) {
194
+ subop_span->add_tag(tracing::attributes::op::retry_count,
195
+ resp.ctx.retry_attempts());
196
+ }
197
+ subop_span->end();
148
198
  }
149
- --ctx->expected_responses_;
150
- if (resp.ctx.ec()) {
151
- if (ctx->expected_responses_ > 0) {
152
- // just ignore the response
199
+ handler_type local_handler{};
200
+ {
201
+ std::scoped_lock lock(ctx->mutex_);
202
+ if (ctx->done_) {
153
203
  return;
154
204
  }
155
- } else {
156
- ctx->result_.emplace_back(get_all_replicas_response::entry{
157
- std::move(resp.value), resp.cas, resp.flags, false /* active */ });
158
- }
159
- if (ctx->expected_responses_ == 0) {
160
- ctx->done_ = true;
161
- std::swap(local_handler, ctx->handler_);
205
+ --ctx->expected_responses_;
206
+ if (resp.ctx.ec()) {
207
+ if (ctx->expected_responses_ > 0) {
208
+ // just ignore the response
209
+ return;
210
+ }
211
+ } else {
212
+ ctx->result_.emplace_back(
213
+ get_all_replicas_response::entry{ std::move(resp.value),
214
+ resp.cas,
215
+ resp.flags,
216
+ false /* active */,
217
+ resp.ctx.last_dispatched_to_node_id() });
218
+ }
219
+ if (ctx->expected_responses_ == 0) {
220
+ ctx->done_ = true;
221
+ std::swap(local_handler, ctx->handler_);
222
+ }
162
223
  }
163
- }
164
- if (local_handler) {
165
- if (ctx->result_.empty()) {
166
- // Return an error only when we have no results from any replica.
167
- return local_handler({ std::move(resp.ctx), {} });
224
+ if (local_handler) {
225
+ if (ctx->result_.empty()) {
226
+ // Return an error only when we have no results from any replica.
227
+ return local_handler({ std::move(resp.ctx), {} });
228
+ }
229
+ return local_handler({ {}, std::move(ctx->result_) });
168
230
  }
169
- return local_handler({ {}, std::move(ctx->result_) });
170
- }
171
- });
231
+ });
172
232
  }
173
233
  }
174
234
  });
@@ -58,13 +58,4 @@ struct get_and_lock_request {
58
58
  const encoded_response_type& encoded) const
59
59
  -> get_and_lock_response;
60
60
  };
61
-
62
61
  } // namespace couchbase::core::operations
63
-
64
- namespace couchbase::core::io::mcbp_traits
65
- {
66
- template<>
67
- struct supports_parent_span<couchbase::core::operations::get_and_lock_request>
68
- : public std::true_type {
69
- };
70
- } // namespace couchbase::core::io::mcbp_traits
@@ -59,13 +59,4 @@ struct get_and_touch_request {
59
59
  const encoded_response_type& encoded) const
60
60
  -> get_and_touch_response;
61
61
  };
62
-
63
62
  } // namespace couchbase::core::operations
64
-
65
- namespace couchbase::core::io::mcbp_traits
66
- {
67
- template<>
68
- struct supports_parent_span<couchbase::core::operations::get_and_touch_request>
69
- : public std::true_type {
70
- };
71
- } // namespace couchbase::core::io::mcbp_traits
@@ -20,6 +20,7 @@
20
20
  #include "core/error_context/key_value.hxx"
21
21
  #include "core/impl/get_replica.hxx"
22
22
  #include "core/impl/replica_utils.hxx"
23
+ #include "core/impl/with_cancellation.hxx"
23
24
  #include "core/operations/document_get.hxx"
24
25
  #include "core/operations/operation_traits.hxx"
25
26
  #include "core/utils/movable_function.hxx"
@@ -51,6 +52,7 @@ struct get_any_replica_request {
51
52
  core::document_id id;
52
53
  std::optional<std::chrono::milliseconds> timeout{};
53
54
  couchbase::read_preference read_preference{ couchbase::read_preference::no_preference };
55
+ std::shared_ptr<couchbase::tracing::request_span> parent_span{ nullptr };
54
56
 
55
57
  template<typename Core, typename Handler>
56
58
  void execute(Core core, Handler handler)
@@ -61,6 +63,7 @@ struct get_any_replica_request {
61
63
  id = id,
62
64
  timeout = timeout,
63
65
  read_preference = read_preference,
66
+ parent_span = std::move(parent_span),
64
67
  h = std::forward<Handler>(handler)](
65
68
  std::error_code ec, std::shared_ptr<topology::configuration> config) mutable {
66
69
  const auto [e, origin] = core->origin();
@@ -91,20 +94,71 @@ struct get_any_replica_request {
91
94
  {
92
95
  }
93
96
 
97
+ void add_cancellation_token(std::shared_ptr<impl::cancellation_token> token)
98
+ {
99
+ std::scoped_lock<std::mutex> lock(cancel_tokens_mutex_);
100
+ cancel_tokens_.emplace_back(std::move(token));
101
+ }
102
+
103
+ auto get_cancellation_tokens() -> std::vector<std::shared_ptr<impl::cancellation_token>>
104
+ {
105
+ std::vector<std::shared_ptr<impl::cancellation_token>> tokens{};
106
+ {
107
+ std::scoped_lock<std::mutex> lock(cancel_tokens_mutex_);
108
+ std::swap(tokens, cancel_tokens_);
109
+ }
110
+ return tokens;
111
+ }
112
+
94
113
  handler_type handler_;
95
114
  std::size_t expected_responses_;
96
115
  bool done_{ false };
97
116
  std::mutex mutex_{};
117
+ std::vector<std::shared_ptr<impl::cancellation_token>> cancel_tokens_{};
118
+ std::mutex cancel_tokens_mutex_{};
98
119
  };
99
120
  auto ctx = std::make_shared<replica_context>(std::move(h), nodes.size());
100
121
 
101
122
  for (const auto& node : nodes) {
123
+ auto subop_span = core->tracer()->create_span(
124
+ node.is_replica ? tracing::operation::mcbp_get_replica : tracing::operation::mcbp_get,
125
+ parent_span);
126
+
127
+ if (subop_span->uses_tags()) {
128
+ subop_span->add_tag(tracing::attributes::op::service, tracing::service::key_value);
129
+ subop_span->add_tag(tracing::attributes::op::operation_name,
130
+ node.is_replica ? tracing::operation::mcbp_get_replica
131
+ : tracing::operation::mcbp_get);
132
+ subop_span->add_tag(tracing::attributes::op::bucket_name, id.bucket());
133
+ subop_span->add_tag(tracing::attributes::op::scope_name, id.scope());
134
+ subop_span->add_tag(tracing::attributes::op::collection_name, id.collection());
135
+ }
136
+
102
137
  if (node.is_replica) {
103
138
  document_id replica_id{ id };
104
139
  replica_id.node_index(node.index);
140
+ impl::with_cancellation<impl::get_replica_request> req{
141
+ {
142
+ std::move(replica_id),
143
+ timeout,
144
+ {},
145
+ {},
146
+ {},
147
+ subop_span,
148
+ },
149
+ };
150
+ ctx->add_cancellation_token(req.cancel_token);
105
151
  core->execute(
106
- impl::get_replica_request{ std::move(replica_id), timeout }, [ctx](auto&& resp) {
152
+ std::move(req), [ctx, subop_span](auto&& resp) {
153
+ {
154
+ if (subop_span->uses_tags()) {
155
+ subop_span->add_tag(tracing::attributes::op::retry_count,
156
+ resp.ctx.retry_attempts());
157
+ }
158
+ subop_span->end();
159
+ }
107
160
  handler_type local_handler;
161
+ std::vector<std::shared_ptr<impl::cancellation_token>> cancel_tokens;
108
162
  {
109
163
  std::scoped_lock lock(ctx->mutex_);
110
164
  if (ctx->done_) {
@@ -121,6 +175,10 @@ struct get_any_replica_request {
121
175
  }
122
176
  ctx->done_ = true;
123
177
  std::swap(local_handler, ctx->handler_);
178
+ cancel_tokens = ctx->get_cancellation_tokens();
179
+ }
180
+ for (const auto& token : cancel_tokens) {
181
+ token->cancel();
124
182
  }
125
183
  if (local_handler) {
126
184
  return local_handler(response_type{
@@ -128,8 +186,27 @@ struct get_any_replica_request {
128
186
  }
129
187
  });
130
188
  } else {
131
- core->execute(get_request{ id, {}, {}, timeout }, [ctx](auto&& resp) {
189
+ impl::with_cancellation<get_request> req{
190
+ {
191
+ id,
192
+ {},
193
+ {},
194
+ timeout,
195
+ {},
196
+ subop_span,
197
+ },
198
+ };
199
+ ctx->add_cancellation_token(req.cancel_token);
200
+ core->execute(std::move(req), [ctx, subop_span](auto&& resp) {
201
+ {
202
+ if (subop_span->uses_tags()) {
203
+ subop_span->add_tag(tracing::attributes::op::retry_count,
204
+ resp.ctx.retry_attempts());
205
+ }
206
+ subop_span->end();
207
+ }
132
208
  handler_type local_handler{};
209
+ std::vector<std::shared_ptr<impl::cancellation_token>> cancel_tokens;
133
210
  {
134
211
  std::scoped_lock lock(ctx->mutex_);
135
212
  if (ctx->done_) {
@@ -146,6 +223,10 @@ struct get_any_replica_request {
146
223
  }
147
224
  ctx->done_ = true;
148
225
  std::swap(local_handler, ctx->handler_);
226
+ cancel_tokens = ctx->get_cancellation_tokens();
227
+ }
228
+ for (const auto& token : cancel_tokens) {
229
+ token->cancel();
149
230
  }
150
231
  if (local_handler) {
151
232
  return local_handler(response_type{