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
@@ -17,7 +17,7 @@
17
17
 
18
18
  #pragma once
19
19
 
20
- #include <couchbase/build_config.hxx>
20
+ #include <couchbase/error_codes.hxx>
21
21
 
22
22
  #include "core/diagnostics.hxx"
23
23
  #include "core/origin.hxx"
@@ -29,19 +29,21 @@
29
29
  #include "http_streaming_parser.hxx"
30
30
  #include "http_streaming_response.hxx"
31
31
  #include "streams.hxx"
32
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
33
- #include "core/impl/bootstrap_error.hxx"
34
- #endif
35
32
 
36
33
  #include "core/tls_context_provider.hxx"
37
34
 
38
35
  #include <asio.hpp>
39
36
  #include <spdlog/fmt/bundled/chrono.h>
40
37
 
38
+ #include <atomic>
39
+ #include <cstddef>
40
+ #include <cstdint>
41
+ #include <deque>
41
42
  #include <memory>
42
43
  #include <optional>
43
44
  #include <string>
44
45
  #include <utility>
46
+ #include <vector>
45
47
 
46
48
  namespace couchbase::core::io
47
49
  {
@@ -78,7 +80,8 @@ public:
78
80
  origin& origin,
79
81
  std::string hostname,
80
82
  std::string service,
81
- http_context http_ctx);
83
+ http_context http_ctx,
84
+ std::uint64_t pool_generation);
82
85
 
83
86
  http_session(service_type type,
84
87
  std::string client_id,
@@ -88,7 +91,8 @@ public:
88
91
  origin& origin,
89
92
  std::string hostname,
90
93
  std::string service,
91
- http_context http_ctx);
94
+ http_context http_ctx,
95
+ std::uint64_t pool_generation);
92
96
 
93
97
  ~http_session();
94
98
 
@@ -96,11 +100,30 @@ public:
96
100
  [[nodiscard]] auto http_context() -> couchbase::core::http_context&;
97
101
  [[nodiscard]] auto remote_address() -> std::string;
98
102
  [[nodiscard]] auto local_address() -> std::string;
103
+ // Local and remote endpoints of the connection the current request was last handed to the socket
104
+ // on, empty before the first write. A resent request is recorded when its write starts on the new
105
+ // connection, not when that connection completes.
106
+ [[nodiscard]] auto dispatched_endpoints() -> std::pair<std::string, std::string>;
99
107
  [[nodiscard]] auto remote_endpoint() -> const asio::ip::tcp::endpoint&;
100
108
  [[nodiscard]] auto diag_info() -> diag::endpoint_diag_info;
101
109
  [[nodiscard]] auto log_prefix() -> std::string;
102
110
  [[nodiscard]] auto id() const -> const std::string&;
103
111
  [[nodiscard]] auto node_uuid() const -> const std::string&;
112
+ // The http_session_manager generation the session serves, fixed for its lifetime: the one it
113
+ // was created in, or for a failover replacement the one of the session it replaces. close()
114
+ // starts a new generation, and the manager neither lists nor reuses a session from an earlier
115
+ // one. A session outside any manager passes 0.
116
+ [[nodiscard]] auto pool_generation() const -> std::uint64_t;
117
+ // The manager's TLS epoch when this session was created. check_in stops a session from an earlier
118
+ // epoch: its connection may carry a client certificate that has since been replaced.
119
+ void set_tls_epoch(std::uint64_t epoch)
120
+ {
121
+ tls_epoch_ = epoch;
122
+ }
123
+ [[nodiscard]] auto tls_epoch() const -> std::uint64_t
124
+ {
125
+ return tls_epoch_;
126
+ }
104
127
  [[nodiscard]] auto credentials() const -> cluster_credentials;
105
128
  [[nodiscard]] auto is_connected() const -> bool;
106
129
  [[nodiscard]] auto type() const -> service_type;
@@ -110,25 +133,56 @@ public:
110
133
 
111
134
  void connect(utils::movable_function<void()>&& callback);
112
135
  void on_stop(std::function<void()> handler);
