couchbase 3.7.0 → 3.8.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 (286) 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 -93
  6. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  7. data/ext/couchbase/CMakeLists.txt +24 -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/free_form_http_request.hxx +0 -2
  33. data/ext/couchbase/core/http_component.cxx +12 -48
  34. data/ext/couchbase/core/impl/analytics.cxx +3 -2
  35. data/ext/couchbase/core/impl/analytics.hxx +2 -1
  36. data/ext/couchbase/core/impl/analytics_index_manager.cxx +249 -137
  37. data/ext/couchbase/core/impl/binary_collection.cxx +134 -58
  38. data/ext/couchbase/core/impl/bucket_manager.cxx +87 -35
  39. data/ext/couchbase/core/impl/collection.cxx +560 -245
  40. data/ext/couchbase/core/impl/collection_manager.cxx +89 -49
  41. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +4 -4
  42. data/ext/couchbase/core/impl/error.cxx +20 -13
  43. data/ext/couchbase/core/impl/error.hxx +15 -10
  44. data/ext/couchbase/core/impl/get_all_replicas.hxx +1 -1
  45. data/ext/couchbase/core/impl/get_any_replica.hxx +2 -1
  46. data/ext/couchbase/core/impl/get_replica.hxx +2 -0
  47. data/ext/couchbase/core/impl/lookup_in_replica.hxx +1 -1
  48. data/ext/couchbase/core/impl/observability_recorder.cxx +161 -0
  49. data/ext/couchbase/core/impl/observability_recorder.hxx +77 -0
  50. data/ext/couchbase/core/impl/observe_seqno.hxx +2 -0
  51. data/ext/couchbase/core/impl/public_bucket.cxx +31 -7
  52. data/ext/couchbase/core/impl/public_cluster.cxx +107 -19
  53. data/ext/couchbase/core/impl/query.cxx +6 -3
  54. data/ext/couchbase/core/impl/query.hxx +3 -1
  55. data/ext/couchbase/core/impl/query_index_manager.cxx +267 -102
  56. data/ext/couchbase/core/impl/scope.cxx +53 -11
  57. data/ext/couchbase/core/impl/search.cxx +8 -4
  58. data/ext/couchbase/core/impl/search.hxx +6 -2
  59. data/ext/couchbase/core/impl/search_index_manager.cxx +131 -41
  60. data/ext/couchbase/core/impl/with_cancellation.hxx +75 -0
  61. data/ext/couchbase/core/io/config_tracker.cxx +9 -9
  62. data/ext/couchbase/core/io/config_tracker.hxx +2 -1
  63. data/ext/couchbase/core/io/http_command.hxx +98 -49
  64. data/ext/couchbase/core/io/http_context.hxx +2 -0
  65. data/ext/couchbase/core/io/http_session.cxx +23 -10
  66. data/ext/couchbase/core/io/http_session.hxx +17 -9
  67. data/ext/couchbase/core/io/http_session_manager.hxx +163 -228
  68. data/ext/couchbase/core/io/http_traits.hxx +0 -7
  69. data/ext/couchbase/core/io/mcbp_command.hxx +123 -44
  70. data/ext/couchbase/core/io/mcbp_session.cxx +251 -26
  71. data/ext/couchbase/core/io/mcbp_session.hxx +9 -1
  72. data/ext/couchbase/core/io/mcbp_traits.hxx +0 -8
  73. data/ext/couchbase/core/io/streams.cxx +3 -3
  74. data/ext/couchbase/core/io/streams.hxx +3 -2
  75. data/ext/couchbase/core/meta/features.hxx +15 -0
  76. data/ext/couchbase/core/meta/version.cxx +13 -0
  77. data/ext/couchbase/core/meta/version.hxx +3 -0
  78. data/ext/couchbase/core/metrics/constants.hxx +23 -0
  79. data/ext/couchbase/core/metrics/logging_meter.cxx +5 -5
  80. data/ext/couchbase/core/metrics/meter_wrapper.cxx +65 -63
  81. data/ext/couchbase/core/metrics/meter_wrapper.hxx +12 -10
  82. data/ext/couchbase/core/operations/document_analytics.hxx +0 -5
  83. data/ext/couchbase/core/operations/document_append.hxx +0 -4
  84. data/ext/couchbase/core/operations/document_decrement.hxx +0 -5
  85. data/ext/couchbase/core/operations/document_exists.hxx +0 -7
  86. data/ext/couchbase/core/operations/document_get.hxx +0 -7
  87. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +77 -27
  88. data/ext/couchbase/core/operations/document_get_and_lock.hxx +0 -9
  89. data/ext/couchbase/core/operations/document_get_and_touch.hxx +0 -9
  90. data/ext/couchbase/core/operations/document_get_any_replica.hxx +83 -2
  91. data/ext/couchbase/core/operations/document_get_projected.hxx +0 -9
  92. data/ext/couchbase/core/operations/document_increment.hxx +0 -5
  93. data/ext/couchbase/core/operations/document_insert.hxx +0 -4
  94. data/ext/couchbase/core/operations/document_lookup_in.hxx +0 -9
  95. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +46 -4
  96. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +121 -43
  97. data/ext/couchbase/core/operations/document_mutate_in.hxx +0 -5
  98. data/ext/couchbase/core/operations/document_prepend.hxx +0 -4
  99. data/ext/couchbase/core/operations/document_query.hxx +0 -4
  100. data/ext/couchbase/core/operations/document_remove.hxx +0 -4
  101. data/ext/couchbase/core/operations/document_replace.hxx +0 -4
  102. data/ext/couchbase/core/operations/document_search.hxx +0 -7
  103. data/ext/couchbase/core/operations/document_touch.hxx +0 -7
  104. data/ext/couchbase/core/operations/document_unlock.hxx +0 -6
  105. data/ext/couchbase/core/operations/document_upsert.hxx +0 -4
  106. data/ext/couchbase/core/operations/document_view.cxx +2 -0
  107. data/ext/couchbase/core/operations/document_view.hxx +10 -13
  108. data/ext/couchbase/core/operations/http_noop.hxx +2 -0
  109. data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +2 -0
  110. data/ext/couchbase/core/operations/management/analytics_dataset_drop.hxx +2 -0
  111. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.hxx +2 -0
  112. data/ext/couchbase/core/operations/management/analytics_dataverse_create.hxx +2 -0
  113. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.hxx +2 -0
  114. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.hxx +2 -0
  115. data/ext/couchbase/core/operations/management/analytics_index_create.hxx +2 -0
  116. data/ext/couchbase/core/operations/management/analytics_index_drop.hxx +2 -0
  117. data/ext/couchbase/core/operations/management/analytics_index_get_all.hxx +2 -0
  118. data/ext/couchbase/core/operations/management/analytics_link_connect.hxx +2 -0
  119. data/ext/couchbase/core/operations/management/analytics_link_create.hxx +2 -0
  120. data/ext/couchbase/core/operations/management/analytics_link_disconnect.hxx +2 -0
  121. data/ext/couchbase/core/operations/management/analytics_link_drop.hxx +2 -0
  122. data/ext/couchbase/core/operations/management/analytics_link_get_all.hxx +2 -0
  123. data/ext/couchbase/core/operations/management/analytics_link_replace.hxx +2 -0
  124. data/ext/couchbase/core/operations/management/bucket_create.hxx +2 -0
  125. data/ext/couchbase/core/operations/management/bucket_describe.hxx +2 -0
  126. data/ext/couchbase/core/operations/management/bucket_drop.hxx +2 -0
  127. data/ext/couchbase/core/operations/management/bucket_flush.hxx +2 -0
  128. data/ext/couchbase/core/operations/management/bucket_get.hxx +2 -0
  129. data/ext/couchbase/core/operations/management/bucket_get_all.hxx +2 -0
  130. data/ext/couchbase/core/operations/management/bucket_update.hxx +2 -0
  131. data/ext/couchbase/core/operations/management/change_password.hxx +2 -0
  132. data/ext/couchbase/core/operations/management/cluster_describe.hxx +2 -0
  133. data/ext/couchbase/core/operations/management/cluster_developer_preview_enable.hxx +2 -0
  134. data/ext/couchbase/core/operations/management/collection_create.hxx +2 -0
  135. data/ext/couchbase/core/operations/management/collection_drop.hxx +2 -0
  136. data/ext/couchbase/core/operations/management/collection_update.hxx +2 -0
  137. data/ext/couchbase/core/operations/management/collections_manifest_get.hxx +2 -0
  138. data/ext/couchbase/core/operations/management/error_utils.cxx +4 -1
  139. data/ext/couchbase/core/operations/management/eventing_deploy_function.hxx +2 -0
  140. data/ext/couchbase/core/operations/management/eventing_drop_function.hxx +2 -0
  141. data/ext/couchbase/core/operations/management/eventing_get_all_functions.hxx +2 -0
  142. data/ext/couchbase/core/operations/management/eventing_get_function.hxx +2 -0
  143. data/ext/couchbase/core/operations/management/eventing_get_status.hxx +2 -0
  144. data/ext/couchbase/core/operations/management/eventing_pause_function.hxx +2 -0
  145. data/ext/couchbase/core/operations/management/eventing_resume_function.hxx +2 -0
  146. data/ext/couchbase/core/operations/management/eventing_undeploy_function.hxx +2 -0
  147. data/ext/couchbase/core/operations/management/eventing_upsert_function.hxx +2 -0
  148. data/ext/couchbase/core/operations/management/freeform.hxx +2 -0
  149. data/ext/couchbase/core/operations/management/group_drop.hxx +2 -0
  150. data/ext/couchbase/core/operations/management/group_get.hxx +2 -0
  151. data/ext/couchbase/core/operations/management/group_get_all.hxx +2 -0
  152. data/ext/couchbase/core/operations/management/group_upsert.hxx +2 -0
  153. data/ext/couchbase/core/operations/management/query_index_build.hxx +2 -0
  154. data/ext/couchbase/core/operations/management/query_index_build_deferred.hxx +68 -30
  155. data/ext/couchbase/core/operations/management/query_index_create.hxx +2 -0
  156. data/ext/couchbase/core/operations/management/query_index_drop.hxx +2 -0
  157. data/ext/couchbase/core/operations/management/query_index_get_all.hxx +4 -3
  158. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.hxx +2 -1
  159. data/ext/couchbase/core/operations/management/role_get_all.hxx +2 -0
  160. data/ext/couchbase/core/operations/management/scope_create.hxx +2 -0
  161. data/ext/couchbase/core/operations/management/scope_drop.hxx +2 -0
  162. data/ext/couchbase/core/operations/management/scope_get_all.hxx +2 -0
  163. data/ext/couchbase/core/operations/management/search_get_stats.hxx +2 -0
  164. data/ext/couchbase/core/operations/management/search_index_analyze_document.hxx +2 -0
  165. data/ext/couchbase/core/operations/management/search_index_control_ingest.hxx +2 -0
  166. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.hxx +2 -0
  167. data/ext/couchbase/core/operations/management/search_index_control_query.hxx +2 -0
  168. data/ext/couchbase/core/operations/management/search_index_drop.hxx +2 -0
  169. data/ext/couchbase/core/operations/management/search_index_get.hxx +2 -0
  170. data/ext/couchbase/core/operations/management/search_index_get_all.hxx +2 -0
  171. data/ext/couchbase/core/operations/management/search_index_get_documents_count.hxx +2 -0
  172. data/ext/couchbase/core/operations/management/search_index_get_stats.hxx +2 -0
  173. data/ext/couchbase/core/operations/management/search_index_upsert.hxx +2 -0
  174. data/ext/couchbase/core/operations/management/user_drop.hxx +2 -0
  175. data/ext/couchbase/core/operations/management/user_get.hxx +2 -0
  176. data/ext/couchbase/core/operations/management/user_get_all.hxx +2 -0
  177. data/ext/couchbase/core/operations/management/user_upsert.hxx +2 -0
  178. data/ext/couchbase/core/operations/management/view_index_drop.hxx +2 -0
  179. data/ext/couchbase/core/operations/management/view_index_get.hxx +2 -0
  180. data/ext/couchbase/core/operations/management/view_index_get_all.hxx +2 -0
  181. data/ext/couchbase/core/operations/management/view_index_upsert.hxx +2 -0
  182. data/ext/couchbase/core/operations/operation_traits.hxx +6 -0
  183. data/ext/couchbase/core/operations.hxx +0 -1
  184. data/ext/couchbase/core/operations_fwd.hxx +8 -0
  185. data/ext/couchbase/core/origin.cxx +67 -12
  186. data/ext/couchbase/core/origin.hxx +13 -8
  187. data/ext/couchbase/core/orphan_reporter.cxx +164 -0
  188. data/ext/couchbase/core/orphan_reporter.hxx +65 -0
  189. data/ext/couchbase/core/sasl/CMakeLists.txt +1 -0
  190. data/ext/couchbase/core/sasl/client.cc +6 -0
  191. data/ext/couchbase/core/sasl/mechanism.cc +2 -1
  192. data/ext/couchbase/core/sasl/mechanism.h +2 -1
  193. data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.cc +41 -0
  194. data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.h +47 -0
  195. data/ext/couchbase/core/tls_context_provider.cxx +44 -0
  196. data/ext/couchbase/core/tls_context_provider.hxx +44 -0
  197. data/ext/couchbase/core/tracing/attribute_helpers.hxx +45 -0
  198. data/ext/couchbase/core/tracing/constants.hxx +148 -68
  199. data/ext/couchbase/core/tracing/threshold_logging_options.hxx +0 -3
  200. data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +122 -170
  201. data/ext/couchbase/core/tracing/tracer_wrapper.cxx +17 -24
  202. data/ext/couchbase/core/tracing/tracer_wrapper.hxx +8 -10
  203. data/ext/couchbase/core/tracing/wrapper_sdk_tracer.cxx +114 -0
  204. data/ext/couchbase/core/tracing/wrapper_sdk_tracer.hxx +85 -0
  205. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +16 -14
  206. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +4 -4
  207. data/ext/couchbase/core/transactions/transactions.cxx +1 -1
  208. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +1 -2
  209. data/ext/couchbase/core/utils/byteswap.hxx +12 -0
  210. data/ext/couchbase/core/utils/concurrent_fixed_priority_queue.hxx +102 -0
  211. data/ext/couchbase/core/utils/connection_string.cxx +2 -0
  212. data/ext/couchbase/couchbase/certificate_authenticator.hxx +1 -0
  213. data/ext/couchbase/couchbase/cluster.hxx +47 -0
  214. data/ext/couchbase/couchbase/cluster_options.hxx +16 -0
  215. data/ext/couchbase/couchbase/collection.hxx +60 -15
  216. data/ext/couchbase/couchbase/error_codes.hxx +48 -48
  217. data/ext/couchbase/couchbase/jwt_authenticator.hxx +52 -0
  218. data/ext/couchbase/couchbase/metrics/meter.hxx +2 -1
  219. data/ext/couchbase/couchbase/metrics/otel_meter.hxx +75 -80
  220. data/ext/couchbase/couchbase/network_options.hxx +19 -0
  221. data/ext/couchbase/couchbase/password_authenticator.hxx +1 -0
  222. data/ext/couchbase/couchbase/tracing/otel_tracer.hxx +15 -17
  223. data/ext/couchbase/couchbase/tracing/request_span.hxx +2 -2
  224. data/ext/couchbase.cxx +4 -0
  225. data/ext/extconf.rb +1 -0
  226. data/ext/rcb_analytics.cxx +157 -47
  227. data/ext/rcb_backend.cxx +118 -71
  228. data/ext/rcb_buckets.cxx +39 -16
  229. data/ext/rcb_collections.cxx +36 -12
  230. data/ext/rcb_crud.cxx +587 -294
  231. data/ext/rcb_hdr_histogram.cxx +219 -0
  232. data/ext/rcb_hdr_histogram.hxx +28 -0
  233. data/ext/rcb_multi.cxx +142 -59
  234. data/ext/rcb_observability.cxx +132 -0
  235. data/ext/rcb_observability.hxx +49 -0
  236. data/ext/rcb_query.cxx +77 -27
  237. data/ext/rcb_search.cxx +92 -31
  238. data/ext/rcb_users.cxx +69 -26
  239. data/ext/rcb_utils.cxx +91 -0
  240. data/ext/rcb_utils.hxx +141 -168
  241. data/ext/rcb_views.cxx +36 -12
  242. data/lib/active_support/cache/couchbase_store.rb +6 -6
  243. data/lib/couchbase/authenticator.rb +14 -0
  244. data/lib/couchbase/binary_collection.rb +37 -22
  245. data/lib/couchbase/bucket.rb +46 -31
  246. data/lib/couchbase/cluster.rb +146 -61
  247. data/lib/couchbase/collection.rb +257 -186
  248. data/lib/couchbase/datastructures/couchbase_list.rb +81 -50
  249. data/lib/couchbase/datastructures/couchbase_map.rb +86 -50
  250. data/lib/couchbase/datastructures/couchbase_queue.rb +64 -38
  251. data/lib/couchbase/datastructures/couchbase_set.rb +57 -41
  252. data/lib/couchbase/deprecations.rb +1 -1
  253. data/lib/couchbase/diagnostics.rb +8 -8
  254. data/lib/couchbase/errors.rb +6 -0
  255. data/lib/couchbase/management/analytics_index_manager.rb +90 -59
  256. data/lib/couchbase/management/bucket_manager.rb +73 -45
  257. data/lib/couchbase/management/collection_manager.rb +86 -43
  258. data/lib/couchbase/management/collection_query_index_manager.rb +56 -33
  259. data/lib/couchbase/management/query_index_manager.rb +88 -36
  260. data/lib/couchbase/management/scope_search_index_manager.rb +119 -52
  261. data/lib/couchbase/management/search_index_manager.rb +401 -178
  262. data/lib/couchbase/management/user_manager.rb +343 -174
  263. data/lib/couchbase/management/view_index_manager.rb +166 -73
  264. data/lib/couchbase/metrics/logging_meter.rb +108 -0
  265. data/lib/couchbase/metrics/logging_value_recorder.rb +50 -0
  266. data/lib/couchbase/metrics/meter.rb +27 -0
  267. data/lib/couchbase/metrics/noop_meter.rb +30 -0
  268. data/lib/couchbase/metrics/noop_value_recorder.rb +27 -0
  269. data/lib/couchbase/metrics/value_recorder.rb +25 -0
  270. data/lib/couchbase/options.rb +69 -3
  271. data/lib/couchbase/protostellar/cluster.rb +3 -0
  272. data/lib/couchbase/scope.rb +62 -48
  273. data/lib/couchbase/search_options.rb +18 -18
  274. data/lib/couchbase/tracing/noop_span.rb +29 -0
  275. data/lib/couchbase/tracing/noop_tracer.rb +29 -0
  276. data/lib/couchbase/tracing/request_span.rb +34 -0
  277. data/lib/couchbase/tracing/request_tracer.rb +28 -0
  278. data/lib/couchbase/tracing/threshold_logging_span.rb +112 -0
  279. data/lib/couchbase/tracing/threshold_logging_tracer.rb +231 -0
  280. data/lib/couchbase/utils/hdr_histogram.rb +55 -0
  281. data/lib/couchbase/utils/observability.rb +257 -0
  282. data/lib/couchbase/utils/observability_constants.rb +200 -0
  283. data/lib/couchbase/utils/stdlib_logger_adapter.rb +1 -3
  284. data/lib/couchbase/version.rb +1 -1
  285. data/lib/couchbase.rb +2 -2
  286. metadata +58 -6
