couchbase 3.8.2 → 3.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/CMakeLists.txt +16 -1
  4. data/ext/cache/cpm/{CPM_0.42.0.cmake → CPM_0.43.1.cmake} +18 -2
  5. data/ext/cache/extconf_include.rb +6 -6
  6. data/ext/cache/mozilla-ca-bundle.crt +121 -55
  7. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  8. data/ext/couchbase/CMakeLists.txt +136 -23
  9. data/ext/couchbase/cmake/APKBUILD.in +25 -4
  10. data/ext/couchbase/cmake/Bundler.cmake +143 -34
  11. data/ext/couchbase/cmake/CPM.cmake +126 -12
  12. data/ext/couchbase/cmake/Cache.cmake +7 -1
  13. data/ext/couchbase/cmake/CompilerOptions.cmake +1 -1
  14. data/ext/couchbase/cmake/CompilerWarnings.cmake +17 -6
  15. data/ext/couchbase/cmake/GrpcProtobuf.cmake +481 -0
  16. data/ext/couchbase/cmake/OpenSSL.cmake +82 -7
  17. data/ext/couchbase/cmake/Packaging.cmake +519 -65
  18. data/ext/couchbase/cmake/Protostellar.cmake +250 -0
  19. data/ext/couchbase/cmake/Sanitizers.cmake +61 -50
  20. data/ext/couchbase/cmake/StaticAnalyzers.cmake +16 -5
  21. data/ext/couchbase/cmake/TestFramework.cmake +283 -0
  22. data/ext/couchbase/cmake/TestFrameworkAddTests.cmake +51 -0
  23. data/ext/couchbase/cmake/Testing.cmake +27 -9
  24. data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +141 -8
  25. data/ext/couchbase/cmake/VersionInfo.cmake +50 -0
  26. data/ext/couchbase/cmake/build_config.hxx.in +2 -1
  27. data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +101 -23
  28. data/ext/couchbase/cmake/couchbase_cxx_client_static-config.cmake.in +7 -0
  29. data/ext/couchbase/cmake/couchbase_cxx_client_static.pc.in +2 -0
  30. data/ext/couchbase/cmake/gRPC_Generate.cmake +58 -0
  31. data/ext/couchbase/cmake/protobuf_Generate.cmake +69 -0
  32. data/ext/couchbase/cmake/require-git-checkout.cmake +25 -0
  33. data/ext/couchbase/cmake/tarball_glob.txt +49 -0
  34. data/ext/couchbase/core/agent_group.cxx +0 -8
  35. data/ext/couchbase/core/agent_group.hxx +0 -4
  36. data/ext/couchbase/core/analytics_stream.cxx +314 -0
  37. data/ext/couchbase/core/analytics_stream.hxx +129 -0
  38. data/ext/couchbase/core/analytics_stream_component.cxx +245 -0
  39. data/ext/couchbase/core/analytics_stream_component.hxx +67 -0
  40. data/ext/couchbase/core/app_telemetry_meter.cxx +25 -3
  41. data/ext/couchbase/core/app_telemetry_meter.hxx +77 -0
  42. data/ext/couchbase/core/app_telemetry_reporter.cxx +7 -6
  43. data/ext/couchbase/core/bucket.cxx +381 -87
  44. data/ext/couchbase/core/bucket.hxx +105 -25
  45. data/ext/couchbase/core/bucket_unit_test_api.hxx +57 -0
  46. data/ext/couchbase/core/capella.hxx +91 -0
  47. data/ext/couchbase/core/cluster.cxx +1551 -397
  48. data/ext/couchbase/core/cluster.hxx +39 -8
  49. data/ext/couchbase/core/cluster_agent.cxx +0 -8
  50. data/ext/couchbase/core/cluster_agent.hxx +0 -4
  51. data/ext/couchbase/core/cluster_options.hxx +26 -3
  52. data/ext/couchbase/core/collections_component.cxx +39 -15
  53. data/ext/couchbase/core/config_profiles.cxx +1 -1
  54. data/ext/couchbase/core/crud_component.cxx +2 -2
  55. data/ext/couchbase/core/crud_options.hxx +34 -0
  56. data/ext/couchbase/core/crypto/cbcrypto.cc +18 -13
  57. data/ext/couchbase/core/document_id_redaction.hxx +81 -0
  58. data/ext/couchbase/core/error_context/base_error_context.hxx +7 -6
  59. data/ext/couchbase/core/error_context/key_value.cxx +25 -2
  60. data/ext/couchbase/core/error_context/key_value.hxx +60 -33
  61. data/ext/couchbase/core/error_context/key_value_error_context.hxx +16 -15
  62. data/ext/couchbase/core/error_context/search.hxx +5 -0
  63. data/ext/couchbase/core/error_context/search_json.hxx +3 -0
  64. data/ext/couchbase/core/error_context/subdocument_error_context.hxx +19 -18
  65. data/ext/couchbase/core/error_context/view.hxx +5 -0
  66. data/ext/couchbase/core/free_form_http_request.cxx +237 -4
  67. data/ext/couchbase/core/free_form_http_request.hxx +41 -8
  68. data/ext/couchbase/core/http_component.cxx +300 -284
  69. data/ext/couchbase/core/http_component.hxx +0 -4
  70. data/ext/couchbase/core/impl/analytics.cxx +38 -5
  71. data/ext/couchbase/core/impl/analytics.hxx +34 -0
  72. data/ext/couchbase/core/impl/bootstrap_error.hxx +0 -3
  73. data/ext/couchbase/core/impl/collection.cxx +215 -202
  74. data/ext/couchbase/core/impl/collection_manager.cxx +1 -1
  75. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +45 -18
  76. data/ext/couchbase/core/impl/error.cxx +22 -2
  77. data/ext/couchbase/core/impl/internal_analytics_stream_result.hxx +111 -0
  78. data/ext/couchbase/core/impl/internal_query_stream_result.hxx +110 -0
  79. data/ext/couchbase/core/impl/invoke_with_node_id.hxx +15 -7
  80. data/ext/couchbase/core/impl/key_value_error_category.cxx +6 -0
  81. data/ext/couchbase/core/impl/lookup_in_replica.cxx +10 -10
  82. data/ext/couchbase/core/impl/lookup_in_replica.hxx +4 -4
  83. data/ext/couchbase/core/impl/node_id.cxx +49 -13
  84. data/ext/couchbase/core/impl/observability_recorder.cxx +12 -2
  85. data/ext/couchbase/core/impl/observe_poll.cxx +63 -23
  86. data/ext/couchbase/core/impl/public_analytics_stream_result.cxx +372 -0
  87. data/ext/couchbase/core/impl/public_bucket.cxx +48 -2
  88. data/ext/couchbase/core/impl/public_cluster.cxx +229 -42
  89. data/ext/couchbase/core/impl/public_query_stream_result.cxx +380 -0
  90. data/ext/couchbase/core/impl/public_transaction_get_multi_replicas_from_preferred_server_group_result.cxx +42 -0
  91. data/ext/couchbase/core/impl/public_transaction_get_multi_result.cxx +42 -0
  92. data/ext/couchbase/core/impl/query.cxx +76 -7
  93. data/ext/couchbase/core/impl/query.hxx +36 -0
  94. data/ext/couchbase/core/impl/query_index_manager.cxx +54 -1
  95. data/ext/couchbase/core/impl/replica_utils.cxx +101 -0
  96. data/ext/couchbase/core/impl/replica_utils.hxx +64 -0
  97. data/ext/couchbase/core/impl/resolve_node_id.hxx +125 -0
  98. data/ext/couchbase/core/impl/scope.cxx +70 -0
  99. data/ext/couchbase/core/impl/search.cxx +31 -1
  100. data/ext/couchbase/core/impl/transactions.cxx +130 -0
  101. data/ext/couchbase/core/impl/wait_until_ready.cxx +439 -0
  102. data/ext/couchbase/core/impl/wait_until_ready.hxx +110 -0
  103. data/ext/couchbase/core/impl/with_bucket_config_or_timeout.hxx +180 -0
  104. data/ext/couchbase/core/impl/with_cancellation.hxx +11 -3
  105. data/ext/couchbase/core/io/configuration_belongs_to_session.hxx +1 -2
  106. data/ext/couchbase/core/io/dns_client.cxx +122 -45
  107. data/ext/couchbase/core/io/dns_codec.hxx +21 -21
  108. data/ext/couchbase/core/io/dns_config.cxx +21 -6
  109. data/ext/couchbase/core/io/http_command.hxx +149 -121
  110. data/ext/couchbase/core/io/http_error.hxx +107 -0
  111. data/ext/couchbase/core/io/http_parser.cxx +4 -0
  112. data/ext/couchbase/core/io/http_session.cxx +606 -154
  113. data/ext/couchbase/core/io/http_session.hxx +147 -30
  114. data/ext/couchbase/core/io/http_session_manager.hxx +329 -382
  115. data/ext/couchbase/core/io/http_streaming_parser.cxx +4 -0
  116. data/ext/couchbase/core/io/http_streaming_response.cxx +328 -43
  117. data/ext/couchbase/core/io/http_streaming_response.hxx +37 -3
  118. data/ext/couchbase/core/io/mcbp_buffer_pool.hxx +122 -0
  119. data/ext/couchbase/core/io/mcbp_command.hxx +150 -51
  120. data/ext/couchbase/core/io/mcbp_command_id.hxx +45 -0
  121. data/ext/couchbase/core/io/mcbp_message.cxx +9 -1
  122. data/ext/couchbase/core/io/mcbp_message.hxx +19 -0
  123. data/ext/couchbase/core/io/mcbp_output_queue.hxx +150 -0
  124. data/ext/couchbase/core/io/mcbp_parser.cxx +24 -7
  125. data/ext/couchbase/core/io/mcbp_session.cxx +309 -301
  126. data/ext/couchbase/core/io/mcbp_session.hxx +27 -18
  127. data/ext/couchbase/core/io/opaque_ring_table.hxx +145 -0
  128. data/ext/couchbase/core/io/retry_orchestrator.hxx +6 -5
  129. data/ext/couchbase/core/io/stream_deadline.hxx +50 -0
  130. data/ext/couchbase/core/io/streams.cxx +151 -21
  131. data/ext/couchbase/core/io/streams.hxx +48 -1
  132. data/ext/couchbase/core/logger/logger.cxx +36 -0
  133. data/ext/couchbase/core/logger/logger.hxx +46 -6
  134. data/ext/couchbase/core/logger/redaction.hxx +503 -0
  135. data/ext/couchbase/core/management/eventing_status.hxx +10 -0
  136. data/ext/couchbase/core/management/eventing_status_json.hxx +4 -0
  137. data/ext/couchbase/core/mcbp/big_endian.cxx +1 -1
  138. data/ext/couchbase/core/mcbp/codec.cxx +27 -18
  139. data/ext/couchbase/core/mcbp/operation_queue.cxx +2 -2
  140. data/ext/couchbase/core/mcbp/packet.hxx +2 -2
  141. data/ext/couchbase/core/mcbp/queue_request.cxx +23 -6
  142. data/ext/couchbase/core/mcbp/queue_request.hxx +21 -0
  143. data/ext/couchbase/core/meta/features.hxx +13 -0
  144. data/ext/couchbase/core/meta/version.cxx +6 -3
  145. data/ext/couchbase/core/metrics/logging_meter.cxx +5 -10
  146. data/ext/couchbase/core/metrics/meter_wrapper.cxx +63 -33
  147. data/ext/couchbase/core/metrics/meter_wrapper.hxx +55 -3
  148. data/ext/couchbase/core/operations/analytics_response_parsing.cxx +177 -0
  149. data/ext/couchbase/core/operations/analytics_response_parsing.hxx +55 -0
  150. data/ext/couchbase/core/operations/document_analytics.cxx +48 -130
  151. data/ext/couchbase/core/operations/document_analytics.hxx +14 -2
  152. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +15 -7
  153. data/ext/couchbase/core/operations/document_get_any_replica.hxx +19 -8
  154. data/ext/couchbase/core/operations/document_get_projected.cxx +1 -1
  155. data/ext/couchbase/core/{impl/get_replica.cxx → operations/document_get_replica.cxx} +21 -3
  156. data/ext/couchbase/core/{impl/get_replica.hxx → operations/document_get_replica.hxx} +31 -4
  157. data/ext/couchbase/core/operations/document_lookup_in.cxx +10 -10
  158. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +228 -198
  159. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +215 -217
  160. data/ext/couchbase/core/operations/document_query.cxx +108 -221
  161. data/ext/couchbase/core/operations/document_query.hxx +18 -4
  162. data/ext/couchbase/core/operations/document_search.cxx +52 -8
  163. data/ext/couchbase/core/operations/document_search.hxx +3 -0
  164. data/ext/couchbase/core/operations/document_view.cxx +3 -3
  165. data/ext/couchbase/core/operations/management/analytics_dataset_create.cxx +15 -8
  166. data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +4 -0
  167. data/ext/couchbase/core/operations/management/analytics_dataset_drop.cxx +11 -6
  168. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.cxx +3 -2
  169. data/ext/couchbase/core/operations/management/analytics_dataverse_create.cxx +10 -5
  170. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.cxx +10 -5
  171. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.cxx +2 -1
  172. data/ext/couchbase/core/operations/management/analytics_index_create.cxx +33 -8
  173. data/ext/couchbase/core/operations/management/analytics_index_drop.cxx +12 -7
  174. data/ext/couchbase/core/operations/management/analytics_index_get_all.cxx +3 -2
  175. data/ext/couchbase/core/operations/management/analytics_link_connect.cxx +11 -6
  176. data/ext/couchbase/core/operations/management/analytics_link_create.cxx +3 -3
  177. data/ext/couchbase/core/operations/management/analytics_link_disconnect.cxx +10 -4
  178. data/ext/couchbase/core/operations/management/analytics_link_drop.cxx +6 -4
  179. data/ext/couchbase/core/operations/management/analytics_link_get_all.cxx +4 -3
  180. data/ext/couchbase/core/operations/management/analytics_link_replace.cxx +3 -3
  181. data/ext/couchbase/core/operations/management/analytics_link_utils.hxx +1 -1
  182. data/ext/couchbase/core/operations/management/change_password.cxx +2 -0
  183. data/ext/couchbase/core/operations/management/collection_drop.cxx +5 -1
  184. data/ext/couchbase/core/operations/management/error_utils.cxx +60 -6
  185. data/ext/couchbase/core/operations/management/error_utils.hxx +29 -1
  186. data/ext/couchbase/core/operations/management/eventing_deploy_function.cxx +9 -3
  187. data/ext/couchbase/core/operations/management/eventing_drop_function.cxx +8 -3
  188. data/ext/couchbase/core/operations/management/eventing_get_all_functions.cxx +4 -2
  189. data/ext/couchbase/core/operations/management/eventing_get_function.cxx +5 -3
  190. data/ext/couchbase/core/operations/management/eventing_get_status.cxx +4 -2
  191. data/ext/couchbase/core/operations/management/eventing_pause_function.cxx +9 -3
  192. data/ext/couchbase/core/operations/management/eventing_resume_function.cxx +9 -3
  193. data/ext/couchbase/core/operations/management/eventing_undeploy_function.cxx +9 -3
  194. data/ext/couchbase/core/operations/management/eventing_upsert_function.cxx +9 -3
  195. data/ext/couchbase/core/operations/management/group_drop.cxx +3 -1
  196. data/ext/couchbase/core/operations/management/group_get.cxx +3 -1
  197. data/ext/couchbase/core/operations/management/group_upsert.cxx +11 -8
  198. data/ext/couchbase/core/operations/management/query_index_build.cxx +5 -2
  199. data/ext/couchbase/core/operations/management/query_index_create.cxx +9 -3
  200. data/ext/couchbase/core/operations/management/query_index_drop.cxx +11 -4
  201. data/ext/couchbase/core/operations/management/query_index_get_all.cxx +1 -1
  202. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.cxx +1 -1
  203. data/ext/couchbase/core/operations/management/scope_drop.cxx +5 -1
  204. data/ext/couchbase/core/operations/management/scope_get_all.cxx +6 -1
  205. data/ext/couchbase/core/operations/management/search_get_stats.cxx +10 -0
  206. data/ext/couchbase/core/operations/management/search_index_analyze_document.cxx +3 -2
  207. data/ext/couchbase/core/operations/management/search_index_control_ingest.cxx +4 -3
  208. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.cxx +4 -3
  209. data/ext/couchbase/core/operations/management/search_index_control_query.cxx +4 -3
  210. data/ext/couchbase/core/operations/management/search_index_drop.cxx +2 -2
  211. data/ext/couchbase/core/operations/management/search_index_get.cxx +2 -2
  212. data/ext/couchbase/core/operations/management/search_index_get_documents_count.cxx +3 -2
  213. data/ext/couchbase/core/operations/management/search_index_get_stats.cxx +3 -1
  214. data/ext/couchbase/core/operations/management/search_index_upsert.cxx +2 -2
  215. data/ext/couchbase/core/operations/management/user_drop.cxx +3 -1
  216. data/ext/couchbase/core/operations/management/user_get.cxx +3 -1
  217. data/ext/couchbase/core/operations/management/user_upsert.cxx +12 -9
  218. data/ext/couchbase/core/operations/management/view_index_drop.cxx +1 -1
  219. data/ext/couchbase/core/operations/management/view_index_get.cxx +1 -1
  220. data/ext/couchbase/core/operations/management/view_index_upsert.cxx +1 -1
  221. data/ext/couchbase/core/operations/operation_traits.hxx +18 -0
  222. data/ext/couchbase/core/operations/query_response_parsing.cxx +211 -0
  223. data/ext/couchbase/core/operations/query_response_parsing.hxx +60 -0
  224. data/ext/couchbase/core/operations_fwd.hxx +3 -3
  225. data/ext/couchbase/core/origin.cxx +54 -26
  226. data/ext/couchbase/core/origin.hxx +12 -0
  227. data/ext/couchbase/core/orphan_reporter.cxx +2 -1
  228. data/ext/couchbase/core/platform/random.cc +7 -7
  229. data/ext/couchbase/core/protocol/client_request.cxx +2 -2
  230. data/ext/couchbase/core/protocol/client_request.hxx +38 -21
  231. data/ext/couchbase/core/protocol/client_response.cxx +11 -3
  232. data/ext/couchbase/core/protocol/client_response.hxx +27 -6
  233. data/ext/couchbase/core/protocol/cmd_append.cxx +2 -2
  234. data/ext/couchbase/core/protocol/cmd_cluster_map_change_notification.cxx +2 -2
  235. data/ext/couchbase/core/protocol/cmd_decrement.cxx +6 -6
  236. data/ext/couchbase/core/protocol/cmd_get.cxx +1 -1
  237. data/ext/couchbase/core/protocol/cmd_get_and_lock.cxx +2 -2
  238. data/ext/couchbase/core/protocol/cmd_get_and_touch.cxx +2 -2
  239. data/ext/couchbase/core/protocol/cmd_get_cluster_config.cxx +6 -4
  240. data/ext/couchbase/core/protocol/cmd_get_collection_id.cxx +2 -2
  241. data/ext/couchbase/core/protocol/cmd_get_error_map.cxx +1 -1
  242. data/ext/couchbase/core/protocol/cmd_get_meta.cxx +4 -4
  243. data/ext/couchbase/core/protocol/cmd_get_replica.cxx +1 -1
  244. data/ext/couchbase/core/protocol/cmd_hello.cxx +1 -1
  245. data/ext/couchbase/core/protocol/cmd_increment.cxx +6 -6
  246. data/ext/couchbase/core/protocol/cmd_insert.cxx +4 -4
  247. data/ext/couchbase/core/protocol/cmd_lookup_in.cxx +4 -3
  248. data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +4 -3
  249. data/ext/couchbase/core/protocol/cmd_mutate_in.cxx +10 -9
  250. data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +10 -10
  251. data/ext/couchbase/core/protocol/cmd_observe_seqno.cxx +7 -7
  252. data/ext/couchbase/core/protocol/cmd_prepend.cxx +2 -2
  253. data/ext/couchbase/core/protocol/cmd_remove.cxx +2 -2
  254. data/ext/couchbase/core/protocol/cmd_replace.cxx +4 -4
  255. data/ext/couchbase/core/protocol/cmd_touch.cxx +1 -1
  256. data/ext/couchbase/core/protocol/cmd_upsert.cxx +4 -4
  257. data/ext/couchbase/core/protocol/datatype.hxx +118 -1
  258. data/ext/couchbase/core/protocol/frame_info_utils.cxx +1 -1
  259. data/ext/couchbase/core/protocol/magic.hxx +4 -0
  260. data/ext/couchbase/core/protocol/magic_fmt.hxx +3 -0
  261. data/ext/couchbase/core/protocol/server_request.hxx +3 -1
  262. data/ext/couchbase/core/protocol/status.cxx +1 -1
  263. data/ext/couchbase/core/protostellar/analytics_converter.hxx +171 -0
  264. data/ext/couchbase/core/protostellar/bucket_admin_converter.hxx +301 -0
  265. data/ext/couchbase/core/protostellar/collection_admin_converter.hxx +92 -0
  266. data/ext/couchbase/core/protostellar/component.cxx +2445 -0
  267. data/ext/couchbase/core/protostellar/component.hxx +391 -0
  268. data/ext/couchbase/core/{columnar/bootstrap_notification_subscriber.hxx → protostellar/compression_settings.hxx} +11 -10
  269. data/ext/couchbase/core/protostellar/credentials.cxx +233 -0
  270. data/ext/couchbase/core/protostellar/credentials.hxx +88 -0
  271. data/ext/couchbase/core/protostellar/dispatcher.cxx +57 -0
  272. data/ext/couchbase/core/protostellar/dispatcher.hxx +482 -0
  273. data/ext/couchbase/core/protostellar/error_utils.cxx +293 -0
  274. data/ext/couchbase/core/protostellar/error_utils.hxx +97 -0
  275. data/ext/couchbase/core/protostellar/json_payload.hxx +49 -0
  276. data/ext/couchbase/core/protostellar/kv_converter.cxx +70 -0
  277. data/ext/couchbase/core/protostellar/kv_converter.hxx +600 -0
  278. data/ext/couchbase/core/protostellar/query_converter.hxx +265 -0
  279. data/ext/couchbase/core/protostellar/query_index_admin_converter.hxx +291 -0
  280. data/ext/couchbase/core/protostellar/query_proto.hxx +73 -0
  281. data/ext/couchbase/core/protostellar/search_converter.hxx +244 -0
  282. data/ext/couchbase/core/protostellar/search_index_admin_converter.hxx +156 -0
  283. data/ext/couchbase/core/protostellar/view_converter.hxx +158 -0
  284. data/ext/couchbase/core/query_stream.cxx +447 -0
  285. data/ext/couchbase/core/query_stream.hxx +141 -0
  286. data/ext/couchbase/core/query_stream_component.cxx +243 -0
  287. data/ext/couchbase/core/query_stream_component.hxx +68 -0
  288. data/ext/couchbase/core/range_scan_load_balancer.cxx +15 -8
  289. data/ext/couchbase/core/range_scan_orchestrator.cxx +15 -3
  290. data/ext/couchbase/core/response_handler.hxx +41 -4
  291. data/ext/couchbase/core/row_streamer.cxx +332 -46
  292. data/ext/couchbase/core/row_streamer.hxx +31 -1
  293. data/ext/couchbase/core/row_streamer_options.hxx +55 -0
  294. data/ext/couchbase/core/sasl/client.h +3 -0
  295. data/ext/couchbase/core/search_scoring.hxx +66 -0
  296. data/ext/couchbase/core/stream_error_details.hxx +69 -0
  297. data/ext/couchbase/core/timeout_defaults.hxx +0 -1
  298. data/ext/couchbase/core/topology/capabilities.hxx +6 -0
  299. data/ext/couchbase/core/topology/capabilities_fmt.hxx +3 -0
  300. data/ext/couchbase/core/topology/configuration.cxx +21 -6
  301. data/ext/couchbase/core/topology/configuration.hxx +29 -8
  302. data/ext/couchbase/core/topology/configuration_json.hxx +3 -0
  303. data/ext/couchbase/core/topology/error_map_json.hxx +3 -1
  304. data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +70 -4
  305. data/ext/couchbase/core/tracing/threshold_logging_tracer.hxx +10 -0
  306. data/ext/couchbase/core/transactions/active_transaction_record.cxx +0 -34
  307. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +108 -63
  308. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +19 -2
  309. data/ext/couchbase/core/transactions/error_list.hxx +2 -2
  310. data/ext/couchbase/core/transactions/get_multi_fetch.hxx +160 -0
  311. data/ext/couchbase/core/transactions/get_multi_orchestrator.cxx +326 -125
  312. data/ext/couchbase/core/transactions/get_multi_transaction_id.hxx +62 -0
  313. data/ext/couchbase/core/transactions/internal/atr_entry.hxx +22 -2
  314. data/ext/couchbase/core/transactions/internal/transaction_context.hxx +2 -2
  315. data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +23 -1
  316. data/ext/couchbase/core/transactions/internal/utils.hxx +50 -14
  317. data/ext/couchbase/core/transactions/staged_mutation.cxx +23 -18
  318. data/ext/couchbase/core/transactions/staged_mutation.hxx +15 -4
  319. data/ext/couchbase/core/transactions/transaction_context.cxx +55 -40
  320. data/ext/couchbase/core/transactions/transaction_get_result.hxx +16 -0
  321. data/ext/couchbase/core/transactions/transactions.cxx +3 -55
  322. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +165 -72
  323. data/ext/couchbase/core/transactions/transactions_config.cxx +0 -11
  324. data/ext/couchbase/core/transactions/utils.cxx +10 -0
  325. data/ext/couchbase/core/transactions/waitable_op_list.hxx +2 -2
  326. data/ext/couchbase/core/transactions.hxx +9 -9
  327. data/ext/couchbase/core/utils/byteswap.hxx +166 -9
  328. data/ext/couchbase/core/utils/connection_string.cxx +50 -85
  329. data/ext/couchbase/core/utils/connection_string.hxx +15 -0
  330. data/ext/couchbase/core/{columnar/backoff_calculator.hxx → utils/deadline.hxx} +13 -13
  331. data/ext/couchbase/core/utils/duration_parser.cxx +1 -1
  332. data/ext/couchbase/core/utils/json_streaming_lexer.cxx +48 -5
  333. data/ext/couchbase/core/utils/json_streaming_lexer.hxx +4 -1
  334. data/ext/couchbase/core/utils/movable_function.hxx +301 -52
  335. data/ext/couchbase/core/utils/name_codec.hxx +154 -11
  336. data/ext/couchbase/core/{columnar/retry_info.hxx → utils/process_id.hxx} +18 -13
  337. data/ext/couchbase/core/utils/url_codec.cxx +12 -51
  338. data/ext/couchbase/core/websocket_codec.cxx +13 -37
  339. data/ext/couchbase/couchbase/analytics_options.hxx +21 -10
  340. data/ext/couchbase/couchbase/analytics_row.hxx +105 -0
  341. data/ext/couchbase/couchbase/analytics_stream_result.hxx +266 -0
  342. data/ext/couchbase/couchbase/boolean_query.hxx +3 -3
  343. data/ext/couchbase/couchbase/bucket.hxx +57 -0
  344. data/ext/couchbase/couchbase/cluster.hxx +183 -5
  345. data/ext/couchbase/{core/columnar/security_options.hxx → couchbase/cluster_state.hxx} +18 -14
  346. data/ext/couchbase/couchbase/codec/lenient_json_transcoder.hxx +69 -0
  347. data/ext/couchbase/couchbase/collection.hxx +234 -14
  348. data/ext/couchbase/couchbase/common_durability_options.hxx +18 -3
  349. data/ext/couchbase/couchbase/conjunction_query.hxx +1 -1
  350. data/ext/couchbase/couchbase/create_dataset_analytics_options.hxx +6 -1
  351. data/ext/couchbase/couchbase/date_range_query.hxx +2 -2
  352. data/ext/couchbase/couchbase/decrement_options.hxx +1 -1
  353. data/ext/couchbase/couchbase/disjunction_query.hxx +1 -1
  354. data/ext/couchbase/couchbase/error.hxx +32 -0
  355. data/ext/couchbase/couchbase/error_codes.hxx +33 -1
  356. data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +1 -1
  357. data/ext/couchbase/couchbase/geo_distance_query.hxx +1 -1
  358. data/ext/couchbase/couchbase/geo_polygon_query.hxx +1 -1
  359. data/ext/couchbase/couchbase/get_replica_options.hxx +68 -0
  360. data/ext/couchbase/couchbase/get_replica_result.hxx +5 -3
  361. data/ext/couchbase/couchbase/get_replica_strategy.hxx +161 -0
  362. data/ext/couchbase/couchbase/get_result.hxx +1 -0
  363. data/ext/couchbase/couchbase/increment_options.hxx +1 -1
  364. data/ext/couchbase/couchbase/insert_options.hxx +1 -1
  365. data/ext/couchbase/couchbase/match_phrase_query.hxx +1 -1
  366. data/ext/couchbase/couchbase/match_query.hxx +1 -1
  367. data/ext/couchbase/couchbase/mutate_in_options.hxx +3 -3
  368. data/ext/couchbase/couchbase/network_options.hxx +1 -1
  369. data/ext/couchbase/couchbase/node_id.hxx +42 -14
  370. data/ext/couchbase/couchbase/node_id_for_options.hxx +7 -1
  371. data/ext/couchbase/couchbase/node_ids_options.hxx +8 -2
  372. data/ext/couchbase/couchbase/numeric_range_query.hxx +1 -1
  373. data/ext/couchbase/couchbase/phrase_query.hxx +1 -1
  374. data/ext/couchbase/couchbase/prefix_query.hxx +1 -1
  375. data/ext/couchbase/couchbase/query_options.hxx +23 -12
  376. data/ext/couchbase/couchbase/query_row.hxx +111 -0
  377. data/ext/couchbase/couchbase/query_stream_result.hxx +302 -0
  378. data/ext/couchbase/couchbase/query_string_query.hxx +3 -3
  379. data/ext/couchbase/couchbase/regexp_query.hxx +1 -1
  380. data/ext/couchbase/couchbase/replace_options.hxx +3 -3
  381. data/ext/couchbase/couchbase/result.hxx +14 -3
  382. data/ext/couchbase/couchbase/scan_result_item.hxx +1 -0
  383. data/ext/couchbase/couchbase/scope.hxx +85 -2
  384. data/ext/couchbase/couchbase/search_options.hxx +58 -8
  385. data/ext/couchbase/couchbase/search_scoring.hxx +94 -0
  386. data/ext/couchbase/couchbase/search_scoring_none.hxx +51 -0
  387. data/ext/couchbase/couchbase/search_scoring_reciprocal_rank_fusion.hxx +88 -0
  388. data/ext/couchbase/couchbase/search_scoring_relative_score_fusion.hxx +70 -0
  389. data/ext/couchbase/couchbase/term_range_query.hxx +1 -1
  390. data/ext/couchbase/couchbase/tracing/request_span.hxx +46 -0
  391. data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +23 -21
  392. data/ext/couchbase/couchbase/transactions/transaction_get_multi_result.hxx +24 -19
  393. data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +17 -3
  394. data/ext/couchbase/couchbase/transactions/transactions_config.hxx +4 -2
  395. data/ext/couchbase/couchbase/transactions.hxx +27 -18
  396. data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
  397. data/ext/couchbase/couchbase/vector_query.hxx +1 -1
  398. data/ext/couchbase/couchbase/wait_until_ready_options.hxx +111 -0
  399. data/ext/couchbase/couchbase/wildcard_query.hxx +1 -1
  400. data/ext/extconf.rb +15 -10
  401. data/ext/rcb_analytics.cxx +82 -102
  402. data/ext/rcb_backend.cxx +42 -36
  403. data/ext/rcb_backend.hxx +2 -0
  404. data/ext/rcb_buckets.cxx +47 -59
  405. data/ext/rcb_collections.cxx +42 -52
  406. data/ext/rcb_crud.cxx +345 -224
  407. data/ext/rcb_diagnostics.cxx +117 -27
  408. data/ext/rcb_exceptions.cxx +152 -99
  409. data/ext/rcb_exceptions.hxx +25 -0
  410. data/ext/rcb_extras.cxx +18 -19
  411. data/ext/rcb_hdr_histogram.cxx +19 -4
  412. data/ext/rcb_logger.cxx +202 -27
  413. data/ext/rcb_logger.hxx +12 -0
  414. data/ext/rcb_multi.cxx +40 -40
  415. data/ext/rcb_observability.cxx +7 -5
  416. data/ext/rcb_query.cxx +99 -142
  417. data/ext/rcb_range_scan.cxx +41 -35
  418. data/ext/rcb_search.cxx +98 -99
  419. data/ext/rcb_users.cxx +36 -56
  420. data/ext/rcb_utils.cxx +100 -37
  421. data/ext/rcb_utils.hxx +287 -33
  422. data/ext/rcb_version.cxx +1 -1
  423. data/ext/rcb_views.cxx +55 -51
  424. data/lib/active_support/cache/couchbase_store.rb +77 -12
  425. data/lib/couchbase/bucket.rb +20 -0
  426. data/lib/couchbase/cluster.rb +17 -0
  427. data/lib/couchbase/collection.rb +36 -1
  428. data/lib/couchbase/errors.rb +18 -0
  429. data/lib/couchbase/fork_hooks.rb +16 -7
  430. data/lib/couchbase/get_replica_strategy.rb +89 -0
  431. data/lib/couchbase/logger.rb +1 -1
  432. data/lib/couchbase/management/analytics_index_manager.rb +15 -15
  433. data/lib/couchbase/management/bucket_manager.rb +6 -6
  434. data/lib/couchbase/management/collection_manager.rb +6 -6
  435. data/lib/couchbase/management/query_index_manager.rb +7 -7
  436. data/lib/couchbase/management/search_index_manager.rb +13 -13
  437. data/lib/couchbase/management/user_manager.rb +10 -10
  438. data/lib/couchbase/management/view_index_manager.rb +5 -5
  439. data/lib/couchbase/options.rb +174 -42
  440. data/lib/couchbase/protostellar/bucket.rb +4 -0
  441. data/lib/couchbase/protostellar/cluster.rb +4 -0
  442. data/lib/couchbase/protostellar/collection.rb +4 -0
  443. data/lib/couchbase/protostellar/error_handling.rb +2 -1
  444. data/lib/couchbase/protostellar/request.rb +1 -0
  445. data/lib/couchbase/protostellar/request_generator/kv.rb +16 -2
  446. data/lib/couchbase/protostellar/request_generator/search.rb +17 -1
  447. data/lib/couchbase/protostellar/retry/orchestrator.rb +3 -2
  448. data/lib/couchbase/protostellar/retry/strategies/fail_fast.rb +33 -0
  449. data/lib/couchbase/protostellar/retry/strategies.rb +1 -0
  450. data/lib/couchbase/search_options.rb +95 -6
  451. data/lib/couchbase/version.rb +1 -1
  452. metadata +91 -33
  453. data/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +0 -40
  454. data/ext/couchbase/core/columnar/agent.hxx +0 -71
  455. data/ext/couchbase/core/columnar/agent_config.hxx +0 -59
  456. data/ext/couchbase/core/columnar/background_bootstrap_listener.hxx +0 -42
  457. data/ext/couchbase/core/columnar/backoff_calculator.cxx +0 -62
  458. data/ext/couchbase/core/columnar/columnar_agent.cxx +0 -147
  459. data/ext/couchbase/core/columnar/columnar_agent_config.cxx +0 -48
  460. data/ext/couchbase/core/columnar/columnar_error.cxx +0 -51
  461. data/ext/couchbase/core/columnar/database_management_options.hxx +0 -56
  462. data/ext/couchbase/core/columnar/error.hxx +0 -51
  463. data/ext/couchbase/core/columnar/error_codes.cxx +0 -107
  464. data/ext/couchbase/core/columnar/error_codes.hxx +0 -75
  465. data/ext/couchbase/core/columnar/management_component.cxx +0 -300
  466. data/ext/couchbase/core/columnar/management_component.hxx +0 -56
  467. data/ext/couchbase/core/columnar/query_component.cxx +0 -523
  468. data/ext/couchbase/core/columnar/query_component.hxx +0 -57
  469. data/ext/couchbase/core/columnar/query_options.hxx +0 -59
  470. data/ext/couchbase/core/columnar/query_result.cxx +0 -130
  471. data/ext/couchbase/core/columnar/query_result.hxx +0 -78
  472. data/ext/couchbase/core/io/config_tracker.cxx +0 -687
  473. data/ext/couchbase/core/io/config_tracker.hxx +0 -123