136
+ // Marks the session stopped and tears it down on the calling thread: releases the stream and
137
+ // posts its close to the strand, runs the connect callback, cancels the timers and the current
138
+ // response, and runs on_stop. Only the first call does anything; a later one returns at once,
139
+ // possibly before that teardown is done.
113
140
  void stop();
114
141
 
115
142
  auto keep_alive() const -> bool;
116
143
  auto is_stopped() const -> bool;
117
144
 
145
+ // A stop that another object has decided on but not yet executed. It is claimed while that
146
+ // object holds its own lock and executed after the lock is released, so between the two the
147
+ // session is still running and still reusable-looking. http_session_manager::check_in refuses a
148
+ // claimed session and check_out skips one. stop() does not set it, so a reader asking whether a
149
+ // session is owed or undergoing a stop tests is_stopped() as well. The claimer must call stop():
150
+ // a session claimed while checked out and never stopped stays in busy_sessions_ with its socket
151
+ // open until http_session_manager::close(), and one claimed while idle stays in idle_sessions_
152
+ // until its idle timer fires. http_session_manager::retire_sessions() claims idle sessions and
153
+ // posts their stop; on_stop unlists them. A separate flag rather than stopped_:
154
+ // stop() returns early when stopped_ is set, so claiming through that member would turn the
155
+ // teardown into a no-op.
156
+ void mark_stopping();
157
+ [[nodiscard]] auto is_stopping() const -> bool;
158
+
118
159
  template<typename Handler>
119
160
  void write_and_subscribe(io::http_request& request, Handler&& handler)
120
161
  {
121
- if (stopped_) {
122
- return;
123
- }
124
162
  {
125
163
  response_context ctx{ std::forward<Handler>(handler) };
126
164
  if (request.streaming) {
127
165
  ctx.parser.response.body.use_json_streaming(std::move(request.streaming.value()));
128
166
  }
129
- std::scoped_lock lock(current_response_mutex_);
130
- streaming_response_ = false;
131
- std::swap(current_response_, ctx);
167
+ bool installed = false;
168
+ {
169
+ // The stopped_ test shares the section that installs the context. stop() sets stopped_
170
+ // before its cancel_current_response() takes this mutex, so either the stop is seen here,
171
+ // or its cancel runs after the install and completes the request. Tested outside this
172
+ // section, a stop in between would leave an installed context that nothing completes.
173
+ const std::scoped_lock lock(current_response_mutex_);
174
+ if (!stopped_) {
175
+ streaming_response_ = false;
176
+ std::swap(current_response_, ctx);
177
+ installed = true;
178
+ }
179
+ }
180
+ if (!installed) {
181
+ // Stopped between check-out and here, for example by the peer's FIN on the liveness read
182
+ // or by http_session_manager::close(). A retryable cancellation, not a request left to
183
+ // its deadline.
184
+ return ctx.handler(errc::common::request_canceled, {});
185
+ }
132
186
  }
133
187
  if (request.headers["connection"] == "keep-alive") {
134
188
  keep_alive_ = true;
@@ -153,37 +207,41 @@ public:
153
207
  }
154
208
  write("\r\n");
155
209
  write(request.body);
210
+ remember_request(creds.uses_certificate());
156
211
  flush();
157
212
  }
158
213
 
159
- void write_and_stream(io::http_request& request,
160
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
161
- utils::movable_function<void(couchbase::core::error_union,
162
- io::http_streaming_response)> resp_handler,
163
- #else
164
- utils::movable_function<void(std::error_code, io::http_streaming_response)>
165
- resp_handler,
166
- #endif
167
- utils::movable_function<void()> stream_end_handler);
214
+ void write_and_stream(
215
+ io::http_request& request,
216
+ utils::movable_function<void(std::error_code, io::http_streaming_response)> resp_handler,
217
+ utils::movable_function<void()> stream_end_handler);
168
218
 
169
219
  void set_idle(std::chrono::milliseconds timeout);
170
220
  auto reset_idle() -> bool;
171
221
 
