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
@@ -32,11 +32,15 @@ module Couchbase
32
32
  # @param [String] bucket_name name of the bucket
33
33
  # @param [String] scope_name name of the scope
34
34
  # @param [String] collection_name name of the collection
35
- def initialize(backend, bucket_name, scope_name, collection_name)
35
+ # @param [Observability::Wrapper] observability wrapper containing tracer and meter
36
+ #
37
+ # @api private
38
+ def initialize(backend, bucket_name, scope_name, collection_name, observability)
36
39
  @backend = backend
37
40
  @bucket_name = bucket_name
38
41
  @scope_name = scope_name
39
42
  @name = collection_name
43
+ @observability = observability
40
44
  end
41
45
 
42
46
  # Provides access to the binary APIs, not used for JSON documents
@@ -48,7 +52,7 @@ module Couchbase
48
52
 
49
53
  # @return [Management::CollectionQueryIndexManager]
50
54
  def query_indexes
51
- Management::CollectionQueryIndexManager.new(@backend, @bucket_name, @scope_name, @name)
55
+ Management::CollectionQueryIndexManager.new(@backend, @bucket_name, @scope_name, @name, @observability)
52
56
  end
53
57
 
54
58
  # Fetches the full document from the collection
@@ -78,17 +82,19 @@ module Couchbase
78
82
  #
79
83
  # @return [GetResult]
80
84
  def get(id, options = Options::Get::DEFAULT)
81
- resp = if options.need_projected_get?
82
- @backend.document_get_projected(bucket_name, @scope_name, @name, id, options.to_backend)
83
- else
84
- @backend.document_get(bucket_name, @scope_name, @name, id, options.to_backend)
85
- end
86
- GetResult.new do |res|
87
- res.transcoder = options.transcoder
88
- res.cas = resp[:cas]
89
- res.flags = resp[:flags]
90
- res.encoded = resp[:content]
91
- res.expiry = resp[:expiry] if resp.key?(:expiry)
85
+ @observability.record_operation(Observability::OP_GET, options.parent_span, self, :kv) do |obs_handler|
86
+ resp = if options.need_projected_get?
87
+ @backend.document_get_projected(bucket_name, @scope_name, @name, id, options.to_backend, obs_handler)
88
+ else
89
+ @backend.document_get(bucket_name, @scope_name, @name, id, options.to_backend, obs_handler)
90
+ end
91
+ GetResult.new do |res|
92
+ res.transcoder = options.transcoder
93
+ res.cas = resp[:cas]
94
+ res.flags = resp[:flags]
95
+ res.encoded = resp[:content]
96
+ res.expiry = resp[:expiry] if resp.key?(:expiry)
97
+ end
92
98
  end
93
99
  end
94
100
 
@@ -107,15 +113,17 @@ module Couchbase
107
113
  #
108
114
  # @return [Array<GetResult>]
109
115
  def get_multi(ids, options = Options::GetMulti::DEFAULT)
110
- resp = @backend.document_get_multi(ids.map { |id| [bucket_name, @scope_name, @name, id] }, options.to_backend)
111
- resp.map do |entry|
112
- GetResult.new do |res|
113
- res.transcoder = options.transcoder
114
- res.id = entry[:id]
115
- res.cas = entry[:cas]
116
- res.flags = entry[:flags]
117
- res.encoded = entry[:content]
118
- res.error = entry[:error]
116
+ @observability.record_operation(Observability::OP_GET_MULTI, options.parent_span, self, :kv) do |_obs_handler|
117
+ resp = @backend.document_get_multi(ids.map { |id| [bucket_name, @scope_name, @name, id] }, options.to_backend)
118
+ resp.map do |entry|
119
+ GetResult.new do |res|
120
+ res.transcoder = options.transcoder
121
+ res.id = entry[:id]
122
+ res.cas = entry[:cas]
123
+ res.flags = entry[:flags]
124
+ res.encoded = entry[:content]
125
+ res.error = entry[:error]
126
+ end
119
127
  end