@@ -21,6 +21,7 @@
21
21
  #include "get_all_replicas.hxx"
22
22
  #include "get_any_replica.hxx"
23
23
  #include "internal_scan_result.hxx"
24
+ #include "observability_recorder.hxx"
24
25
  #include "observe_poll.hxx"
25
26
 
26
27
  #include "core/agent_group.hxx"
@@ -28,6 +29,7 @@
28
29
  #include "core/cluster.hxx"
29
30
  #include "core/impl/subdoc/command.hxx"
30
31
  #include "core/logger/logger.hxx"
32
+ #include "core/metrics/meter_wrapper.hxx"
31
33
  #include "core/operations/document_append.hxx"
32
34
  #include "core/operations/document_decrement.hxx"
33
35
  #include "core/operations/document_exists.hxx"
@@ -53,6 +55,8 @@
53
55
  #include "core/range_scan_orchestrator.hxx"
54
56
  #include "core/range_scan_orchestrator_options.hxx"
55
57
  #include "core/topology/configuration.hxx"
58
+ #include "core/tracing/constants.hxx"
59
+ #include "core/tracing/tracer_wrapper.hxx"
56
60
 
57
61
  #include <couchbase/binary_collection.hxx>
58
62
  #include <couchbase/cas.hxx>
@@ -103,6 +107,8 @@
103
107
  #include <variant>