172
222
  /**
173
223
  * Reads some bytes from the body of the HTTP response. Should only be used in streaming mode.
224
+ * The read is initiated on the session strand, so the callback may run after this returns. At
225
+ * most one read is outstanding on the socket: a call made while one is in flight is queued and
226
+ * started when it completes, so callbacks for one response run in call order. Calls queued past
227
+ * the end of the response complete with no data and no more to come; calls queued behind a read
228
+ * that fails complete with its error.
174
229
  */
175
230
  void read_some(utils::movable_function<void(std::string, bool, std::error_code)>&& callback);
176
231
 
232
+ // Posts `handler` to the strand once the session holds no read_some() call. Called on the strand;
233
+ // every handler registered before then is posted. After stop(), a read in flight completes when
234
+ // its aborted socket read does, and the calls queued behind it complete after that; until then
235
+ // the session holds what they captured.
236
+ void on_reads_drained(utils::movable_function<void()>&& handler);
237
+
177
238
  private:
178
239
  struct streaming_response_context {
179
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
180
- utils::movable_function<void(couchbase::core::error_union, io::http_streaming_response)>
181
- resp_handler{};
182
- #else
183
240
  utils::movable_function<void(std::error_code, io::http_streaming_response)> resp_handler{};
184
- #endif
185
241
  utils::movable_function<void()> stream_end_handler{};
186
- std::optional<io::http_streaming_response> resp{};
242
+ // Copied from the response, which is not stored: the response's body holds this session, so
243
+ // storing it here would form a cycle that keeps both alive after the consumer drops the body.
244
+ bool must_close_connection{ false };
187
245
  http_streaming_parser parser{};
188
246
  bool complete{ false };
189
247
  };
@@ -198,23 +256,50 @@ private:
198
256
  void on_connect(const std::error_code& ec, asio::ip::tcp::resolver::results_type::iterator it);
199
257
  void initiate_connect();
200
258
  void do_read();
259
+ using read_callback = utils::movable_function<void(std::string, bool, std::error_code)>;
260
+ void do_read_some(read_callback&& callback);
261
+ void finish_read_some(std::error_code ec, bool response_ended);
262
+ void drain_ended_reads(std::shared_ptr<std::deque<read_callback>> reads);
263
+ void notify_reads_drained();
201
264
  void do_write();
202
265
  void write(const std::vector<std::uint8_t>& buf);
203
266
  void write(const std::string_view& buf);
204
267
  void flush();
205
268
  void cancel_current_response(std::error_code ec);
269
+ void remember_request(bool uses_certificate);
270
+ void record_dispatch();
271
+ auto resend_after_rejected_handshake(std::error_code ec) -> bool;
272
+ void reconnect_to_resend();
206
273
  void invoke_connect_callback();
207
274
 
208
275
  service_type type_{};
209
276
  std::string client_id_;
210
277
  std::string node_uuid_;
211
278
  std::string id_;
279
+ std::uint64_t pool_generation_;
280
+ std::atomic<std::uint64_t> tls_epoch_{ 0 };
212
281
  asio::io_context& ctx_;
213
282
  asio::ip::tcp::resolver resolver_;
214
283
  std::unique_ptr<stream_impl> stream_;
284
+ // The timers are built on the strand executor, and the resolve completion is bound to it: their
285
+ // handlers close stream_ and run the connect callback, serialised with the connect and read
286
+ // handlers that touch the same state.
215
287
  asio::steady_timer connect_deadline_timer_;
288
+ // The strand arms and cancels connect_deadline_timer_, and stop() cancels it on its calling
289
+ // thread. Arming tests stopped_ under this lock, as for retry_backoff_.
290
+ std::mutex connect_deadline_timer_mutex_{};
216
291
  asio::steady_timer idle_timer_;
292
+ // set_idle() and reset_idle() touch idle_timer_ under the manager's sessions_mutex_ from any
293
+ // thread, and stop() cancels it on its calling thread; an asio timer is not thread-safe.
294
+ std::mutex idle_timer_mutex_{};
217
295
  asio::steady_timer retry_backoff_;