120
128
  end
121
129
  end
@@ -137,14 +145,16 @@ module Couchbase
137
145
  #
138
146
  # @return [GetResult]
139
147
  def get_and_lock(id, lock_time, options = Options::GetAndLock::DEFAULT)
140
- resp = @backend.document_get_and_lock(bucket_name, @scope_name, @name, id,
141
- lock_time.respond_to?(:in_seconds) ? lock_time.in_seconds : lock_time,
142
- options.to_backend)
143
- GetResult.new do |res|
144
- res.transcoder = options.transcoder
145
- res.cas = resp[:cas]
146
- res.flags = resp[:flags]
147
- res.encoded = resp[:content]
148
+ @observability.record_operation(Observability::OP_GET_AND_LOCK, options.parent_span, self, :kv) do |obs_handler|
149
+ resp = @backend.document_get_and_lock(bucket_name, @scope_name, @name, id,
150
+ lock_time.respond_to?(:in_seconds) ? lock_time.in_seconds : lock_time,
151
+ options.to_backend, obs_handler)
152
+ GetResult.new do |res|
153
+ res.transcoder = options.transcoder
154
+ res.cas = resp[:cas]
155
+ res.flags = resp[:flags]
156
+ res.encoded = resp[:content]
157
+ end
148
158
  end
149
159
  end
150
160
 
@@ -159,14 +169,16 @@ module Couchbase
159
169
  #
160
170
  # @return [GetResult]
161
171
  def get_and_touch(id, expiry, options = Options::GetAndTouch::DEFAULT)
162
- resp = @backend.document_get_and_touch(bucket_name, @scope_name, @name, id,
163
- Utils::Time.extract_expiry_time(expiry),
164
- options.to_backend)
165
- GetResult.new do |res|
166
- res.transcoder = options.transcoder
167
- res.cas = resp[:cas]
168
- res.flags = resp[:flags]
169
- res.encoded = resp[:content]
172
+ @observability.record_operation(Observability::OP_GET_AND_TOUCH, options.parent_span, self, :kv) do |obs_handler|
173
+ resp = @backend.document_get_and_touch(bucket_name, @scope_name, @name, id,
174
+ Utils::Time.extract_expiry_time(expiry),
175
+ options.to_backend, obs_handler)
176
+ GetResult.new do |res|
177
+ res.transcoder = options.transcoder
178
+ res.cas = resp[:cas]
179
+ res.flags = resp[:flags]
180
+ res.encoded = resp[:content]
181
+ end
170
182
  end
171
183
  end
172
184
 
@@ -177,14 +189,16 @@ module Couchbase
177
189
  #
178
190
  # @return [Array<GetReplicaResult>]
179
191
  def get_all_replicas(id, options = Options::GetAllReplicas::DEFAULT)
180
- resp = @backend.document_get_all_replicas(@bucket_name, @scope_name, @name, id, options.to_backend)
181
- resp.map do |entry|
182
- GetReplicaResult.new do |res|
183
- res.transcoder = options.transcoder
184
- res.cas = entry[:cas]
185
- res.flags = entry[:flags]
186
- res.encoded = entry[:content]
187
- res.is_replica = entry[:is_replica]
192
+ @observability.record_operation(Observability::OP_GET_ALL_REPLICAS, options.parent_span, self, :kv) do |obs_handler|
193
+ resp = @backend.document_get_all_replicas(@bucket_name, @scope_name, @name, id, options.to_backend, obs_handler)
194
+ resp.map do |entry|
195
+ GetReplicaResult.new do |res|
196
+ res.transcoder = options.transcoder
197
+ res.cas = entry[:cas]
198
+ res.flags = entry[:flags]
199
+ res.encoded = entry[:content]
200
+ res.is_replica = entry[:is_replica]
201
+ end
188
202
  end
189
203
  end
190
204
  end
@@ -207,13 +221,15 @@ module Couchbase
207
221
  #
208
222
  # @return [GetReplicaResult]