104
108
  #include <vector>
105
109
 
110
+ #include "core/tracing/attribute_helpers.hxx"
111
+
106
112
  namespace couchbase
107
113
  {
108
114
  class collection_impl : public std::enable_shared_from_this<collection_impl>
@@ -148,41 +154,62 @@ public:
148
154
 
149
155
  void get(std::string document_key, get_options::built options, get_handler&& handler) const
150
156
  {
157
+ auto obs_rec =
158
+ create_observability_recorder(core::tracing::operation::mcbp_get, options.parent_span);
159
+
151
160
  if (!options.with_expiry && options.projections.empty()) {
152
- return core_.execute(
153
- core::operations::get_request{
154
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
155
- {},
156
- {},
157
- options.timeout,
158
- { options.retry_strategy },
159
- options.parent_span,
161
+ core::operations::get_request request{
162
+ core::document_id{
163
+ bucket_name_,
164
+ scope_name_,
165
+ name_,
166
+ std::move(document_key),
160
167
  },
161
- [crypto_manager = crypto_manager_, handler = std::move(handler)](auto resp) mutable {
168
+ {},
169
+ {},
170
+ options.timeout,
171
+ { options.retry_strategy },
172
+ obs_rec->operation_span(),
173
+ };
174
+ return core_.execute(
175
+ std::move(request),
176
+ [obs_rec = std::move(obs_rec),
177
+ crypto_manager = crypto_manager_,
178
+ handler = std::move(handler)](auto resp) mutable {
179
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
162
180
  return handler(
163
181
  core::impl::make_error(std::move(resp.ctx)),
164
182
  get_result{
165
183
  resp.cas, { std::move(resp.value), resp.flags }, {}, std::move(crypto_manager) });
166
184
  });
167
185
  }
168
- return core_.execute(
169
- core::operations::get_projected_request{
170
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
171
- {},
172
- {},
173
- options.projections,
174
- options.with_expiry,
175
- {},
176
- false,
177
- options.timeout,
178
- { options.retry_strategy },
179
- options.parent_span,
186
+ core::operations::get_projected_request request{
187
+ core::document_id{
188
+ bucket_name_,
189
+ scope_name_,
190
+ name_,
191
+ std::move(document_key),
180
192
  },
181
- [crypto_manager = crypto_manager_, handler = std::move(handler)](auto resp) mutable {
193
+ {},
194
+ {},
195
+ options.projections,
196
+ options.with_expiry,
197
+ {},
198
+ false,
199
+ options.timeout,
200
+ { options.retry_strategy },
201
+ obs_rec->operation_span(),
202
+ };
203
+ return core_.execute(
204
+ std::move(request),
205
+ [obs_rec = std::move(obs_rec),
206
+ crypto_manager = crypto_manager_,
207
+ handler = std::move(handler)](auto resp) mutable {
182
208
  std::optional<std::chrono::system_clock::time_point> expiry_time{};
183
209
  if (resp.expiry && resp.expiry.value() > 0) {
184
210
  expiry_time.emplace(std::chrono::seconds{ resp.expiry.value() });
185
211
  }
212
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
186
213
  return handler(core::impl::make_error(std::move(resp.ctx)),
187
214
  get_result{ resp.cas,
188
215
  { std::move(resp.value), resp.flags },
@@ -196,17 +223,30 @@ public:
196
223
  get_and_touch_options::built options,
197
224
  get_and_touch_handler&& handler) const
198
225
  {
199
- return core_.execute(
200
- core::operations::get_and_touch_request{
201
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
202
- {},
203
- {},
204
- expiry,
205
- options.timeout,
206
- { options.retry_strategy },
207
- options.parent_span,
226
+ auto obs_rec = create_observability_recorder(core::tracing::operation::mcbp_get_and_touch,
227
+ options.parent_span);
228
+
229
+ core::operations::get_and_touch_request request{
230
+ core::document_id{
231
+ bucket_name_,
232
+ scope_name_,
233
+ name_,
234
+ std::move(document_key),
208
235
  },
209
- [crypto_manager = crypto_manager_, handler = std::move(handler)](auto resp) mutable {
236
+ {},
237
+ {},
238
+ expiry,
239
+ options.timeout,
240
+ { options.retry_strategy },
241
+ obs_rec->operation_span(),
242
+ };
243
+
244
+ return core_.execute(
245
+ std::move(request),
246
+ [obs_rec = std::move(obs_rec),
247
+ crypto_manager = crypto_manager_,
248
+ handler = std::move(handler)](auto resp) mutable {
249
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
210
250
  return handler(
211
251
  core::impl::make_error(std::move(resp.ctx)),
212
252
  get_result{
@@ -219,17 +259,27 @@ public:
219
259
  touch_options::built options,
220
260
  touch_handler&& handler) const
221
261
  {
222
- return core_.execute(
223
- core::operations::touch_request{
224
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
225
- {},
226
- {},
227
- expiry,
228
- options.timeout,
229
- { options.retry_strategy },
230
- options.parent_span,
262
+ auto obs_rec =
263
+ create_observability_recorder(core::tracing::operation::mcbp_touch, options.parent_span);
264
+
265
+ core::operations::touch_request request{
266
+ core::document_id{
267
+ bucket_name_,
268
+ scope_name_,
269
+ name_,
270
+ std::move(document_key),
231
271
  },
232
- [handler = std::move(handler)](const auto& resp) mutable {
272
+ {},
273
+ {},
274
+ expiry,
275
+ options.timeout,
276
+ { options.retry_strategy },
277
+ obs_rec->operation_span(),
278
+ };
279
+ return core_.execute(
280
+ std::move(request),
281
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](const auto& resp) mutable {
282
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
233
283
  return handler(core::impl::make_error(std::move(resp.ctx)), result{ resp.cas });
234
284
  });
235
285
  }
@@ -238,13 +288,26 @@ public:
238
288
  const get_any_replica_options::built& options,
239
289
  core::impl::movable_get_any_replica_handler&& handler) const
240
290
  {
241
- return core_.execute(
242
- core::operations::get_any_replica_request{
243
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
244
- options.timeout,
245
- options.read_preference,
291
+ auto obs_rec = create_observability_recorder(core::tracing::operation::mcbp_get_any_replica,
292
+ options.parent_span);
293
+
294
+ core::operations::get_any_replica_request request{
295
+ core::document_id{
296
+ bucket_name_,
297
+ scope_name_,
298
+ name_,
299
+ std::move(document_key),
246
300
  },
247
- [crypto_manager = crypto_manager_, handler = std::move(handler)](auto resp) mutable {
301
+ options.timeout,
302
+ options.read_preference,
303
+ obs_rec->operation_span(),
304
+ };
305
+ return core_.execute(
306
+ std::move(request),
307
+ [obs_rec = std::move(obs_rec),
308
+ crypto_manager = crypto_manager_,
309
+ handler = std::move(handler)](auto resp) mutable {
310
+ obs_rec->finish(resp.ctx.ec());
248
311
  return handler(core::impl::make_error(std::move(resp.ctx)),
249
312
  get_replica_result{
250
313
  resp.cas,
@@ -259,13 +322,25 @@ public:
259
322
  const get_all_replicas_options::built& options,
260
323
  core::impl::movable_get_all_replicas_handler&& handler) const
261
324
  {
262
- return core_.execute(
263
- core::operations::get_all_replicas_request{
264
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
265
- options.timeout,
266
- options.read_preference,
325
+ auto obs_rec = create_observability_recorder(core::tracing::operation::mcbp_get_all_replicas,
326
+ options.parent_span);
327
+
328
+ core::operations::get_all_replicas_request request{
329
+ core::document_id{
330
+ bucket_name_,
331
+ scope_name_,
332
+ name_,
333
+ std::move(document_key),
267
334
  },
268
- [crypto_manager = crypto_manager_, handler = std::move(handler)](auto resp) mutable {
335
+ options.timeout,
336
+ options.read_preference,
337
+ obs_rec->operation_span(),
338
+ };
339
+ return core_.execute(
340
+ std::move(request),
341
+ [obs_rec = std::move(obs_rec),
342
+ crypto_manager = crypto_manager_,
343
+ handler = std::move(handler)](auto resp) mutable {
269
344
  get_all_replicas_result result{};
270
345
  for (auto& entry : resp.entries) {
271
346
  result.emplace_back(get_replica_result{
@@ -275,6 +350,7 @@ public:
275
350
  crypto_manager,
276
351
  });
277
352
  }
353
+ obs_rec->finish(resp.ctx.ec());
278
354
  return handler(core::impl::make_error(std::move(resp.ctx)), std::move(result));
279
355
  });
280
356
  }
@@ -283,6 +359,9 @@ public:
283
359
  remove_options::built options,
284
360
  remove_handler&& handler) const
285
361
  {
362
+ auto obs_rec =
363
+ create_observability_recorder(core::tracing::operation::mcbp_remove, options.parent_span);
364
+
286
365
  auto id = core::document_id{
287
366
  bucket_name_,
288
367
  scope_name_,
@@ -290,18 +369,20 @@ public:
290
369
  std::move(document_key),
291
370
  };
292
371
  if (options.persist_to == persist_to::none && options.replicate_to == replicate_to::none) {
372
+ core::operations::remove_request request{
373
+ std::move(id),
374
+ {},
375
+ {},
376
+ options.cas,
377
+ options.durability_level,
378
+ options.timeout,
379
+ { options.retry_strategy },
380
+ obs_rec->operation_span(),
381
+ };
293
382
  return core_.execute(
294
- core::operations::remove_request{
295
- std::move(id),
296
- {},
297
- {},
298
- options.cas,
299
- options.durability_level,
300
- options.timeout,
301
- { options.retry_strategy },
302
- options.parent_span,
303
- },
304
- [handler = std::move(handler)](auto resp) mutable {
383
+ std::move(request),
384
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto resp) mutable {
385
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
305
386
  if (resp.ctx.ec()) {
306
387
  return handler(core::impl::make_error(std::move(resp.ctx)), mutation_result{});
307
388
  }
@@ -318,33 +399,39 @@ public:
318
399
  durability_level::none,
319
400
  options.timeout,
320
401
  { options.retry_strategy },
321
- options.parent_span,
402
+ obs_rec->operation_span(),
322
403
  };
323
- return core_.execute(std::move(request),
324
- [core = core_, id = std::move(id), options, handler = std::move(handler)](
325
- auto&& resp) mutable {
326
- if (resp.ctx.ec()) {
327
- return handler(core::impl::make_error(std::move(resp.ctx)),
328
- mutation_result{ resp.cas, std::move(resp.token) });
329
- }
330
- auto token = resp.token;
331
- core::impl::initiate_observe_poll(
332
- core,
333
- std::move(id),
334
- token,
335
- options.timeout,
336
- options.persist_to,
337
- options.replicate_to,
338
- [resp, handler = std::move(handler)](std::error_code ec) mutable {
339
- if (ec) {
340
- resp.ctx.override_ec(ec);
341
- return handler(core::impl::make_error(std::move(resp.ctx)),
342
- mutation_result{});
343
- }
344
- return handler(core::impl::make_error(std::move(resp.ctx)),
345
- mutation_result{ resp.cas, std::move(resp.token) });
346
- });
347
- });
404
+ return core_.execute(
405
+ std::move(request),
406
+ [obs_rec = std::move(obs_rec),
407
+ core = core_,
408
+ id = std::move(id),
409
+ options,
410
+ handler = std::move(handler)](auto&& resp) mutable {
411
+ if (resp.ctx.ec()) {
412
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
413
+ return handler(core::impl::make_error(std::move(resp.ctx)),
414
+ mutation_result{ resp.cas, std::move(resp.token) });
415
+ }
416
+ auto token = resp.token;
417
+ core::impl::initiate_observe_poll(
418
+ core,
419
+ std::move(id),
420
+ token,
421
+ options.timeout,
422
+ options.persist_to,
423
+ options.replicate_to,
424
+ [obs_rec = std::move(obs_rec), resp, handler = std::move(handler)](
425
+ std::error_code ec) mutable {
426
+ obs_rec->finish(resp.ctx.retry_attempts(), ec);
427
+ if (ec) {
428
+ resp.ctx.override_ec(ec);
429
+ return handler(core::impl::make_error(std::move(resp.ctx)), mutation_result{});
430
+ }
431
+ return handler(core::impl::make_error(std::move(resp.ctx)),
432
+ mutation_result{ resp.cas, std::move(resp.token) });
433
+ });
434
+ });
348
435
  }
349
436
 
350
437
  void get_and_lock(std::string document_key,
@@ -352,17 +439,29 @@ public:
352
439
  get_and_lock_options::built options,
353
440
  get_and_lock_handler&& handler) const
354
441
  {
355
- core_.execute(
356
- core::operations::get_and_lock_request{
357
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
358
- {},
359
- {},
360
- static_cast<uint32_t>(lock_duration.count()),
361
- options.timeout,
362
- { options.retry_strategy },
363
- options.parent_span,
442
+ auto obs_rec = create_observability_recorder(core::tracing::operation::mcbp_get_and_lock,
443
+ options.parent_span);
444
+
445
+ core::operations::get_and_lock_request request{
446
+ core::document_id{
447
+ bucket_name_,
448
+ scope_name_,
449
+ name_,
450
+ std::move(document_key),
364
451
  },
365
- [crypto_manager = crypto_manager_, handler = std::move(handler)](auto&& resp) mutable {
452
+ {},
453
+ {},
454
+ static_cast<uint32_t>(lock_duration.count()),
455
+ options.timeout,
456
+ { options.retry_strategy },
457
+ obs_rec->operation_span(),
458
+ };
459
+ core_.execute(
460
+ std::move(request),
461
+ [obs_rec = std::move(obs_rec),
462
+ crypto_manager = crypto_manager_,
463
+ handler = std::move(handler)](auto&& resp) mutable {
464
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
366
465
  return handler(
367
466
  core::impl::make_error(std::move(resp.ctx)),
368
467
  get_result{
@@ -375,17 +474,27 @@ public:
375
474
  unlock_options::built options,
376
475
  unlock_handler&& handler) const
377
476
  {
378
- core_.execute(
379
- core::operations::unlock_request{
380
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
381
- {},
382
- {},
383
- cas,
384
- options.timeout,
385
- { options.retry_strategy },
386
- options.parent_span,
477
+ auto obs_rec =
478
+ create_observability_recorder(core::tracing::operation::mcbp_unlock, options.parent_span);
479
+
480
+ core::operations::unlock_request request{
481
+ core::document_id{
482
+ bucket_name_,
483
+ scope_name_,
484
+ name_,
485
+ std::move(document_key),
387
486
  },
388
- [handler = std::move(handler)](auto&& resp) mutable {
487
+ {},
488
+ {},
489
+ cas,
490
+ options.timeout,
491
+ { options.retry_strategy },
492
+ obs_rec->operation_span(),
493
+ };
494
+ core_.execute(
495
+ std::move(request),
496
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto&& resp) mutable {
497
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
389
498
  return handler(core::impl::make_error(std::move(resp.ctx)));
390
499
  });
391
500
  }
@@ -394,16 +503,26 @@ public:
394
503
  exists_options::built options,
395
504
  exists_handler&& handler) const
396
505
  {
397
- core_.execute(
398
- core::operations::exists_request{
399
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
400
- {},
401
- {},
402
- options.timeout,
403
- { options.retry_strategy },
404
- options.parent_span,
506
+ auto obs_rec =
507
+ create_observability_recorder(core::tracing::operation::mcbp_exists, options.parent_span);
508
+
509
+ core::operations::exists_request request{
510
+ core::document_id{
511
+ bucket_name_,
512
+ scope_name_,
513
+ name_,
514
+ std::move(document_key),
405
515
  },
406
- [handler = std::move(handler)](auto&& resp) mutable {
516
+ {},
517
+ {},
518
+ options.timeout,
519
+ { options.retry_strategy },
520
+ obs_rec->operation_span(),
521
+ };
522
+ core_.execute(
523
+ std::move(request),
524
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto&& resp) mutable {
525
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
407
526
  return handler(core::impl::make_error(std::move(resp.ctx)),
408
527
  exists_result{ resp.cas, resp.exists() });
409
528
  });
@@ -414,23 +533,29 @@ public:
414
533
  lookup_in_options::built options,
415
534
  lookup_in_handler&& handler) const
416
535
  {
417
- return core_.execute(
418
- core::operations::lookup_in_request{
419
- core::document_id{
420
- bucket_name_,
421
- scope_name_,
422
- name_,
423
- std::move(document_key),
424
- },
425
- {},
426
- {},
427
- options.access_deleted,
428
- specs,
429
- options.timeout,
430
- { options.retry_strategy },
431
- options.parent_span,
536
+ auto obs_rec =
537
+ create_observability_recorder(core::tracing::operation::mcbp_lookup_in, options.parent_span);
538
+
539
+ core::operations::lookup_in_request request{
540
+ core::document_id{
541
+ bucket_name_,
542
+ scope_name_,
543
+ name_,
544
+ std::move(document_key),
432
545
  },
433
- [handler = std::move(handler)](auto resp) mutable {
546
+ {},
547
+ {},
548
+ options.access_deleted,
549
+ specs,
550
+ options.timeout,
551
+ { options.retry_strategy },
552
+ obs_rec->operation_span(),
553
+ };
554
+ return core_.execute(
555
+ std::move(request),
556
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto resp) mutable {
557
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
558
+
434
559
  if (resp.ctx.ec()) {
435
560
  return handler(core::impl::make_error(std::move(resp.ctx)), lookup_in_result{});
436
561
  }
@@ -456,15 +581,24 @@ public:
456
581
  const lookup_in_all_replicas_options::built& options,
457
582
  lookup_in_all_replicas_handler&& handler) const
458
583
  {
459
- return core_.execute(
460
- core::operations::lookup_in_all_replicas_request{
461
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
462
- specs,
463
- options.timeout,
464
- options.parent_span,
465
- options.read_preference,
584
+ auto obs_rec = create_observability_recorder(
585
+ core::tracing::operation::mcbp_lookup_in_all_replicas, options.parent_span);
586
+
587
+ core::operations::lookup_in_all_replicas_request request{
588
+ core::document_id{
589
+ bucket_name_,
590
+ scope_name_,
591
+ name_,
592
+ std::move(document_key),
466
593
  },
467
- [handler = std::move(handler)](auto resp) mutable {
594
+ specs,
595
+ options.timeout,
596
+ obs_rec->operation_span(),
597
+ options.read_preference,
598
+ };
599
+ return core_.execute(
600
+ std::move(request),
601
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto resp) mutable {
468
602
  lookup_in_all_replicas_result result{};
469
603
  for (auto& res : resp.entries) {
470
604
  std::vector<lookup_in_result::entry> entries;
@@ -485,6 +619,7 @@ public:
485
619
  res.is_replica,
486
620
  });
487
621
  }
622
+ obs_rec->finish(resp.ctx.ec());
488
623
  return handler(core::impl::make_error(std::move(resp.ctx)), result);
489
624
  });
490
625
  }
@@ -494,15 +629,24 @@ public:
494
629
  const lookup_in_any_replica_options::built& options,
495
630
  lookup_in_any_replica_handler&& handler) const
496
631
  {
497
- return core_.execute(
498
- core::operations::lookup_in_any_replica_request{
499
- core::document_id{ bucket_name_, scope_name_, name_, std::move(document_key) },
500
- specs,
501
- options.timeout,
502
- options.parent_span,
503
- options.read_preference,
632
+ auto obs_rec = create_observability_recorder(
633
+ core::tracing::operation::mcbp_lookup_in_any_replica, options.parent_span);
634
+
635
+ core::operations::lookup_in_any_replica_request request{
636
+ core::document_id{
637
+ bucket_name_,
638
+ scope_name_,
639
+ name_,
640
+ std::move(document_key),
504
641
  },
505
- [handler = std::move(handler)](auto resp) mutable {
642
+ specs,
643
+ options.timeout,
644
+ obs_rec->operation_span(),
645
+ options.read_preference,
646
+ };
647
+ return core_.execute(
648
+ std::move(request),
649
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto resp) mutable {
506
650
  std::vector<lookup_in_result::entry> entries;
507
651
  entries.reserve(resp.fields.size());
508
652
  for (auto& field : resp.fields) {
@@ -514,7 +658,7 @@ public:
514
658
  field.ec,
515
659
  });
516
660
  }
517
- entries.reserve(resp.fields.size());
661
+ obs_rec->finish(resp.ctx.ec());
518
662
  return handler(
519
663
  core::impl::make_error(std::move(resp.ctx)),
520
664
  lookup_in_replica_result{ resp.cas, std::move(entries), resp.deleted, resp.is_replica });
@@ -526,6 +670,9 @@ public:
526
670
  mutate_in_options::built options,
527
671
  mutate_in_handler&& handler) const
528
672
  {
673
+ auto obs_rec = create_observability_recorder(
674
+ core::tracing::operation::mcbp_mutate_in, options.parent_span, options.durability_level);
675
+
529
676
  auto id = core::document_id{
530
677
  bucket_name_,
531
678
  scope_name_,
@@ -533,25 +680,27 @@ public:
533
680
  std::move(document_key),
534
681
  };
535
682
  if (options.persist_to == persist_to::none && options.replicate_to == replicate_to::none) {
683
+ core::operations::mutate_in_request request{
684
+ std::move(id),
685
+ {},
686
+ {},
687
+ options.cas,
688
+ options.access_deleted,
689
+ options.create_as_deleted,
690
+ false,
691
+ options.expiry,
692
+ options.store_semantics,
693
+ specs,
694
+ options.durability_level,
695
+ options.timeout,
696
+ { options.retry_strategy },
697
+ options.preserve_expiry,
698
+ obs_rec->operation_span(),
699
+ };
536
700
  return core_.execute(
537
- core::operations::mutate_in_request{
538
- std::move(id),
539
- {},
540
- {},
541
- options.cas,
542
- options.access_deleted,
543
- options.create_as_deleted,
544
- false,
545
- options.expiry,
546
- options.store_semantics,
547
- specs,
548
- options.durability_level,
549
- options.timeout,
550
- { options.retry_strategy },
551
- options.preserve_expiry,
552
- options.parent_span,
553
- },
554
- [handler = std::move(handler)](auto resp) mutable {
701
+ std::move(request),
702
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto resp) mutable {
703
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
555
704
  if (resp.ctx.ec()) {
556
705
  return handler(core::impl::make_error(std::move(resp.ctx)), mutate_in_result{});
557
706
  }
@@ -585,13 +734,17 @@ public:
585
734
  options.timeout,
586
735
  { options.retry_strategy },
587
736
  options.preserve_expiry,
588
- options.parent_span,
737
+ obs_rec->operation_span(),
589
738
  };
590
739
  return core_.execute(
591
740
  std::move(request),
592
- [core = core_, id = std::move(id), options, handler = std::move(handler)](
593
- auto&& resp) mutable {
741
+ [obs_rec = std::move(obs_rec),
742
+ core = core_,
743
+ id = std::move(id),
744
+ options,
745
+ handler = std::move(handler)](auto&& resp) mutable {
594
746
  if (resp.ctx.ec()) {
747
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
595
748
  return handler(core::impl::make_error(std::move(resp.ctx)), mutate_in_result{});
596
749
  }
597
750
 
@@ -603,7 +756,9 @@ public:
603
756
  options.timeout,
604
757
  options.persist_to,
605
758
  options.replicate_to,
606
- [resp, handler = std::move(handler)](std::error_code ec) mutable {
759
+ [obs_rec = std::move(obs_rec), resp, handler = std::move(handler)](
760
+ std::error_code ec) mutable {
761
+ obs_rec->finish(resp.ctx.retry_attempts(), ec);
607
762
  if (ec) {
608
763
  resp.ctx.override_ec(ec);
609
764
  return handler(core::impl::make_error(std::move(resp.ctx)), mutate_in_result{});
@@ -625,11 +780,14 @@ public:
625
780
  }
626
781
 
627
782
  void upsert(std::string document_key,
628
- codec::encoded_value encoded,
783
+ std::variant<codec::encoded_value, std::function<codec::encoded_value()>> value,
629
784
  upsert_options::built options,
630
785
  upsert_handler&& handler) const
631
786
  {
632
- auto value = std::move(encoded);
787
+ auto obs_rec = create_observability_recorder(
788
+ core::tracing::operation::mcbp_upsert, options.parent_span, options.durability_level);
789
+
790
+ auto [data, flags] = get_encoded_value(std::move(value), obs_rec);
633
791
  auto id = core::document_id{
634
792
  bucket_name_,
635
793
  scope_name_,
@@ -637,21 +795,23 @@ public:
637
795
  std::move(document_key),
638
796
  };
639
797
  if (options.persist_to == persist_to::none && options.replicate_to == replicate_to::none) {
798
+ core::operations::upsert_request request{
799
+ std::move(id),
800
+ std::move(data),
801
+ {},
802
+ {},
803
+ flags,
804
+ options.expiry,
805
+ options.durability_level,
806
+ options.timeout,
807
+ { options.retry_strategy },
808
+ options.preserve_expiry,
809
+ obs_rec->operation_span(),
810
+ };
640
811
  return core_.execute(
641
- core::operations::upsert_request{
642
- std::move(id),
643
- std::move(value.data),
644
- {},
645
- {},
646
- value.flags,
647
- options.expiry,
648
- options.durability_level,
649
- options.timeout,
650
- { options.retry_strategy },
651
- options.preserve_expiry,
652
- options.parent_span,
653
- },
654
- [handler = std::move(handler)](auto resp) mutable {
812
+ std::move(request),
813
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto resp) mutable {
814
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
655
815
  return handler(core::impl::make_error(std::move(resp.ctx)),
656
816
  mutation_result{ resp.cas, std::move(resp.token) });
657
817
  });
@@ -659,21 +819,26 @@ public:
659
819
 
660
820
  core::operations::upsert_request request{
661
821
  id,
662
- std::move(value.data),
822
+ std::move(data),
663
823
  {},
664
824
  {},
665
- value.flags,
825
+ flags,
666
826
  options.expiry,
667
827
  durability_level::none,
668
828
  options.timeout,
669
829
  { options.retry_strategy },
670
830
  options.preserve_expiry,
671
- options.parent_span,
831
+ obs_rec->operation_span(),
672
832
  };
673
833
  return core_.execute(
674
834
  std::move(request),
675
- [core = core_, id = std::move(id), options, handler = std::move(handler)](auto resp) mutable {
835
+ [obs_rec = std::move(obs_rec),
836
+ core = core_,
837
+ id = std::move(id),
838
+ options,
839
+ handler = std::move(handler)](auto resp) mutable {
676
840
  if (resp.ctx.ec()) {
841
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
677
842
  return handler(core::impl::make_error(std::move(resp.ctx)),
678
843
  mutation_result{ resp.cas, std::move(resp.token) });
679
844
  }
@@ -686,7 +851,9 @@ public:
686
851
  options.timeout,
687
852
  options.persist_to,
688
853
  options.replicate_to,
689
- [resp, handler = std::move(handler)](std::error_code ec) mutable {
854
+ [obs_rec = std::move(obs_rec), resp, handler = std::move(handler)](
855
+ std::error_code ec) mutable {
856
+ obs_rec->finish(resp.ctx.retry_attempts(), ec);
690
857
  if (ec) {
691
858
  resp.ctx.override_ec(ec);
692
859
  return handler(core::impl::make_error(std::move(resp.ctx)), mutation_result{});
@@ -698,11 +865,14 @@ public:
698
865
  }
699
866
 
700
867
  void insert(std::string document_key,
701
- codec::encoded_value encoded,
868
+ std::variant<codec::encoded_value, std::function<codec::encoded_value()>> value,
702
869
  insert_options::built options,
703
870
  insert_handler&& handler) const
704
871
  {
705
- auto value = std::move(encoded);
872
+ auto obs_rec = create_observability_recorder(
873
+ core::tracing::operation::mcbp_insert, options.parent_span, options.durability_level);
874
+
875
+ auto [data, flags] = get_encoded_value(std::move(value), obs_rec);
706
876
  auto id = core::document_id{
707
877
  bucket_name_,
708
878
  scope_name_,
@@ -710,20 +880,22 @@ public:
710
880
  std::move(document_key),
711
881
  };
712
882
  if (options.persist_to == persist_to::none && options.replicate_to == replicate_to::none) {
883
+ core::operations::insert_request request{
884
+ std::move(id),
885
+ std::move(data),
886
+ {},
887
+ {},
888
+ flags,
889
+ options.expiry,
890
+ options.durability_level,
891
+ options.timeout,
892
+ { options.retry_strategy },
893
+ obs_rec->operation_span(),
894
+ };
713
895
  return core_.execute(
714
- core::operations::insert_request{
715
- std::move(id),
716
- std::move(value.data),
717
- {},
718
- {},
719
- value.flags,
720
- options.expiry,
721
- options.durability_level,
722
- options.timeout,
723
- { options.retry_strategy },
724
- options.parent_span,
725
- },
726
- [handler = std::move(handler)](auto&& resp) mutable {
896
+ std::move(request),
897
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto&& resp) mutable {
898
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
727
899
  if (resp.ctx.ec()) {
728
900
  return handler(core::impl::make_error(std::move(resp.ctx)), mutation_result{});
729
901
  }
@@ -734,20 +906,25 @@ public:
734
906
 
735
907
  core::operations::insert_request request{
736
908
  id,
737
- std::move(value.data),
909
+ std::move(data),
738
910
  {},
739
911
  {},
740
- value.flags,
912
+ flags,
741
913
  options.expiry,
742
914
  durability_level::none,
743
915
  options.timeout,
744
916
  { options.retry_strategy },
745
- options.parent_span,
917
+ obs_rec->operation_span(),
746
918
  };
747
919
  return core_.execute(
748
920
  std::move(request),
749
- [core = core_, id = std::move(id), options, handler = std::move(handler)](auto resp) mutable {
921
+ [obs_rec = std::move(obs_rec),
922
+ core = core_,
923
+ id = std::move(id),
924
+ options,
925
+ handler = std::move(handler)](auto resp) mutable {
750
926
  if (resp.ctx.ec()) {
927
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
751
928
  return handler(core::impl::make_error(std::move(resp.ctx)),
752
929
  mutation_result{ resp.cas, std::move(resp.token) });
753
930
  }
@@ -760,7 +937,9 @@ public:
760
937
  options.timeout,
761
938
  options.persist_to,
762
939
  options.replicate_to,
763
- [resp, handler = std::move(handler)](std::error_code ec) mutable {
940
+ [obs_rec = std::move(obs_rec), resp, handler = std::move(handler)](
941
+ std::error_code ec) mutable {
942
+ obs_rec->finish(resp.ctx.retry_attempts(), ec);
764
943
  if (ec) {
765
944
  resp.ctx.override_ec(ec);
766
945
  return handler(core::impl::make_error(std::move(resp.ctx)), mutation_result{});
@@ -770,12 +949,17 @@ public:
770
949
  });
771
950
  });
772
951
  }
952
+
773
953
  void replace(std::string document_key,
774
- codec::encoded_value encoded,
954
+ std::variant<codec::encoded_value, std::function<codec::encoded_value()>> value,
775
955
  replace_options::built options,
776
956
  replace_handler&& handler) const
777
957
  {
778
- auto value = std::move(encoded);
958
+ auto obs_rec = create_observability_recorder(
959
+ core::tracing::operation::mcbp_replace, options.parent_span, options.durability_level);
960
+
961
+ auto [data, flags] = get_encoded_value(std::move(value), obs_rec);
962
+
779
963
  auto id = core::document_id{
780
964
  bucket_name_,
781
965
  scope_name_,
@@ -783,22 +967,24 @@ public:
783
967
  std::move(document_key),
784
968
  };
785
969
  if (options.persist_to == persist_to::none && options.replicate_to == replicate_to::none) {
970
+ core::operations::replace_request request{
971
+ std::move(id),
972
+ std::move(data),
973
+ {},
974
+ {},
975
+ flags,
976
+ options.expiry,
977
+ options.cas,
978
+ options.durability_level,
979
+ options.timeout,
980
+ { options.retry_strategy },
981
+ options.preserve_expiry,
982
+ obs_rec->operation_span(),
983
+ };
786
984
  return core_.execute(
787
- core::operations::replace_request{
788
- std::move(id),
789
- std::move(value.data),
790
- {},
791
- {},
792
- value.flags,
793
- options.expiry,
794
- options.cas,
795
- options.durability_level,
796
- options.timeout,
797
- { options.retry_strategy },
798
- options.preserve_expiry,
799
- options.parent_span,
800
- },
801
- [handler = std::move(handler)](auto resp) mutable {
985
+ std::move(request),
986
+ [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto resp) mutable {
987
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
802
988
  if (resp.ctx.ec()) {
803
989
  return handler(core::impl::make_error(std::move(resp.ctx)), mutation_result{});
804
990
  }
@@ -809,22 +995,26 @@ public:
809
995
 
810
996
  core::operations::replace_request request{
811
997
  id,
812
- std::move(value.data),
998
+ std::move(data),
813
999
  {},
814
1000
  {},
815
- value.flags,
1001
+ flags,
816
1002
  options.expiry,
817
1003
  options.cas,
818
1004
  durability_level::none,
819
1005
  options.timeout,
820
1006
  { options.retry_strategy },
821
1007
  options.preserve_expiry,
822
- options.parent_span,
1008
+ obs_rec->operation_span(),
823
1009
  };
824
1010
  return core_.execute(std::move(request),
825
- [core = core_, id = std::move(id), options, handler = std::move(handler)](
826
- auto&& resp) mutable {
1011
+ [obs_rec = std::move(obs_rec),
1012
+ core = core_,
1013
+ id = std::move(id),
1014
+ options,
1015
+ handler = std::move(handler)](auto&& resp) mutable {
827
1016
  if (resp.ctx.ec()) {
1017
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
828
1018
  return handler(core::impl::make_error(std::move(resp.ctx)),
829
1019
  mutation_result{ resp.cas, std::move(resp.token) });
830
1020
  }
@@ -837,7 +1027,9 @@ public:
837
1027
  options.timeout,
838
1028
  options.persist_to,
839
1029
  options.replicate_to,
840
- [resp, handler = std::move(handler)](std::error_code ec) mutable {
1030
+ [obs_rec = std::move(obs_rec), resp, handler = std::move(handler)](
1031
+ std::error_code ec) mutable {
1032
+ obs_rec->finish(resp.ctx.retry_attempts(), ec);
841
1033
  if (ec) {
842
1034
  resp.ctx.override_ec(ec);
843
1035
  return handler(core::impl::make_error(std::move(resp.ctx)),
@@ -851,6 +1043,9 @@ public:
851
1043
 
852
1044
  void scan(scan_type::built scan_type, scan_options::built options, scan_handler&& handler) const
853
1045
  {
1046
+ auto obs_rec =
1047
+ create_observability_recorder(core::tracing::operation::mcbp_scan, options.parent_span);
1048
+
854
1049
  core::range_scan_orchestrator_options orchestrator_opts{ options.ids_only };
855
1050
  if (!options.mutation_state.empty()) {
856
1051
  orchestrator_opts.consistent_with = core::mutation_state{ options.mutation_state };
@@ -903,22 +1098,31 @@ public:
903
1098
 
904
1099
  return core_.open_bucket(
905
1100
  bucket_name_,
906
- [this, handler = std::move(handler), orchestrator_opts, core_scan_type](
907
- std::error_code ec) mutable {
1101
+ [this,
1102
+ obs_rec = std::move(obs_rec),
1103
+ handler = std::move(handler),
1104
+ orchestrator_opts,
1105
+ core_scan_type](std::error_code ec) mutable {
908
1106
  if (ec) {
1107
+ obs_rec->finish(ec);
909
1108
  return handler(error(ec), {});
910
1109
  }
911
1110
  return core_.with_bucket_configuration(
912
1111
  bucket_name_,
913
- [this, handler = std::move(handler), orchestrator_opts, core_scan_type](
914
- std::error_code ec,
915
- const std::shared_ptr<core::topology::configuration>& config) mutable {
1112
+ [this,
1113
+ obs_rec = std::move(obs_rec),
1114
+ handler = std::move(handler),
1115
+ orchestrator_opts,
1116
+ core_scan_type](std::error_code ec,
1117
+ const std::shared_ptr<core::topology::configuration>& config) mutable {
916
1118
  if (ec) {
1119
+ obs_rec->finish(ec);
917
1120
  return handler(
918
1121
  error(ec, "An error occurred when attempting to fetch the bucket configuration."),
919
1122
  {});
920
1123
  }
921
1124
  if (!config->capabilities.supports_range_scan()) {
1125
+ obs_rec->finish(ec);
922
1126
  return handler(error(errc::common::feature_not_available,
923
1127
  "This bucket does not support range scan."),
924
1128
  {});
@@ -927,6 +1131,7 @@ public:
927
1131
  core::agent_group(core_.io_context(), core::agent_group_config{ { core_ } });
928
1132
  ec = agent_group.open_bucket(bucket_name_);
929
1133
  if (ec) {
1134
+ obs_rec->finish(ec);
930
1135
  return handler(error(ec,
931
1136
  fmt::format("An error occurred while opening the `{}` bucket.",
932
1137
  bucket_name_)),
@@ -934,6 +1139,7 @@ public:
934
1139
  }
935
1140
  auto agent = agent_group.get_agent(bucket_name_);
936
1141
  if (!agent.has_value()) {
1142
+ obs_rec->finish(ec);
937
1143
  return handler(
938
1144
  error(agent.error(),
939
1145
  fmt::format(
@@ -944,6 +1150,7 @@ public:
944
1150
  if (!config->vbmap.has_value() || config->vbmap->empty()) {
945
1151
  CB_LOG_WARNING("Unable to get vbucket map for `{}` - cannot perform scan operation",
946
1152
  bucket_name_);
1153
+ obs_rec->finish(ec);
947
1154
  return handler(error(errc::common::request_canceled,
948
1155
  "No vbucket map included with the bucket config"),
949
1156
  {});
@@ -957,8 +1164,10 @@ public:
957
1164
  core_scan_type,
958
1165
  orchestrator_opts);
959
1166
  return orchestrator.scan(
960
- [crypto_manager = crypto_manager_,
1167
+ [obs_rec = std::move(obs_rec),
1168
+ crypto_manager = crypto_manager_,
961
1169
  handler = std::move(handler)](auto ec, auto core_scan_result) mutable {
1170
+ obs_rec->finish(ec);
962
1171
  if (ec) {
963
1172
  return handler(error(ec, "Error while starting the range scan"), {});
964
1173
  }
@@ -971,6 +1180,39 @@ public:
971
1180
  }
972
1181
 
973
1182
  private:
1183
+ static auto get_encoded_value(
1184
+ std::variant<codec::encoded_value, std::function<codec::encoded_value()>> value,
1185
+ const std::unique_ptr<core::impl::observability_recorder>& obs_rec) -> codec::encoded_value
1186
+ {
1187
+ if (std::holds_alternative<codec::encoded_value>(value)) {
1188
+ return std::get<codec::encoded_value>(value);
1189
+ }
1190
+ const auto request_encoding_span = obs_rec->create_request_encoding_span();
1191
+ auto encoded = std::get<std::function<codec::encoded_value()>>(value)();
1192
+ request_encoding_span->end();
1193
+ return encoded;
1194
+ }
1195
+
1196
+ [[nodiscard]] auto create_observability_recorder(
1197
+ const std::string& operation_name,
1198
+ const std::shared_ptr<tracing::request_span>& parent_span,
1199
+ const std::optional<durability_level> durability = {}) const
1200
+ -> std::unique_ptr<core::impl::observability_recorder>
1201
+ {
1202
+ auto rec = core::impl::observability_recorder::create(
1203
+ operation_name, parent_span, core_.tracer(), core_.meter());
1204
+
1205
+ rec->with_service(core::tracing::service::key_value);
1206
+ rec->with_bucket_name(bucket_name_);
1207
+ rec->with_scope_name(scope_name_);
1208
+ rec->with_collection_name(name_);
1209
+ if (durability.has_value()) {
1210
+ rec->with_durability(durability.value());
1211
+ }
1212
+
1213
+ return rec;
1214
+ }
1215
+
974
1216
  core::cluster core_;
975
1217
  std::string bucket_name_;
976
1218
  std::string scope_name_;
@@ -1392,6 +1634,30 @@ collection::upsert(std::string document_id,
1392
1634
  return future;
1393
1635
  }
1394
1636
 
1637
+ auto
1638
+ collection::upsert(std::string document_id,
1639
+ std::function<codec::encoded_value()> document_fn,
1640
+ const upsert_options& options,
1641
+ upsert_handler&& handler) const -> void
1642
+ {
1643
+ impl_->upsert(
1644
+ std::move(document_id), std::move(document_fn), options.build(), std::move(handler));
1645
+ }
1646
+
1647
+ auto
1648
+ collection::upsert(std::string document_id,
1649
+ std::function<codec::encoded_value()> document_fn,
1650
+ const upsert_options& options) const
1651
+ -> std::future<std::pair<error, mutation_result>>
1652
+ {
1653
+ auto barrier = std::make_shared<std::promise<std::pair<error, mutation_result>>>();
1654
+ auto future = barrier->get_future();
1655
+ upsert(std::move(document_id), std::move(document_fn), options, [barrier](auto err, auto result) {
1656
+ barrier->set_value({ std::move(err), std::move(result) });
1657
+ });
1658
+ return future;
1659
+ }
1660
+
1395
1661
  void
1396
1662
  collection::insert(std::string document_id,
1397
1663
  codec::encoded_value document,
@@ -1416,6 +1682,30 @@ collection::insert(std::string document_id,
1416
1682
  return future;
1417
1683
  }
1418
1684
 
1685
+ auto
1686
+ collection::insert(std::string document_id,
1687
+ std::function<codec::encoded_value()> document_fn,
1688
+ const insert_options& options,
1689
+ insert_handler&& handler) const -> void
1690
+ {
1691
+ impl_->insert(
1692
+ std::move(document_id), std::move(document_fn), options.build(), std::move(handler));
1693
+ }
1694
+
1695
+ auto
1696
+ collection::insert(std::string document_id,
1697
+ std::function<codec::encoded_value()> document_fn,
1698
+ const insert_options& options) const
1699
+ -> std::future<std::pair<error, mutation_result>>
1700
+ {
1701
+ auto barrier = std::make_shared<std::promise<std::pair<error, mutation_result>>>();
1702
+ auto future = barrier->get_future();
1703
+ insert(std::move(document_id), std::move(document_fn), options, [barrier](auto err, auto result) {
1704
+ barrier->set_value({ std::move(err), std::move(result) });
1705
+ });
1706
+ return future;
1707
+ }
1708
+
1419
1709
  void
1420
1710
  collection::replace(std::string document_id,
1421
1711
  codec::encoded_value document,
@@ -1440,6 +1730,31 @@ collection::replace(std::string document_id,
1440
1730
  return future;
1441
1731
  }
1442
1732
 
1733
+ void
1734
+ collection::replace(std::string document_id,
1735
+ std::function<codec::encoded_value()> document_fn,
1736
+ const replace_options& options,
1737
+ replace_handler&& handler) const
1738
+ {
1739
+ impl_->replace(
1740
+ std::move(document_id), std::move(document_fn), options.build(), std::move(handler));
1741
+ }
1742
+
1743
+ auto
1744
+ collection::replace(std::string document_id,
1745
+ std::function<codec::encoded_value()> document_fn,
1746
+ const replace_options& options) const
1747
+ -> std::future<std::pair<error, mutation_result>>
1748
+ {
1749
+ auto barrier = std::make_shared<std::promise<std::pair<error, mutation_result>>>();
1750
+ auto future = barrier->get_future();
1751
+ replace(
1752
+ std::move(document_id), std::move(document_fn), options, [barrier](auto err, auto result) {
1753
+ barrier->set_value({ std::move(err), std::move(result) });
1754
+ });
1755
+ return future;
1756
+ }
1757
+
1443
1758
  void
1444
1759
  collection::scan(const couchbase::scan_type& scan_type,
1445
1760
  const couchbase::scan_options& options,