296
+ // The strand arms retry_backoff_ and stop() cancels it on its calling thread; an asio timer is
297
+ // not thread-safe. Arming tests stopped_ under this lock, so a stop() either cancels the armed
298
+ // timer or makes the arming site return.
299
+ std::mutex retry_backoff_mutex_{};
300
+ // Only the first certificate refusal logs at warning: the resend repeats every reconnect_backoff
301
+ // until the deadline.
302
+ std::atomic_bool refusal_logged_{ false };
218
303
 
219
304
  core::origin& origin_;
220
305
  std::string hostname_;
@@ -222,9 +307,14 @@ private:
222
307
  std::string user_agent_;
223
308
 
224
309
  std::atomic_bool stopped_{ false };
310
+ std::atomic_bool stopping_{ false };
225
311
  std::atomic_bool connected_{ false };
226
312
  std::atomic_bool keep_alive_{ false };
227
313
  std::atomic_bool reading_{ false };
314
+ // True while the session is parked in the connection pool between requests. A
315
+ // read is kept armed in this state so a peer-initiated close is detected
316
+ // promptly (see set_idle()), rather than the dead socket being reused.
317
+ std::atomic_bool idle_{ false };
228
318
 
229
319
  utils::movable_function<void()> connect_callback_{};
230
320
  std::mutex connect_callback_mutex_{};
@@ -234,19 +324,46 @@ private:
234
324
  streaming_response_context current_streaming_response_{};
235
325
  bool streaming_response_{ false };
236
326
  std::mutex current_response_mutex_{};
237
- std::mutex read_some_mutex_{};
327
+
328
+ // Touched only on the strand. A read_some() arriving while one is in flight waits here, since
329
+ // both would read the socket into input_buffer_.
330
+ bool read_some_in_flight_{ false };
331
+ // Set while a streaming response's body is pulled through read_some(), from the head until the
332
+ // read that ends it; do_read() arms nothing meanwhile. Touched only on the strand.
333
+ bool body_pulled_{ false };
334
+ std::deque<read_callback> queued_reads_{};
335
+ // Reads moved out at a clean end and still completing through drain_ended_reads(). Touched only
336
+ // on the strand.
337
+ std::size_t ended_drains_{ 0 };
338
+ // Posted once read_some_in_flight_ is clear and ended_drains_ is zero. Touched only on the
339
+ // strand.
340
+ std::vector<utils::movable_function<void()>> reads_drained_{};
238
341
 
239
342
  std::array<std::uint8_t, 16384> input_buffer_{};
240
343
  std::vector<std::vector<std::uint8_t>> output_buffer_{};
344
+ // The first request written on a new connection, kept until the first byte of its response
345
+ // arrives. Guarded by output_buffer_mutex_.
346
+ std::vector<std::vector<std::uint8_t>> unanswered_request_{};
347
+ // Set by a connect, cleared by the first byte of a response.
348
+ std::atomic_bool fresh_connection_{ false };
241
349
  std::vector<std::vector<std::uint8_t>> writing_buffer_{};
242
350
  std::mutex output_buffer_mutex_{};
243
351
  std::mutex writing_buffer_mutex_{};
244
352
  asio::ip::tcp::resolver::results_type endpoints_{};
245
353
  http_session_info info_;
354
+ // Guards info_, dispatched_from_ and dispatched_to_.
246
355
  std::mutex info_mutex_{};
356
+ std::string dispatched_from_{};
357
+ std::string dispatched_to_{};
247
358
  couchbase::core::http_context http_ctx_;
248
359
 
249
- std::chrono::time_point<std::chrono::steady_clock> last_active_{};
250
- diag::endpoint_state state_{ diag::endpoint_state::disconnected };
360
+ // Read by diag_info() from any thread.
361
+ // Initialised with a value: libstdc++ 8 deletes atomic<T>::atomic() when T() is not noexcept.
362
+ std::atomic<std::chrono::steady_clock::time_point> last_active_{
363
+ std::chrono::steady_clock::time_point{}
364
+ };
365
+ // Written by stop() on its calling thread, by initiate_connect() on the connect() caller or on
366
+ // the strand, and by on_connect() on the strand; read by diag_info() from any thread.
367
+ std::atomic<diag::endpoint_state> state_{ diag::endpoint_state::disconnected };
251
368
  };
252
369
  } // namespace couchbase::core::io