209
223
  def get_any_replica(id, options = Options::GetAnyReplica::DEFAULT)
210
- resp = @backend.document_get_any_replica(@bucket_name, @scope_name, @name, id, options.to_backend)
211
- GetReplicaResult.new do |res|
212
- res.transcoder = options.transcoder
213
- res.cas = resp[:cas]
214
- res.flags = resp[:flags]
215
- res.encoded = resp[:content]
216
- res.is_replica = resp[:is_replica]
224
+ @observability.record_operation(Observability::OP_GET_ANY_REPLICA, options.parent_span, self, :kv) do |obs_handler|
225
+ resp = @backend.document_get_any_replica(@bucket_name, @scope_name, @name, id, options.to_backend, obs_handler)
226
+ GetReplicaResult.new do |res|
227
+ res.transcoder = options.transcoder
228
+ res.cas = resp[:cas]
229
+ res.flags = resp[:flags]
230
+ res.encoded = resp[:content]
231
+ res.is_replica = resp[:is_replica]
232
+ end
217
233
  end
218
234
  end
219
235
 
@@ -228,15 +244,17 @@ module Couchbase
228
244
  #
229
245
  # @return [ExistsResult]
230
246
  def exists(id, options = Options::Exists::DEFAULT)
231
- resp = @backend.document_exists(bucket_name, @scope_name, @name, id, options.to_backend)
232
- ExistsResult.new do |res|
233
- res.deleted = resp[:deleted]
234
- res.exists = resp[:exists]
235
- res.expiry = resp[:expiry]
236
- res.flags = resp[:flags]
237
- res.sequence_number = resp[:sequence_number]
238
- res.datatype = resp[:datatype]
239
- res.cas = resp[:cas]
247
+ @observability.record_operation(Observability::OP_EXISTS, options.parent_span, self, :kv) do |obs_handler|
248
+ resp = @backend.document_exists(bucket_name, @scope_name, @name, id, options.to_backend, obs_handler)
249
+ ExistsResult.new do |res|
250
+ res.deleted = resp[:deleted]
251
+ res.exists = resp[:exists]
252
+ res.expiry = resp[:expiry]
253
+ res.flags = resp[:flags]
254
+ res.sequence_number = resp[:sequence_number]
255
+ res.datatype = resp[:datatype]
256
+ res.cas = resp[:cas]
257
+ end
240
258
  end
241
259
  end
242
260
 
@@ -261,10 +279,13 @@ module Couchbase
261
279
  #
262
280
  # @return [MutationResult]
263
281
  def remove(id, options = Options::Remove::DEFAULT)
264
- resp = @backend.document_remove(bucket_name, @scope_name, @name, id, options.to_backend)
265
- MutationResult.new do |res|
266
- res.cas = resp[:cas]
267
- res.mutation_token = extract_mutation_token(resp)
282
+ @observability.record_operation(Observability::OP_REMOVE, options.parent_span, self, :kv) do |obs_handler|
283
+ obs_handler.add_durability_level(options.durability_level)
284
+ resp = @backend.document_remove(bucket_name, @scope_name, @name, id, options.to_backend, obs_handler)
285
+ MutationResult.new do |res|
286
+ res.cas = resp[:cas]
287
+ res.mutation_token = extract_mutation_token(resp)
288
+ end
268
289
  end
269
290
  end
270
291
 
@@ -287,22 +308,25 @@ module Couchbase
287
308
  #
288
309
  # @return [Array<MutationResult>]
289
310
  def remove_multi(ids, options = Options::RemoveMulti::DEFAULT)