@@ -19,10 +19,11 @@
19
19
 
20
20
  #include "free_form_http_request.hxx"
21
21
  #include "io/http_session_manager.hxx"
22
+ #include "logger/redaction.hxx"
22
23
  #include "pending_operation.hxx"
23
24
  #include "pending_operation_connection_info.hxx"
24
-
25
- #include <couchbase/build_config.hxx>
25
+ #include "tracing/constants.hxx"
26
+ #include "tracing/tracer_wrapper.hxx"
26
27
 
27
28
  #include <asio/error.hpp>
28
29
  #include <spdlog/fmt/bundled/chrono.h>
@@ -50,25 +51,12 @@ class pending_http_operation
50
51
  , public pending_operation_connection_info
51
52
  {
52
53
  public:
53
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
54
- pending_http_operation(asio::io_context& io,
55
- http_request request,
56
- std::chrono::milliseconds dispatch_timeout)
57
- : deadline_{ io }
58
- , dispatch_deadline_{ io }
59
- , dispatch_timeout_{ dispatch_timeout }
60
- , request_{ std::move(request) }
61
- , encoded_{ encode_http_request(request_) }
62
- {
63
- }
64
- #else
65
54
  pending_http_operation(asio::io_context& io, http_request request)
66
55
  : deadline_{ io }
67
56
  , request_{ std::move(request) }
68
57
  , encoded_{ encode_http_request(request_) }
69
58
  {
70
59
  }
71
- #endif
72
60
 
73
61
  ~pending_http_operation() override = default;
74
62
  pending_http_operation(const pending_http_operation&) = delete;
@@ -80,107 +68,112 @@ public:
80
68
  {
81
69
  callback_ = std::move(callback);
82
70
  encoded_.headers["client-context-id"] = request_.client_context_id;
83
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
84
- dispatch_deadline_.expires_after(dispatch_timeout_);
85
- dispatch_deadline_.async_wait([self = shared_from_this()](auto ec) {
86
- if (ec == asio::error::operation_aborted) {
87
- return;
88
- }
89
- CB_LOG_DEBUG(
90
- R"(HTTP request timed out (dispatch): {}, method={}, path="{}", dispatch_timeout={}, client_context_id={})",
91
- self->encoded_.type,
92
- self->encoded_.method,
93
- self->encoded_.path,
94
- self->dispatch_timeout_,
95
- self->encoded_.client_context_id);
96
- self->trigger_timeout();
97
- if (self->session_) {
98
- self->session_->stop();
99
- }
100
- });
101
- #endif
102
71
  deadline_.expires_after(request_.timeout);
103
72
  deadline_.async_wait([self = shared_from_this()](auto ec) {
104
73
  if (ec == asio::error::operation_aborted) {
105
74
  return;
106
75
  }
76
+ // deadline_.cancel() does not retract a completion already queued. A response that took
77
+ // the callback first has handed the session to the stream or to the pool.
78
+ if (!self->trigger_timeout()) {
79
+ return;
80
+ }
107
81
  CB_LOG_DEBUG(
108
82
  R"(HTTP request timed out: {}, method={}, path="{}", timeout={}, client_context_id={})",
109
83
  self->encoded_.type,
110
84
  self->encoded_.method,
111
- self->encoded_.path,
85
+ logger::user_data(self->encoded_.path),
112
86
  self->request_.timeout,
113
87
  self->encoded_.client_context_id);
114
- self->trigger_timeout();
115
- if (self->session_) {
116
- self->session_->stop();
117
- }
118
88
  });
119
89
  }
120
90
 
121
- void set_stream_end_callback(utils::movable_function<void()>&& stream_end_callback)
91
+ // Receives the session the stream was dispatched on, which a failover makes different from the
92
+ // one checked out.
93
+ void set_stream_end_callback(
94
+ utils::movable_function<void(std::shared_ptr<io::http_session>)>&& stream_end_callback)
122
95
  {
123
96
  stream_end_callback_ = std::move(stream_end_callback);
124
97
  }
125
98
 
99
+ void set_tracer(std::shared_ptr<tracing::tracer_wrapper> tracer)
100
+ {
101
+ tracer_ = std::move(tracer);
102
+ }
103
+
104
+ // Once the stream has ended its connection is back in the pool, possibly serving another
105
+ // request, so cancel() leaves it alone. A cancel that comes first keeps the stream end from
106
+ // checking the connection in.
126
107
  void cancel() override
127
108
  {
128
- if (session_) {
129
- session_->stop();
109
+ std::shared_ptr<io::http_session> session;
110
+ {
111
+ const std::scoped_lock lock(callback_mutex_);
112
+ if (stream_ended_) {
113
+ return;
114
+ }
115
+ cancelled_ = true;
116
+ session = session_.lock();
117
+ }
118
+ if (session) {
119
+ session->stop();
130
120
  }
131
121
  invoke_response_handler(errc::common::request_canceled, {});
132
122
  }
133
123
 
134
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
135
- void invoke_response_handler(error_union err, io::http_streaming_response resp)
124
+ // Returns whether this call took the callback, which is the token for completing the request.
125
+ auto invoke_response_handler(std::error_code err, io::http_streaming_response resp) -> bool
136
126
  {
137
- dispatch_deadline_.cancel();
138
- #else
139
- void invoke_response_handler(std::error_code err, io::http_streaming_response resp)
140
- {
141
- #endif
142
127
  deadline_.cancel();
143
128
  free_form_http_request_callback callback{};
129
+ std::shared_ptr<couchbase::tracing::request_span> dispatch_span{};
144
130
  {
145
131
  const std::scoped_lock lock(callback_mutex_);
146
132
  std::swap(callback, callback_);
133
+ std::swap(dispatch_span, dispatch_span_);
134
+ }
135
+ // The dispatch span covers the request up to the response headers, not the streamed body.
136
+ if (dispatch_span) {
137
+ dispatch_span->end();
147
138
  }
148
- if (callback) {
149
- callback(http_response{ std::move(resp) }, err);
139
+ if (!callback) {
140
+ return false;
150
141
  }
142
+ callback(http_response{ std::move(resp) }, err);
143
+ return true;
151
144
  }
152
145
 
153
146
  void send_to(std::shared_ptr<io::http_session> session)
154
147
  {
155
- if (!callback_) {
156
- return;
148
+ {
149
+ // The deadline or a cancel can complete the operation concurrently. Checking the callback and
150
+ // storing the span under the lock that invoke_response_handler takes means the span is either
151
+ // stored before the handler runs, and ended by it, or never created.
152
+ std::unique_lock lock(callback_mutex_);
153
+ if (!callback_) {
154
+ // The session is listed busy and nothing checks it in; on_stop removes it.
155
+ lock.unlock();
156
+ return session->stop();
157
+ }
158
+ session_ = session;
159
+ dispatched_to_ = session->remote_address();
160
+ dispatched_from_ = session->local_address();
161
+ dispatched_to_host_ = fmt::format("{}:{}", session->hostname(), session->port());
162
+ dispatch_span_ = create_dispatch_span(*session);
157
163
  }
158
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
159
- dispatch_deadline_.cancel();
160
- #endif
161
- session_ = std::move(session);
162
164
 
163
- auto start_op = [self = shared_from_this()]() {
164
- self->session_->write_and_stream(
165
+ auto start_op = [self = shared_from_this(), session]() {
166
+ session->write_and_stream(
165
167
  self->encoded_,
166
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
167
- [self](error_union err, io::http_streaming_response resp) {
168
- if (std::holds_alternative<std::error_code>(err) &&
169
- std::get<std::error_code>(err) == asio::error::operation_aborted) {
170
- return;
171
- }
172
- self->invoke_response_handler(err, std::move(resp));
173
- },
174
- #else
175
168
  [self](std::error_code ec, io::http_streaming_response resp) {
176
169
  if (ec == asio::error::operation_aborted) {
177
170
  return;
178
171
  }
172
+ self->refresh_dispatched();
179
173
  self->invoke_response_handler(ec, std::move(resp));
180
174
  },
181
- #endif
182
175
  [self]() {
183
- self->stream_end_callback_();
176
+ self->stream_end_callback_(self->session_at_stream_end());
184
177
  });
185
178
  };
186
179
 
@@ -192,14 +185,6 @@ public:
192
185
  return deadline_.expiry();
193
186
  }
194
187
 
195
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
196
- [[nodiscard]] auto dispatch_deadline_expiry() const
197
- -> std::chrono::time_point<std::chrono::steady_clock>
198
- {
199
- return dispatch_deadline_.expiry();
200
- }
201
- #endif
202
-
203
188
  [[nodiscard]] auto request() const -> http_request
204
189
  {
205
190
  return request_;
@@ -207,40 +192,137 @@ public:
207
192
 
208
193
  [[nodiscard]] auto dispatched_to() const -> std::string override
209
194
  {
210
- return session_->remote_address();
195
+ const std::scoped_lock lock(callback_mutex_);
196
+ return dispatched_to_;
211
197
  }
212
198
 
213
199
  [[nodiscard]] auto dispatched_from() const -> std::string override
214
200
  {
215
- return session_->local_address();
201
+ const std::scoped_lock lock(callback_mutex_);
202
+ return dispatched_from_;
216
203
  }
217
204
 
218
205
  [[nodiscard]] auto dispatched_to_host() const -> std::string override
219
206
  {
220
- return fmt::format("{}:{}", session_->hostname(), session_->port());
207
+ const std::scoped_lock lock(callback_mutex_);
208
+ return dispatched_to_host_;
221
209
  }
222
210
 
223
211
  private:
224
- void trigger_timeout()
212
+ // Rereads the endpoints from the session. A resend after a refused client certificate writes the
213
+ // request on a new connection.
214
+ void refresh_dispatched()
215
+ {
216
+ const std::scoped_lock lock(callback_mutex_);
217
+ if (const auto session = session_.lock(); session) {
218
+ if (auto [from, to] = session->dispatched_endpoints(); !to.empty()) {
219
+ dispatched_from_ = std::move(from);
220
+ dispatched_to_ = std::move(to);
221
+ }
222
+ }
223
+ }
224
+
225
+ // Null before send_to() runs or once the session is gone: the operation does not keep its
226
+ // session alive.
227
+ [[nodiscard]] auto session() const -> std::shared_ptr<io::http_session>
228
+ {
229
+ const std::scoped_lock lock(callback_mutex_);
230
+ return session_.lock();
231
+ }
232
+
233
+ // The session to check in at stream end: null if cancel() or the deadline came first, which stops
234
+ // it.
235
+ [[nodiscard]] auto session_at_stream_end() -> std::shared_ptr<io::http_session>
225
236
  {
237
+ const std::scoped_lock lock(callback_mutex_);
238
+ stream_ended_ = true;
239
+ if (cancelled_) {
240
+ return nullptr;
241
+ }
242
+ return session_.lock();
243
+ }
244
+
245
+ // Ends the request with a timeout unless a response took the callback first. The session is
246
+ // stopped before the callback runs, and a stream end does not check it in. Returns whether this
247
+ // call took the callback.
248
+ auto trigger_timeout() -> bool
249
+ {
250
+ refresh_dispatched();
226
251
  // TODO(JC): if triggered from the dispatch timeout, should only be
227
252
  // errc::common::unambiguous_timeout?
228
253
  auto ec =
229
254
  request_.is_read_only ? errc::common::unambiguous_timeout : errc::common::ambiguous_timeout;
230
- invoke_response_handler(ec, {});
255
+ free_form_http_request_callback callback{};
256
+ std::shared_ptr<couchbase::tracing::request_span> dispatch_span{};
257
+ std::shared_ptr<io::http_session> session;
258
+ {
259
+ const std::scoped_lock lock(callback_mutex_);
260
+ std::swap(callback, callback_);
261
+ std::swap(dispatch_span, dispatch_span_);
262
+ if (callback) {
263
+ cancelled_ = true;
264
+ }
265
+ session = session_.lock();
266
+ }
267
+ if (dispatch_span) {
268
+ dispatch_span->end();
269
+ }
270
+ if (!callback) {
271
+ return false;
272
+ }
273
+ if (session) {
274
+ session->stop();
275
+ }
276
+ callback(http_response{ io::http_streaming_response{} }, ec);
277
+ return true;
278
+ }
279
+
280
+ // Carries the same tags as http_command::create_dispatch_span, so a streamed request reports the
281
+ // same dispatch_to_server span as a buffered one. It is parented to the caller's span because no
282
+ // operation span exists in core for a streamed request.
283
+ [[nodiscard]] auto create_dispatch_span(io::http_session& session) const
284
+ -> std::shared_ptr<couchbase::tracing::request_span>
285
+ {
286
+ if (!tracer_) {
287
+ return {};
288
+ }
289
+ auto dispatch_span =
290
+ tracer_->create_span(tracing::operation::step_dispatch, request_.parent_span);
291
+ if (dispatch_span->uses_tags()) {
292
+ dispatch_span->add_tag(tracing::attributes::dispatch::network_transport, "tcp");
293
+ dispatch_span->add_tag(tracing::attributes::dispatch::operation_id,
294
+ request_.client_context_id);
295
+ dispatch_span->add_tag(tracing::attributes::dispatch::local_id, session.id());
296
+ dispatch_span->add_tag(tracing::attributes::dispatch::server_address,
297
+ session.http_context().canonical_hostname);
298
+ dispatch_span->add_tag(tracing::attributes::dispatch::server_port,
299
+ session.http_context().canonical_port);
300
+
301
+ const auto& peer_endpoint = session.remote_endpoint();
302
+ dispatch_span->add_tag(tracing::attributes::dispatch::peer_address,
303
+ peer_endpoint.address().to_string());
304
+ dispatch_span->add_tag(tracing::attributes::dispatch::peer_port, peer_endpoint.port());
305
+ }
306
+ return dispatch_span;
231
307
  }
232
308
 
233
309
  asio::steady_timer deadline_;
234
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
235
- asio::steady_timer dispatch_deadline_;
236
- std::chrono::milliseconds dispatch_timeout_;
237
- #endif
238
310
  http_request request_;
239
311
  io::http_request encoded_;
240
312
  free_form_http_request_callback callback_;
241
- utils::movable_function<void()> stream_end_callback_;
242
- std::shared_ptr<io::http_session> session_;
243
- std::mutex callback_mutex_;
313
+ std::shared_ptr<tracing::tracer_wrapper> tracer_{};
314
+ std::shared_ptr<couchbase::tracing::request_span> dispatch_span_{};
315
+ utils::movable_function<void(std::shared_ptr<io::http_session>)> stream_end_callback_;
316
+ std::weak_ptr<io::http_session> session_;
317
+ // Endpoints of the session send_to() dispatched on, guarded by callback_mutex_. Recorded because
318
+ // session_ expires once the session is released.
319
+ std::string dispatched_to_;
320
+ std::string dispatched_from_;
321
+ std::string dispatched_to_host_;
322
+ // Guarded by callback_mutex_.
323
+ bool stream_ended_{ false };
324
+ bool cancelled_{ false };
325
+ mutable std::mutex callback_mutex_;
244
326
  };
245
327
 
246
328
  class pending_buffered_http_operation
@@ -249,25 +331,12 @@ class pending_buffered_http_operation
249
331
  , public pending_operation_connection_info
250
332
  {
251
333
  public:
252
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
253
- pending_buffered_http_operation(asio::io_context& io,
254
- http_request request,
255
- std::chrono::milliseconds dispatch_timeout)
256
- : deadline_{ io }
257
- , dispatch_deadline_{ io }
258
- , dispatch_timeout_{ dispatch_timeout }
259
- , request_{ std::move(request) }
260
- , encoded_{ encode_http_request(request_) }
261
- {
262
- }
263
- #else
264
334
  pending_buffered_http_operation(asio::io_context& io, http_request request)
265
335
  : deadline_{ io }
266
336
  , request_{ std::move(request) }
267
337
  , encoded_{ encode_http_request(request_) }
268
338
  {
269
339
  }
270
- #endif
271
340
 
272
341
  ~pending_buffered_http_operation() override = default;
273
342
  pending_buffered_http_operation(const pending_buffered_http_operation&) = delete;
@@ -280,99 +349,106 @@ public:
280
349
  {
281
350
  callback_ = std::move(callback);
282
351
  encoded_.headers["client-context-id"] = request_.client_context_id;
283
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
284
- dispatch_deadline_.expires_after(dispatch_timeout_);
285
- dispatch_deadline_.async_wait([self = shared_from_this()](auto ec) {
286
- if (ec == asio::error::operation_aborted) {
287
- return;
288
- }
289
- CB_LOG_DEBUG(
290
- R"(HTTP request timed out (dispatch): {}, method={}, path="{}", dispatch_timeout={}, client_context_id={})",
291
- self->encoded_.type,
292
- self->encoded_.method,
293
- self->encoded_.path,
294
- self->dispatch_timeout_,
295
- self->encoded_.client_context_id);
296
- self->trigger_timeout();
297
- if (self->session_) {
298
- self->session_->stop();
299
- }
300
- });
301
- #endif
302
352
  deadline_.expires_after(request_.timeout);
303
353
  deadline_.async_wait([self = shared_from_this()](auto ec) {
304
354
  if (ec == asio::error::operation_aborted) {
305
355
  return;
306
356
  }
357
+ // deadline_.cancel() does not retract a completion already queued. A response that took
358
+ // the callback first has handed the session back to the pool.
359
+ if (!self->trigger_timeout()) {
360
+ return;
361
+ }
307
362
  CB_LOG_DEBUG(
308
363
  R"(HTTP request timed out: {}, method={}, path="{}", timeout={}, client_context_id={})",
309
364
  self->encoded_.type,
310
365
  self->encoded_.method,
311
- self->encoded_.path,
366
+ logger::user_data(self->encoded_.path),
312
367
  self->request_.timeout,
313
368
  self->encoded_.client_context_id);
314
- self->trigger_timeout();
315
- if (self->session_) {
316
- self->session_->stop();
317
- }
318
369
  });
319
370
  }
320
371
 
372
+ // Takes the callback, then stops the session before running it: the callback checks the session
373
+ // in, and check_in refuses a stopped one. With no callback left the operation has completed, and
374
+ // its connection may be serving another request.
321
375
  void cancel() override
322
376
  {
323
- if (session_) {
324
- session_->stop();
377
+ buffered_free_form_http_request_callback callback{};
378
+ std::shared_ptr<io::http_session> session;
379
+ {
380
+ const std::scoped_lock lock(callback_mutex_);
381
+ std::swap(callback, callback_);
382
+ session = session_.lock();
325
383
  }
326
- invoke_response_handler(errc::common::request_canceled, {});
384
+ if (!callback) {
385
+ return;
386
+ }
387
+ deadline_.cancel();
388
+ if (session) {
389
+ session->stop();
390
+ }
391
+ callback(buffered_http_response{ io::http_response{} }, errc::common::request_canceled);
327
392
  }
328
393
 
329
- void invoke_response_handler(std::error_code ec, io::http_response resp)
394
+ // Returns whether this call took the callback, which is the token for completing the request.
395
+ auto invoke_response_handler(std::error_code ec, io::http_response resp) -> bool
330
396
  {
331
397
  deadline_.cancel();
332
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
333
- dispatch_deadline_.cancel();
334
- #endif
335
398
  buffered_free_form_http_request_callback callback{};
336
399
  {
337
400
  const std::scoped_lock lock(callback_mutex_);
338
401
  std::swap(callback, callback_);
339
402
  }
340
- if (callback) {
341
- callback(buffered_http_response{ std::move(resp) }, ec);
403
+ if (!callback) {
404
+ return false;
342
405
  }
406
+ callback(buffered_http_response{ std::move(resp) }, ec);
407
+ return true;
343
408
  }
344
409
 
345
410
  void send_to(std::shared_ptr<io::http_session> session)
346
411
  {
347
- if (!callback_) {
348
- return;
412
+ {
413
+ // Checked and stored under the lock invoke_response_handler takes the callback with: a
414
+ // deadline completion that took the callback reads this session, and after it took the
415
+ // callback nothing is stored.
416
+ std::unique_lock lock(callback_mutex_);
417
+ if (!callback_) {
418
+ // The completion checks in only a session stored here, so this one stays listed busy
419
+ // until on_stop removes it.
420
+ lock.unlock();
421
+ return session->stop();
422
+ }
423
+ session_ = session;
424
+ dispatched_to_ = session->remote_address();
425
+ dispatched_from_ = session->local_address();
426
+ dispatched_to_host_ = fmt::format("{}:{}", session->hostname(), session->port());
349
427
  }
350
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
351
- dispatch_deadline_.cancel();
352
- #endif
353
- session_ = std::move(session);
354
428
 
355
- session_->write_and_subscribe(
429
+ session->write_and_subscribe(
356
430
  encoded_, [self = shared_from_this()](std::error_code ec, io::http_response resp) {
357
431
  if (ec == asio::error::operation_aborted) {
358
432
  return;
359
433
  }
434
+ self->refresh_dispatched();
360
435
  self->invoke_response_handler(ec, std::move(resp));
361
436
  });
362
437
  }
363
438
 
364
- [[nodiscard]] auto deadline_expiry() const -> std::chrono::time_point<std::chrono::steady_clock>
439
+ // The session send_to() dispatched on, which a failover makes different from the one checked
440
+ // out. Null if send_to() never ran or the session is gone: the operation does not keep its
441
+ // session alive.
442
+ [[nodiscard]] auto session() const -> std::shared_ptr<io::http_session>
365
443
  {
366
- return deadline_.expiry();
444
+ const std::scoped_lock lock(callback_mutex_);
445
+ return session_.lock();
367
446
  }
368
447
 
369
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
370
- [[nodiscard]] auto dispatch_deadline_expiry() const
371
- -> std::chrono::time_point<std::chrono::steady_clock>
448
+ [[nodiscard]] auto deadline_expiry() const -> std::chrono::time_point<std::chrono::steady_clock>
372
449
  {
373
- return dispatch_deadline_.expiry();
450
+ return deadline_.expiry();
374
451
  }
375
- #endif
376
452
 
377
453
  [[nodiscard]] auto request() const -> http_request
378
454
  {
@@ -381,39 +457,74 @@ public:
381
457
 
382
458
  [[nodiscard]] auto dispatched_to() const -> std::string override
383
459
  {
384
- return session_->remote_address();
460
+ const std::scoped_lock lock(callback_mutex_);
461
+ return dispatched_to_;
385
462
  }
386
463
 
387
464
  [[nodiscard]] auto dispatched_from() const -> std::string override
388
465
  {
389
- return session_->local_address();
466
+ const std::scoped_lock lock(callback_mutex_);
467
+ return dispatched_from_;
390
468
  }
391
469
 
392
470
  [[nodiscard]] auto dispatched_to_host() const -> std::string override
393
471
  {
394
- return fmt::format("{}:{}", session_->hostname(), session_->port());
472
+ const std::scoped_lock lock(callback_mutex_);
473
+ return dispatched_to_host_;
395
474
  }
396
475
 
397
476
  private:
398
- void trigger_timeout()
477
+ // Rereads the endpoints from the session. A resend after a refused client certificate writes the
478
+ // request on a new connection.
479
+ void refresh_dispatched()
480
+ {
481
+ const std::scoped_lock lock(callback_mutex_);
482
+ if (const auto session = session_.lock(); session) {
483
+ if (auto [from, to] = session->dispatched_endpoints(); !to.empty()) {
484
+ dispatched_from_ = std::move(from);
485
+ dispatched_to_ = std::move(to);
486
+ }
487
+ }
488
+ }
489
+
490
+ // Ends the request with a timeout unless a response took the callback first. The session is
491
+ // stopped before the callback runs: the callback checks the session in, and check_in refuses a
492
+ // stopped one. Returns whether this call took the callback.
493
+ auto trigger_timeout() -> bool
399
494
  {
495
+ refresh_dispatched();
400
496
  // TODO(JC): if triggered from the dispatch timeout, should only be
401
497
  // errc::common::unambiguous_timeout?
402
498
  auto ec =
403
499
  request_.is_read_only ? errc::common::unambiguous_timeout : errc::common::ambiguous_timeout;
404
- invoke_response_handler(ec, {});
500
+ buffered_free_form_http_request_callback callback{};
501
+ std::shared_ptr<io::http_session> session;
502
+ {
503
+ const std::scoped_lock lock(callback_mutex_);
504
+ std::swap(callback, callback_);
505
+ session = session_.lock();
506
+ }
507
+ if (!callback) {
508
+ return false;
509
+ }
510
+ if (session) {
511
+ session->stop();
512
+ }
513
+ callback(buffered_http_response{ io::http_response{} }, ec);
514
+ return true;
405
515
  }
406
516
 
407
517
  asio::steady_timer deadline_;
408
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
409
- asio::steady_timer dispatch_deadline_;
410
- std::chrono::milliseconds dispatch_timeout_;
411
- #endif
412
518
  http_request request_;
413
519
  io::http_request encoded_;
414
520
  buffered_free_form_http_request_callback callback_;
415
- std::shared_ptr<io::http_session> session_;
416
- std::mutex callback_mutex_;
521
+ std::weak_ptr<io::http_session> session_;
522
+ // Endpoints of the session send_to() dispatched on, guarded by callback_mutex_. Recorded because
523
+ // session_ expires once the session is released.
524
+ std::string dispatched_to_;
525
+ std::string dispatched_from_;
526
+ std::string dispatched_to_host_;
527
+ mutable std::mutex callback_mutex_;
417
528
  };
418
529
 
419
530
  class http_component_impl
@@ -428,13 +539,8 @@ public:
428
539
  {
429
540
  }
430
541
 
431
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
432
- auto do_http_request(const http_request& request, free_form_http_request_callback&& callback)
433
- -> tl::expected<std::shared_ptr<pending_operation>, error_union>
434
- #else
435
542
  auto do_http_request(const http_request& request, free_form_http_request_callback&& callback)
436
543
  -> tl::expected<std::shared_ptr<pending_operation>, std::error_code>
437
- #endif
438
544
  {
439
545
  std::shared_ptr<io::http_session_manager> session_manager;
440
546
  {
@@ -444,19 +550,7 @@ public:
444
550
  }
445
551
  session_manager = std::move(sm);
446
552
  }
447
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
448
- auto op =
449
- std::make_shared<pending_http_operation>(io_, request, session_manager->dispatch_timeout());
450
- if (!session_manager->is_configured()) {
451
- auto err = defer_command(op, session_manager, std::move(callback));
452
- if (!std::holds_alternative<std::monostate>(err)) {
453
- return tl::unexpected{ err };
454
- }
455
- return op;
456
- }
457
- #else
458
553
  auto op = std::make_shared<pending_http_operation>(io_, request);
459
- #endif
460
554
 
461
555
  send_http_operation(op, session_manager, std::move(callback));
462
556
  return op;
@@ -475,22 +569,7 @@ public:
475
569
  session_manager = std::move(sm);
476
570
  }
477
571
 
478
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
479
- auto op = std::make_shared<pending_buffered_http_operation>(
480
- io_, request, session_manager->dispatch_timeout());
481
- if (!session_manager->is_configured()) {
482
- auto err = defer_command(op, session_manager, std::move(callback));
483
- if (!std::holds_alternative<std::monostate>(err)) {
484
- auto ec = std::holds_alternative<impl::bootstrap_error>(err)
485
- ? std::get<impl::bootstrap_error>(err).ec
486
- : std::get<std::error_code>(err);
487
- return tl::unexpected{ ec };
488
- }
489
- return op;
490
- }
491
- #else
492
572
  auto op = std::make_shared<pending_buffered_http_operation>(io_, request);
493
- #endif
494
573
 
495
574
  send_http_operation(op, session_manager, std::move(callback));
496
575
  return op;
@@ -501,44 +580,38 @@ private:
501
580
  const std::shared_ptr<io::http_session_manager>& session_manager,
502
581
  free_form_http_request_callback&& callback)
503
582
  {
504
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
505
- op->start([callback = std::move(callback)](auto resp, error_union err) mutable {
506
- callback(std::move(resp), err);
507
- });
508
- // don't do anything if the op wasn't dispatched or has already timed out
509
- auto now = std::chrono::steady_clock::now();
510
- if (op->dispatch_deadline_expiry() < now || op->deadline_expiry() < now) {
511
- return;
512
- }
513
- #else
514
583
  op->start([callback = std::move(callback)](auto resp, auto ec) mutable {
515
584
  callback(std::move(resp), ec);
516
585
  });
517
- #endif
518
586
  std::shared_ptr<io::http_session> session;
519
587
  {
520
588
  auto [check_out_ec, s] = session_manager->check_out(
521
589
  op->request().service, op->request().endpoint, op->request().internal.undesired_endpoint);
522
590
  if (check_out_ec) {
523
- return op->invoke_response_handler(check_out_ec, {});
591
+ op->invoke_response_handler(check_out_ec, {});
592
+ return;
524
593
  }
525
594
  session = std::move(s);
526
595
  }
596
+ // Not an owner: a completed operation that never reaches the stream end must not keep the
597
+ // manager alive.
527
598
  op->set_stream_end_callback(
528
- [session_manager, session, service = op->request().service]() mutable {
529
- session_manager->check_in(service, session);
599
+ [manager = std::weak_ptr{ session_manager },
600
+ service = op->request().service](std::shared_ptr<io::http_session> served) {
601
+ if (const auto m = manager.lock(); m) {
602
+ m->check_in(service, std::move(served));
603
+ }
530
604
  });
605
+ op->set_tracer(session_manager->tracer());
531
606
  if (!session->is_connected()) {
532
607
  session_manager->connect_then_send_pending_op(
533
608
  session,
534
609
  {},
535
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
536
- op->dispatch_deadline_expiry(),
537
- #endif
538
610
  op->deadline_expiry(),
539
611
  [op](std::error_code ec, std::shared_ptr<io::http_session> http_session) {
540
612
  if (ec) {
541
- return op->invoke_response_handler(ec, {});
613
+ op->invoke_response_handler(ec, {});
614
+ return;
542
615
  }
543
616
  op->send_to(std::move(http_session));
544
617
  });
@@ -556,28 +629,33 @@ private:
556
629
  auto [check_out_ec, s] = session_manager->check_out(
557
630
  op->request().service, op->request().endpoint, op->request().internal.undesired_endpoint);
558
631
  if (check_out_ec) {
559
- return op->invoke_response_handler(check_out_ec, {});
632
+ op->invoke_response_handler(check_out_ec, {});
633
+ return;
560
634
  }
561
635
  session = std::move(s);
562
636
  }
563
- op->start(
564
- [callback = std::move(callback), session_manager, session, service = op->request().service](
565
- auto resp, auto ec) mutable {
566
- callback(std::move(resp), ec);
567
- session_manager->check_in(service, session);
568
- });
637
+ // Checks in only the session send_to() stored. A completion before send_to() leaves the
638
+ // checked-out session to send_to(), which stops it. Checked in here, it could be taken by
639
+ // another request before that stop.
640
+ op->start([callback = std::move(callback),
641
+ session_manager,
642
+ weak_op = std::weak_ptr<pending_buffered_http_operation>{ op },
643
+ service = op->request().service](auto resp, auto ec) mutable {
644
+ callback(std::move(resp), ec);
645
+ if (auto self = weak_op.lock(); self) {
646
+ session_manager->check_in(service, self->session());
647
+ }
648
+ });
569
649
 
570
650
  if (!session->is_connected()) {
571
651
  session_manager->connect_then_send_pending_op(
572
652
  session,
573
653
  {},
574
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
575
- op->dispatch_deadline_expiry(),
576
- #endif
577
654
  op->deadline_expiry(),
578
655
  [op](std::error_code ec, std::shared_ptr<io::http_session> http_session) {
579
656
  if (ec) {
580
- return op->invoke_response_handler(ec, {});
657
+ op->invoke_response_handler(ec, {});
658
+ return;
581
659
  }
582
660
  op->send_to(std::move(http_session));
583
661
  });
@@ -586,64 +664,6 @@ private:
586
664
  }
587
665
  }
588
666
 
589
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
590
- template<typename Callback, typename PendingHttpOp>
591
- auto defer_command(std::shared_ptr<PendingHttpOp> pending_op,
592
- const std::shared_ptr<io::http_session_manager>& session_manager,
593
- Callback&& callback) -> error_union
594
- {
595
- if (auto last_error = session_manager->last_bootstrap_error(); last_error.has_value()) {
596
- return last_error.value();
597
- }
598
- CB_LOG_DEBUG(
599
- R"(Adding pending HTTP operation to deferred queue: service={}, client_context_id={})",
600
- pending_op->request().service,
601
- pending_op->request().client_context_id);
602
- session_manager->add_to_deferred_queue([this,
603
- callback = std::forward<Callback>(callback),
604
- op = std::move(pending_op),
605
- session_manager](error_union err) mutable {
606
- if (!std::holds_alternative<std::monostate>(err)) {
607
- // The deferred operation was cancelled - currently this can happen due to closing the
608
- // cluster
609
- return callback({}, err);
610
- }
611
-
612
- return send_http_operation(op, session_manager, std::forward<Callback>(callback));
613
- });
614
- return std::monostate{};
615
- }
616
-
617
- auto defer_command(std::shared_ptr<pending_buffered_http_operation> pending_op,
618
- const std::shared_ptr<io::http_session_manager>& session_manager,
619
- buffered_free_form_http_request_callback&& callback) -> error_union
620
- {
621
- if (auto last_error = session_manager->last_bootstrap_error(); last_error.has_value()) {
622
- return last_error.value();
623
- }
624
- CB_LOG_DEBUG(
625
- R"(Adding pending HTTP operation to deferred queue: service={}, client_context_id={})",
626
- pending_op->request().service,
627
- pending_op->request().client_context_id);
628
- session_manager->add_to_deferred_queue([this,
629
- callback = std::move(callback),
630
- op = std::move(pending_op),
631
- session_manager](error_union err) mutable {
632
- if (!std::holds_alternative<std::monostate>(err)) {
633
- auto ec = std::holds_alternative<impl::bootstrap_error>(err)
634
- ? std::get<impl::bootstrap_error>(err).ec
635
- : std::get<std::error_code>(err);
636
- // The deferred operation was cancelled - currently this can happen due to closing the
637
- // cluster
638
- return callback({}, ec);
639
- }
640
-
641
- return send_http_operation(op, session_manager, std::move(callback));
642
- });
643
- return std::monostate{};
644
- }
645
- #endif
646
-
647
667
  asio::io_context& io_;
648
668
  core_sdk_shim shim_;
649
669
  std::shared_ptr<retry_strategy> default_retry_strategy_;
@@ -661,11 +681,7 @@ http_component::http_component(asio::io_context& io,
661
681
  auto
662
682
  http_component::do_http_request(const http_request& request,
663
683
  free_form_http_request_callback&& callback)
664
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
665
- -> tl::expected<std::shared_ptr<pending_operation>, error_union>
666
- #else
667
684
  -> tl::expected<std::shared_ptr<pending_operation>, std::error_code>
668
- #endif
669
685
  {
670
686
  return impl_->do_http_request(request, std::move(callback));
671
687
  }