290
- resp = @backend.document_remove_multi(bucket_name, @scope_name, @name, ids.map do |id|
291
- case id
292
- when String
293
- [id, nil]
294
- when Array
295
- id
296
- else
297
- raise ArgumentError, "id argument of remove_multi must be a String or Array<String, Integer>, given: #{id.inspect}"
298
- end
299
- end, options.to_backend)
300
- resp.map do |entry|
301
- MutationResult.new do |res|
302
- res.cas = entry[:cas]
303
- res.mutation_token = extract_mutation_token(entry)
304
- res.error = entry[:error]
305
- res.id = entry[:id]
311
+ @observability.record_operation(Observability::OP_REMOVE_MULTI, options.parent_span, self, :kv) do |obs_handler|
312
+ obs_handler.add_durability_level(options.durability_level)
313
+ resp = @backend.document_remove_multi(bucket_name, @scope_name, @name, ids.map do |id|
314
+ case id
315
+ when String
316
+ [id, nil]
317
+ when Array
318
+ id
319
+ else
320
+ raise ArgumentError, "id argument of remove_multi must be a String or Array<String, Integer>, given: #{id.inspect}"
321
+ end
322
+ end, options.to_backend)
323
+ resp.map do |entry|
324
+ MutationResult.new do |res|
325
+ res.cas = entry[:cas]
326
+ res.mutation_token = extract_mutation_token(entry)
327
+ res.error = entry[:error]
328
+ res.id = entry[:id]
329
+ end
306
330
  end
307
331
  end
308
332
  end
@@ -327,11 +351,14 @@ module Couchbase
327
351
  #
328
352
  # @return [MutationResult]
329
353
  def insert(id, content, options = Options::Insert::DEFAULT)
330
- blob, flags = options.transcoder ? options.transcoder.encode(content) : [content, 0]
331
- resp = @backend.document_insert(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend)
332
- MutationResult.new do |res|
333
- res.cas = resp[:cas]
334
- res.mutation_token = extract_mutation_token(resp)
354
+ @observability.record_operation(Observability::OP_INSERT, options.parent_span, self, :kv) do |obs_handler|
355
+ obs_handler.add_durability_level(options.durability_level)
356
+ blob, flags = encode_content(content, options, obs_handler)
357
+ resp = @backend.document_insert(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend, obs_handler)
358
+ MutationResult.new do |res|
359
+ res.cas = resp[:cas]
360
+ res.mutation_token = extract_mutation_token(resp)
361
+ end
335
362
  end
336
363
  end
337
364
 
@@ -347,11 +374,14 @@ module Couchbase
347
374
  #
348
375
  # @return [MutationResult]
349
376
  def upsert(id, content, options = Options::Upsert::DEFAULT)
350
- blob, flags = options.transcoder ? options.transcoder.encode(content) : [content, 0]
351
- resp = @backend.document_upsert(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend)
352
- MutationResult.new do |res|
353
- res.cas = resp[:cas]
354
- res.mutation_token = extract_mutation_token(resp)
377
+ @observability.record_operation(Observability::OP_UPSERT, options.parent_span, self, :kv) do |obs_handler|
378
+ obs_handler.add_durability_level(options.durability_level)
379
+ blob, flags = encode_content(content, options, obs_handler)
380
+ resp = @backend.document_upsert(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend, obs_handler)
381
+ MutationResult.new do |res|
382
+ res.cas = resp[:cas]
383
+ res.mutation_token = extract_mutation_token(resp)
384
+ end
355
385
  end
356
386
  end
357
387
 
@@ -374,16 +404,16 @@ module Couchbase
374
404
  #
375
405
  # @return [Array<MutationResult>]
376
406
  def upsert_multi(id_content, options = Options::UpsertMulti::DEFAULT)
377
- resp = @backend.document_upsert_multi(bucket_name, @scope_name, @name, id_content.map do |(id, content)|
378
- blob, flags = options.transcoder ? options.transcoder.encode(content) : [content, 0]
379
- [id, blob, flags]
380
- end, options.to_backend)
381
- resp.map do |entry|
382
- MutationResult.new do |res|
383
- res.cas = entry[:cas]
384
- res.mutation_token = extract_mutation_token(entry)
385
- res.error = entry[:error]
386
- res.id = entry[:id]
407
+ @observability.record_operation(Observability::OP_UPSERT, options.parent_span, self, :kv) do |obs_handler|
408
+ encoded_id_content = encode_content_multi(id_content, options, obs_handler)
409
+ resp = @backend.document_upsert_multi(bucket_name, @scope_name, @name, encoded_id_content, options.to_backend)
410
+ resp.map do |entry|
411
+ MutationResult.new do |res|
412
+ res.cas = entry[:cas]
413
+ res.mutation_token = extract_mutation_token(entry)
414
+ res.error = entry[:error]
415
+ res.id = entry[:id]
416
+ end
387
417
  end
388
418
  end
389
419
  end
@@ -401,11 +431,14 @@ module Couchbase
401
431
  #
402
432
  # @return [MutationResult]
403
433
  def replace(id, content, options = Options::Replace::DEFAULT)
404
- blob, flags = options.transcoder ? options.transcoder.encode(content) : [content, 0]
405
- resp = @backend.document_replace(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend)
406
- MutationResult.new do |res|
407
- res.cas = resp[:cas]
408
- res.mutation_token = extract_mutation_token(resp)
434
+ @observability.record_operation(Observability::OP_REPLACE, options.parent_span, self, :kv) do |obs_handler|
435
+ obs_handler.add_durability_level(options.durability_level)
436
+ blob, flags = encode_content(content, options, obs_handler)
437
+ resp = @backend.document_replace(bucket_name, @scope_name, @name, id, blob, flags, options.to_backend, obs_handler)
438
+ MutationResult.new do |res|
439
+ res.cas = resp[:cas]
440
+ res.mutation_token = extract_mutation_token(resp)
441
+ end
409
442
  end
410
443
  end
411
444
 
@@ -420,11 +453,13 @@ module Couchbase
420
453
  #
421
454
  # @return [MutationResult]
422
455
  def touch(id, expiry, options = Options::Touch::DEFAULT)
423
- resp = @backend.document_touch(bucket_name, @scope_name, @name, id,
424
- Utils::Time.extract_expiry_time(expiry),
425
- options.to_backend)
426
- MutationResult.new do |res|
427
- res.cas = resp[:cas]
456
+ @observability.record_operation(Observability::OP_TOUCH, options.parent_span, self, :kv) do |obs_handler|
457
+ resp = @backend.document_touch(bucket_name, @scope_name, @name, id,
458
+ Utils::Time.extract_expiry_time(expiry),
459
+ options.to_backend, obs_handler)
460
+ MutationResult.new do |res|
461
+ res.cas = resp[:cas]
462
+ end
428
463
  end
429
464
  end
430
465
 
@@ -442,7 +477,9 @@ module Couchbase
442
477
  #
443
478
  # @raise [Error::DocumentNotFound]
444
479
  def unlock(id, cas, options = Options::Unlock::DEFAULT)
445
- @backend.document_unlock(bucket_name, @scope_name, @name, id, cas, options.to_backend)
480
+ @observability.record_operation(Observability::OP_UNLOCK, options.parent_span, self, :kv) do |obs_handler|
481
+ @backend.document_unlock(bucket_name, @scope_name, @name, id, cas, options.to_backend, obs_handler)
482
+ end
446
483
  end
447
484
 
448
485
  # Performs lookups to document fragments
@@ -464,27 +501,29 @@ module Couchbase
464
501
  # ]
465
502
  # @return [LookupInResult]
466
503
  def lookup_in(id, specs, options = Options::LookupIn::DEFAULT)
467
- resp = @backend.document_lookup_in(
468
- bucket_name, @scope_name, @name, id,
469
- specs.map do |s|
470
- {
471
- opcode: s.type,
472
- xattr: s.xattr?,
473
- path: s.path,
474
- }
475
- end, options.to_backend
476
- )
477
- LookupInResult.new do |res|
478
- res.transcoder = options.transcoder
479
- res.cas = resp[:cas]
480
- res.deleted = resp[:deleted]
481
- res.encoded = resp[:fields].map do |field|
482
- SubDocumentField.new do |f|
483
- f.exists = field[:exists]
484
- f.index = field[:index]
485
- f.path = field[:path]
486
- f.value = field[:value]
487
- f.error = field[:error]
504
+ @observability.record_operation(Observability::OP_LOOKUP_IN, options.parent_span, self, :kv) do |obs_handler|
505
+ resp = @backend.document_lookup_in(
506
+ bucket_name, @scope_name, @name, id,
507
+ specs.map do |s|
508
+ {
509
+ opcode: s.type,
510
+ xattr: s.xattr?,
511
+ path: s.path,
512
+ }
513
+ end, options.to_backend, obs_handler
514
+ )
515
+ LookupInResult.new do |res|
516
+ res.transcoder = options.transcoder
517
+ res.cas = resp[:cas]
518
+ res.deleted = resp[:deleted]
519
+ res.encoded = resp[:fields].map do |field|
520
+ SubDocumentField.new do |f|
521
+ f.exists = field[:exists]
522
+ f.index = field[:index]
523
+ f.path = field[:path]
524
+ f.value = field[:value]
525
+ f.error = field[:error]
526
+ end
488
527
  end
489
528
  end
490
529
  end
@@ -504,17 +543,19 @@ module Couchbase
504
543
  # @raise [Error::CouchbaseError]
505
544
  # @raise [Error::FeatureNotAvailable]
506
545
  def lookup_in_any_replica(id, specs, options = Options::LookupInAnyReplica::DEFAULT)
507
- resp = @backend.document_lookup_in_any_replica(
508
- bucket_name, @scope_name, @name, id,
509
- specs.map do |s|
510
- {
511
- opcode: s.type,
512
- xattr: s.xattr?,
513
- path: s.path,
514
- }
515
- end, options.to_backend
516
- )
517
- extract_lookup_in_replica_result(resp, options)
546
+ @observability.record_operation(Observability::OP_LOOKUP_IN_ANY_REPLICA, options.parent_span, self, :kv) do |obs_handler|
547
+ resp = @backend.document_lookup_in_any_replica(
548
+ bucket_name, @scope_name, @name, id,
549
+ specs.map do |s|
550
+ {
551
+ opcode: s.type,
552
+ xattr: s.xattr?,
553
+ path: s.path,
554
+ }
555
+ end, options.to_backend, obs_handler
556
+ )
557
+ extract_lookup_in_replica_result(resp, options)
558
+ end
518
559
  end
519
560
 
520
561
  # Performs lookups to document fragments. Reads from the active node and all available replicas and returns all of
@@ -531,18 +572,20 @@ module Couchbase
531
572
  # @raise [Error::CouchbaseError]
532
573
  # @raise [Error::FeatureNotAvailable]
533
574
  def lookup_in_all_replicas(id, specs, options = Options::LookupInAllReplicas::DEFAULT)
534
- resp = @backend.document_lookup_in_all_replicas(
535
- bucket_name, @scope_name, @name, id,
536
- specs.map do |s|
537
- {
538
- opcode: s.type,
539
- xattr: s.xattr?,
540
- path: s.path,
541
- }
542
- end, options.to_backend
543
- )
544
- resp.map do |entry|
545
- extract_lookup_in_replica_result(entry, options)
575
+ @observability.record_operation(Observability::OP_LOOKUP_IN_ALL_REPLICAS, options.parent_span, self, :kv) do |obs_handler|
576
+ resp = @backend.document_lookup_in_all_replicas(
577
+ bucket_name, @scope_name, @name, id,
578
+ specs.map do |s|
579
+ {
580
+ opcode: s.type,
581
+ xattr: s.xattr?,
582
+ path: s.path,
583
+ }
584
+ end, options.to_backend, obs_handler
585
+ )
586
+ resp.map do |entry|
587
+ extract_lookup_in_replica_result(entry, options)
588
+ end
546
589
  end
547
590
  end
548
591
 
@@ -567,29 +610,32 @@ module Couchbase
567
610
  #
568
611
  # @return [MutateInResult]
569
612
  def mutate_in(id, specs, options = Options::MutateIn::DEFAULT)
570
- resp = @backend.document_mutate_in(
571
- bucket_name, @scope_name, @name, id,
572
- specs.map do |s|
573
- {
574
- opcode: s.type,
575
- path: s.path,
576
- param: s.param,
577
- xattr: s.xattr?,
578
- expand_macros: s.expand_macros?,
579
- create_path: s.create_path?,
580
- }
581
- end, options.to_backend
582
- )
583
- MutateInResult.new do |res|
584
- res.transcoder = options.transcoder
585
- res.cas = resp[:cas]
586
- res.deleted = resp[:deleted]
587
- res.mutation_token = extract_mutation_token(resp)
588
- res.encoded = resp[:fields].map do |field|
589
- SubDocumentField.new do |f|
590
- f.index = field[:index]
591
- f.path = field[:path]
592
- f.value = field[:value]
613
+ @observability.record_operation(Observability::OP_MUTATE_IN, options.parent_span, self, :kv) do |obs_handler|
614
+ obs_handler.add_durability_level(options.durability_level)
615
+ resp = @backend.document_mutate_in(
616
+ bucket_name, @scope_name, @name, id,
617
+ specs.map do |s|
618
+ {
619
+ opcode: s.type,
620
+ path: s.path,
621
+ param: s.param,
622
+ xattr: s.xattr?,
623
+ expand_macros: s.expand_macros?,
624
+ create_path: s.create_path?,
625
+ }
626
+ end, options.to_backend, obs_handler
627
+ )
628
+ MutateInResult.new do |res|
629
+ res.transcoder = options.transcoder
630
+ res.cas = resp[:cas]
631
+ res.deleted = resp[:deleted]
632
+ res.mutation_token = extract_mutation_token(resp)
633
+ res.encoded = resp[:fields].map do |field|
634
+ SubDocumentField.new do |f|
635
+ f.index = field[:index]
636
+ f.path = field[:path]
637
+ f.value = field[:value]
638
+ end
593
639
  end
594
640
  end
595
641
  end
@@ -622,16 +668,41 @@ module Couchbase
622
668
  # a lot of documents to find the matching documents. For low latency range queries, it is recommended that you use
623
669
  # SQL++ with the necessary indexes.
624
670
  def scan(scan_type, options = Options::Scan::DEFAULT)
625
- ScanResults.new(
626
- core_scan_result: @backend.document_scan_create(
627
- @bucket_name, @scope_name, @name, scan_type.to_backend, options.to_backend
628
- ),
629
- transcoder: options.transcoder,
630
- )
671
+ @observability.record_operation(Observability::OP_SCAN, options.parent_span, self, :kv) do |_obs_handler|
672
+ ScanResults.new(
673
+ core_scan_result: @backend.document_scan_create(
674
+ @bucket_name, @scope_name, @name, scan_type.to_backend, options.to_backend
675
+ ),
676
+ transcoder: options.transcoder,
677
+ )
678
+ end
631
679
  end
632
680
 
633
681
  private
634
682
 
683
+ def encode_content(content, options, obs_handler)
684
+ return [content, 0] unless options.transcoder
685
+
686
+ obs_handler.with_request_encoding_span do
687
+ options.transcoder.encode(content)
688
+ end
689
+ end
690
+
691
+ def encode_content_multi(id_content_pairs, options, obs_handler)
692
+ unless options.transcoder
693
+ return id_content_pairs.map do |(id, content)|
694
+ [id, content, 0]
695
+ end
696
+ end
697
+
698
+ obs_handler.with_request_encoding_span do
699
+ id_content_pairs.map do |(id, content)|
700
+ blob, flags = options.transcoder.encode(content)
701
+ [id, blob, flags]
702
+ end
703
+ end
704
+ end
705
+
635
706
  def extract_mutation_token(resp)
636
707
  return unless resp.key?(:mutation_token)
637
708