couchbase 4.3.1 → 4.4.1-dev.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 (1104) hide show
  1. package/deps/couchbase-cxx-cache/mozilla-ca-bundle.crt +19 -32
  2. package/deps/couchbase-cxx-cache/mozilla-ca-bundle.sha256 +1 -1
  3. package/deps/couchbase-cxx-client/CMakeLists.txt +16 -9
  4. package/deps/couchbase-cxx-client/README.md +39 -44
  5. package/deps/couchbase-cxx-client/cmake/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +3 -4
  6. package/deps/couchbase-cxx-client/cmake/CompilerWarnings.cmake +2 -1
  7. package/deps/couchbase-cxx-client/cmake/Packaging.cmake +41 -0
  8. package/deps/couchbase-cxx-client/cmake/Sanitizers.cmake +1 -0
  9. package/deps/couchbase-cxx-client/cmake/VersionInfo.cmake +5 -5
  10. package/deps/couchbase-cxx-client/cmake/build_version.hxx.in +1 -0
  11. package/deps/couchbase-cxx-client/cmake/couchbase-cxx-client.pc.in +10 -0
  12. package/deps/couchbase-cxx-client/cmake/test_boringssl.cxx +1 -1
  13. package/deps/couchbase-cxx-client/cmake/test_openssl.cxx +1 -1
  14. package/deps/couchbase-cxx-client/core/agent.cxx +353 -304
  15. package/deps/couchbase-cxx-client/core/agent.hxx +94 -76
  16. package/deps/couchbase-cxx-client/core/agent_config.cxx +9 -8
  17. package/deps/couchbase-cxx-client/core/agent_config.hxx +7 -7
  18. package/deps/couchbase-cxx-client/core/agent_group.cxx +132 -120
  19. package/deps/couchbase-cxx-client/core/agent_group.hxx +26 -22
  20. package/deps/couchbase-cxx-client/core/agent_group_config.cxx +8 -7
  21. package/deps/couchbase-cxx-client/core/agent_group_config.hxx +6 -6
  22. package/deps/couchbase-cxx-client/core/agent_unit_test_api.hxx +6 -6
  23. package/deps/couchbase-cxx-client/core/analytics_query_options.cxx +21 -21
  24. package/deps/couchbase-cxx-client/core/analytics_query_options.hxx +19 -18
  25. package/deps/couchbase-cxx-client/core/analytics_scan_consistency.hxx +2 -2
  26. package/deps/couchbase-cxx-client/core/bucket.cxx +848 -776
  27. package/deps/couchbase-cxx-client/core/bucket.hxx +151 -139
  28. package/deps/couchbase-cxx-client/core/capella_ca.hxx +20 -19
  29. package/deps/couchbase-cxx-client/core/cluster.cxx +1240 -927
  30. package/deps/couchbase-cxx-client/core/cluster.hxx +254 -167
  31. package/deps/couchbase-cxx-client/core/cluster_agent.cxx +7 -7
  32. package/deps/couchbase-cxx-client/core/cluster_agent.hxx +4 -4
  33. package/deps/couchbase-cxx-client/core/cluster_agent_config.cxx +8 -7
  34. package/deps/couchbase-cxx-client/core/cluster_agent_config.hxx +6 -6
  35. package/deps/couchbase-cxx-client/core/cluster_options.cxx +17 -17
  36. package/deps/couchbase-cxx-client/core/cluster_options.hxx +50 -47
  37. package/deps/couchbase-cxx-client/core/cluster_state.hxx +3 -3
  38. package/deps/couchbase-cxx-client/core/collection_id_cache_entry.hxx +5 -4
  39. package/deps/couchbase-cxx-client/core/collections_component.cxx +372 -329
  40. package/deps/couchbase-cxx-client/core/collections_component.hxx +17 -13
  41. package/deps/couchbase-cxx-client/core/collections_component_unit_test_api.hxx +6 -6
  42. package/deps/couchbase-cxx-client/core/collections_options.hxx +29 -27
  43. package/deps/couchbase-cxx-client/core/config_listener.hxx +3 -3
  44. package/deps/couchbase-cxx-client/core/config_profile.hxx +3 -3
  45. package/deps/couchbase-cxx-client/core/config_profiles.cxx +31 -31
  46. package/deps/couchbase-cxx-client/core/config_profiles.hxx +19 -19
  47. package/deps/couchbase-cxx-client/core/core_sdk_shim.cxx +2 -1
  48. package/deps/couchbase-cxx-client/core/core_sdk_shim.hxx +2 -2
  49. package/deps/couchbase-cxx-client/core/crud_component.cxx +310 -276
  50. package/deps/couchbase-cxx-client/core/crud_component.hxx +21 -15
  51. package/deps/couchbase-cxx-client/core/crud_options.hxx +361 -354
  52. package/deps/couchbase-cxx-client/core/crypto/cbcrypto.cc +732 -627
  53. package/deps/couchbase-cxx-client/core/crypto/cbcrypto.h +12 -3
  54. package/deps/couchbase-cxx-client/core/design_document_namespace.hxx +2 -2
  55. package/deps/couchbase-cxx-client/core/design_document_namespace_fmt.hxx +18 -18
  56. package/deps/couchbase-cxx-client/core/diagnostics.hxx +44 -44
  57. package/deps/couchbase-cxx-client/core/diagnostics_fmt.hxx +76 -76
  58. package/deps/couchbase-cxx-client/core/diagnostics_json.hxx +61 -60
  59. package/deps/couchbase-cxx-client/core/diagntostics_options.hxx +14 -14
  60. package/deps/couchbase-cxx-client/core/dispatcher.cxx +4 -3
  61. package/deps/couchbase-cxx-client/core/dispatcher.hxx +8 -7
  62. package/deps/couchbase-cxx-client/core/document_id.cxx +37 -34
  63. package/deps/couchbase-cxx-client/core/document_id.hxx +87 -86
  64. package/deps/couchbase-cxx-client/core/document_id_fmt.hxx +10 -10
  65. package/deps/couchbase-cxx-client/core/durability_options.hxx +50 -49
  66. package/deps/couchbase-cxx-client/core/error_context/analytics.hxx +18 -18
  67. package/deps/couchbase-cxx-client/core/error_context/analytics_json.hxx +115 -0
  68. package/deps/couchbase-cxx-client/core/error_context/base_error_context.hxx +184 -0
  69. package/deps/couchbase-cxx-client/core/error_context/http.hxx +14 -14
  70. package/deps/couchbase-cxx-client/core/error_context/http_json.hxx +90 -0
  71. package/deps/couchbase-cxx-client/core/error_context/internal_tof_metadata_json.hxx +36 -0
  72. package/deps/couchbase-cxx-client/core/error_context/key_value.cxx +27 -27
  73. package/deps/couchbase-cxx-client/core/error_context/key_value.hxx +41 -38
  74. package/deps/couchbase-cxx-client/core/error_context/key_value_error_context.hxx +235 -0
  75. package/deps/couchbase-cxx-client/core/error_context/key_value_error_map_attribute.hxx +142 -0
  76. package/deps/couchbase-cxx-client/core/error_context/key_value_error_map_info.hxx +139 -0
  77. package/deps/couchbase-cxx-client/core/error_context/key_value_extended_error_info.hxx +86 -0
  78. package/deps/couchbase-cxx-client/core/error_context/key_value_json.hxx +83 -0
  79. package/deps/couchbase-cxx-client/core/error_context/key_value_status_code.hxx +109 -0
  80. package/deps/couchbase-cxx-client/core/error_context/query.hxx +18 -18
  81. package/deps/couchbase-cxx-client/core/error_context/query_error_context.hxx +150 -0
  82. package/deps/couchbase-cxx-client/core/error_context/query_json.hxx +114 -0
  83. package/deps/couchbase-cxx-client/core/error_context/query_public_json.hxx +84 -0
  84. package/deps/couchbase-cxx-client/core/error_context/search.hxx +17 -17
  85. package/deps/couchbase-cxx-client/core/error_context/search_json.hxx +101 -0
  86. package/deps/couchbase-cxx-client/core/error_context/subdocument_error_context.hxx +147 -0
  87. package/deps/couchbase-cxx-client/core/error_context/subdocument_json.hxx +48 -0
  88. package/deps/couchbase-cxx-client/{couchbase → core/error_context}/transaction_error_context.hxx +22 -22
  89. package/deps/couchbase-cxx-client/core/error_context/transaction_op_error_context.hxx +79 -0
  90. package/deps/couchbase-cxx-client/core/error_context/view.hxx +17 -17
  91. package/deps/couchbase-cxx-client/core/fmt/key_value_error_map_attribute.hxx +100 -0
  92. package/deps/couchbase-cxx-client/{couchbase → core}/fmt/key_value_extended_error_info.hxx +20 -20
  93. package/deps/couchbase-cxx-client/core/fmt/key_value_status_code.hxx +269 -0
  94. package/deps/couchbase-cxx-client/core/free_form_http_request.cxx +26 -26
  95. package/deps/couchbase-cxx-client/core/free_form_http_request.hxx +34 -33
  96. package/deps/couchbase-cxx-client/core/impl/analytics.cxx +111 -131
  97. package/deps/couchbase-cxx-client/core/impl/analytics.hxx +5 -7
  98. package/deps/couchbase-cxx-client/core/impl/analytics_error_category.cxx +29 -28
  99. package/deps/couchbase-cxx-client/core/impl/analytics_index_manager.cxx +615 -516
  100. package/deps/couchbase-cxx-client/core/impl/best_effort_retry_strategy.cxx +53 -50
  101. package/deps/couchbase-cxx-client/core/impl/binary_collection.cxx +346 -285
  102. package/deps/couchbase-cxx-client/core/impl/boolean_field_query.cxx +10 -10
  103. package/deps/couchbase-cxx-client/core/impl/boolean_query.cxx +27 -27
  104. package/deps/couchbase-cxx-client/core/impl/bootstrap_state_listener.hxx +6 -6
  105. package/deps/couchbase-cxx-client/core/impl/bucket.cxx +39 -34
  106. package/deps/couchbase-cxx-client/core/impl/bucket_manager.cxx +354 -313
  107. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +430 -325
  108. package/deps/couchbase-cxx-client/core/impl/collection.cxx +1033 -1187
  109. package/deps/couchbase-cxx-client/core/impl/collection_manager.cxx +201 -170
  110. package/deps/couchbase-cxx-client/core/impl/common_error_category.cxx +58 -55
  111. package/deps/couchbase-cxx-client/core/impl/configuration_profiles_registry.cxx +46 -32
  112. package/deps/couchbase-cxx-client/core/impl/conjunction_query.cxx +17 -17
  113. package/deps/couchbase-cxx-client/core/impl/date_range.cxx +24 -20
  114. package/deps/couchbase-cxx-client/core/impl/date_range_facet.cxx +22 -22
  115. package/deps/couchbase-cxx-client/core/impl/date_range_facet_result.cxx +6 -6
  116. package/deps/couchbase-cxx-client/core/impl/date_range_query.cxx +50 -48
  117. package/deps/couchbase-cxx-client/core/impl/diagnostics.cxx +211 -198
  118. package/deps/couchbase-cxx-client/core/impl/diagnostics.hxx +7 -6
  119. package/deps/couchbase-cxx-client/core/impl/disjunction_query.cxx +18 -17
  120. package/deps/couchbase-cxx-client/core/impl/dns_srv_tracker.cxx +92 -75
  121. package/deps/couchbase-cxx-client/core/impl/dns_srv_tracker.hxx +24 -20
  122. package/deps/couchbase-cxx-client/core/impl/doc_id_query.cxx +9 -9
  123. package/deps/couchbase-cxx-client/core/impl/encoded_search_facet.hxx +2 -2
  124. package/deps/couchbase-cxx-client/core/impl/encoded_search_query.hxx +2 -2
  125. package/deps/couchbase-cxx-client/core/impl/encoded_search_sort.hxx +2 -2
  126. package/deps/couchbase-cxx-client/core/impl/error.cxx +171 -0
  127. package/deps/couchbase-cxx-client/core/impl/error.hxx +64 -0
  128. package/deps/couchbase-cxx-client/core/impl/error_context.cxx +56 -0
  129. package/deps/couchbase-cxx-client/core/impl/expiry.cxx +66 -53
  130. package/deps/couchbase-cxx-client/core/impl/fail_fast_retry_strategy.cxx +5 -4
  131. package/deps/couchbase-cxx-client/core/impl/field_level_encryption_error_category.cxx +30 -28
  132. package/deps/couchbase-cxx-client/core/impl/geo_bounding_box_query.cxx +17 -17
  133. package/deps/couchbase-cxx-client/core/impl/geo_distance_query.cxx +14 -14
  134. package/deps/couchbase-cxx-client/core/impl/geo_polygon_query.cxx +17 -17
  135. package/deps/couchbase-cxx-client/core/impl/get_all_replicas.hxx +26 -22
  136. package/deps/couchbase-cxx-client/core/impl/get_any_replica.hxx +25 -23
  137. package/deps/couchbase-cxx-client/core/impl/get_replica.cxx +18 -15
  138. package/deps/couchbase-cxx-client/core/impl/get_replica.hxx +23 -18
  139. package/deps/couchbase-cxx-client/core/impl/internal_date_range_facet_result.cxx +16 -14
  140. package/deps/couchbase-cxx-client/core/impl/internal_date_range_facet_result.hxx +16 -15
  141. package/deps/couchbase-cxx-client/core/impl/internal_error_context.cxx +79 -0
  142. package/deps/couchbase-cxx-client/core/impl/internal_error_context.hxx +52 -0
  143. package/deps/couchbase-cxx-client/core/impl/internal_numeric_range_facet_result.cxx +18 -15
  144. package/deps/couchbase-cxx-client/core/impl/internal_numeric_range_facet_result.hxx +16 -15
  145. package/deps/couchbase-cxx-client/core/impl/internal_scan_result.hxx +7 -7
  146. package/deps/couchbase-cxx-client/core/impl/internal_search_error_context.cxx +25 -22
  147. package/deps/couchbase-cxx-client/core/impl/internal_search_error_context.hxx +32 -31
  148. package/deps/couchbase-cxx-client/core/impl/internal_search_meta_data.cxx +15 -13
  149. package/deps/couchbase-cxx-client/core/impl/internal_search_meta_data.hxx +10 -9
  150. package/deps/couchbase-cxx-client/core/impl/internal_search_result.cxx +30 -22
  151. package/deps/couchbase-cxx-client/core/impl/internal_search_result.hxx +10 -9
  152. package/deps/couchbase-cxx-client/core/impl/internal_search_row.cxx +10 -10
  153. package/deps/couchbase-cxx-client/core/impl/internal_search_row.hxx +16 -16
  154. package/deps/couchbase-cxx-client/core/impl/internal_search_row_location.hxx +2 -2
  155. package/deps/couchbase-cxx-client/core/impl/internal_search_row_locations.cxx +68 -65
  156. package/deps/couchbase-cxx-client/core/impl/internal_search_row_locations.hxx +16 -13
  157. package/deps/couchbase-cxx-client/core/impl/internal_term_facet_result.cxx +16 -14
  158. package/deps/couchbase-cxx-client/core/impl/internal_term_facet_result.hxx +15 -15
  159. package/deps/couchbase-cxx-client/core/impl/key_value_error_category.cxx +73 -72
  160. package/deps/couchbase-cxx-client/core/impl/key_value_error_context.cxx +65 -65
  161. package/deps/couchbase-cxx-client/core/impl/logger.cxx +91 -0
  162. package/deps/couchbase-cxx-client/core/impl/lookup_in_all_replicas.hxx +32 -29
  163. package/deps/couchbase-cxx-client/core/impl/lookup_in_any_replica.hxx +33 -29
  164. package/deps/couchbase-cxx-client/core/impl/lookup_in_replica.cxx +75 -68
  165. package/deps/couchbase-cxx-client/core/impl/lookup_in_replica.hxx +30 -26
  166. package/deps/couchbase-cxx-client/core/impl/management_error_category.cxx +41 -40
  167. package/deps/couchbase-cxx-client/core/impl/match_all_query.cxx +6 -6
  168. package/deps/couchbase-cxx-client/core/impl/match_none_query.cxx +6 -6
  169. package/deps/couchbase-cxx-client/core/impl/match_phrase_query.cxx +13 -13
  170. package/deps/couchbase-cxx-client/core/impl/match_query.cxx +28 -28
  171. package/deps/couchbase-cxx-client/core/impl/network_error_category.cxx +39 -38
  172. package/deps/couchbase-cxx-client/core/impl/numeric_range.cxx +6 -6
  173. package/deps/couchbase-cxx-client/core/impl/numeric_range_facet.cxx +22 -22
  174. package/deps/couchbase-cxx-client/core/impl/numeric_range_facet_result.cxx +6 -6
  175. package/deps/couchbase-cxx-client/core/impl/numeric_range_query.cxx +22 -22
  176. package/deps/couchbase-cxx-client/core/impl/observe_poll.cxx +294 -277
  177. package/deps/couchbase-cxx-client/core/impl/observe_poll.hxx +1 -1
  178. package/deps/couchbase-cxx-client/core/impl/observe_seqno.cxx +21 -18
  179. package/deps/couchbase-cxx-client/core/impl/observe_seqno.hxx +31 -26
  180. package/deps/couchbase-cxx-client/core/impl/phrase_query.cxx +10 -10
  181. package/deps/couchbase-cxx-client/core/impl/prefix_query.cxx +10 -10
  182. package/deps/couchbase-cxx-client/core/impl/query.cxx +163 -154
  183. package/deps/couchbase-cxx-client/core/impl/query.hxx +6 -7
  184. package/deps/couchbase-cxx-client/core/impl/query_error_category.cxx +22 -21
  185. package/deps/couchbase-cxx-client/core/impl/query_error_context.cxx +45 -45
  186. package/deps/couchbase-cxx-client/core/impl/query_index_manager.cxx +488 -408
  187. package/deps/couchbase-cxx-client/core/impl/query_string_query.cxx +7 -7
  188. package/deps/couchbase-cxx-client/core/impl/regexp_query.cxx +10 -10
  189. package/deps/couchbase-cxx-client/core/impl/replica_utils.cxx +66 -0
  190. package/deps/couchbase-cxx-client/core/impl/replica_utils.hxx +48 -0
  191. package/deps/couchbase-cxx-client/core/impl/retry_action.cxx +3 -3
  192. package/deps/couchbase-cxx-client/core/impl/retry_reason.cxx +129 -56
  193. package/deps/couchbase-cxx-client/core/impl/retry_reason.hxx +28 -0
  194. package/deps/couchbase-cxx-client/core/impl/scan_result.cxx +53 -49
  195. package/deps/couchbase-cxx-client/core/impl/scope.cxx +103 -94
  196. package/deps/couchbase-cxx-client/core/impl/search.cxx +139 -130
  197. package/deps/couchbase-cxx-client/core/impl/search.hxx +4 -4
  198. package/deps/couchbase-cxx-client/core/impl/search_error_category.cxx +18 -17
  199. package/deps/couchbase-cxx-client/core/impl/search_index_manager.cxx +492 -390
  200. package/deps/couchbase-cxx-client/core/impl/search_meta_data.cxx +3 -3
  201. package/deps/couchbase-cxx-client/core/impl/search_request.cxx +78 -78
  202. package/deps/couchbase-cxx-client/core/impl/search_result.cxx +5 -5
  203. package/deps/couchbase-cxx-client/core/impl/search_row.cxx +7 -7
  204. package/deps/couchbase-cxx-client/core/impl/search_row_location.cxx +9 -8
  205. package/deps/couchbase-cxx-client/core/impl/search_row_locations.cxx +8 -7
  206. package/deps/couchbase-cxx-client/core/impl/search_sort_field.cxx +53 -53
  207. package/deps/couchbase-cxx-client/core/impl/search_sort_geo_distance.cxx +49 -48
  208. package/deps/couchbase-cxx-client/core/impl/search_sort_id.cxx +10 -10
  209. package/deps/couchbase-cxx-client/core/impl/search_sort_score.cxx +10 -10
  210. package/deps/couchbase-cxx-client/core/impl/streaming_json_lexer_error_category.cxx +70 -68
  211. package/deps/couchbase-cxx-client/core/impl/subdoc/array_add_unique.cxx +6 -6
  212. package/deps/couchbase-cxx-client/core/impl/subdoc/array_append.cxx +6 -6
  213. package/deps/couchbase-cxx-client/core/impl/subdoc/array_insert.cxx +6 -6
  214. package/deps/couchbase-cxx-client/core/impl/subdoc/array_prepend.cxx +6 -6
  215. package/deps/couchbase-cxx-client/core/impl/subdoc/command.hxx +5 -5
  216. package/deps/couchbase-cxx-client/core/impl/subdoc/command_bundle.hxx +11 -11
  217. package/deps/couchbase-cxx-client/core/impl/subdoc/count.cxx +6 -6
  218. package/deps/couchbase-cxx-client/core/impl/subdoc/counter.cxx +6 -6
  219. package/deps/couchbase-cxx-client/core/impl/subdoc/exists.cxx +6 -6
  220. package/deps/couchbase-cxx-client/core/impl/subdoc/get.cxx +6 -6
  221. package/deps/couchbase-cxx-client/core/impl/subdoc/insert.cxx +6 -6
  222. package/deps/couchbase-cxx-client/core/impl/subdoc/join_values.cxx +25 -25
  223. package/deps/couchbase-cxx-client/core/impl/subdoc/lookup_in_macro.cxx +61 -60
  224. package/deps/couchbase-cxx-client/core/impl/subdoc/lookup_in_specs.cxx +9 -9
  225. package/deps/couchbase-cxx-client/core/impl/subdoc/mutate_in_macro.cxx +48 -39
  226. package/deps/couchbase-cxx-client/core/impl/subdoc/mutate_in_specs.cxx +9 -9
  227. package/deps/couchbase-cxx-client/core/impl/subdoc/opcode.hxx +16 -16
  228. package/deps/couchbase-cxx-client/core/impl/subdoc/path_flags.hxx +40 -17
  229. package/deps/couchbase-cxx-client/core/impl/subdoc/remove.cxx +6 -6
  230. package/deps/couchbase-cxx-client/core/impl/subdoc/replace.cxx +6 -6
  231. package/deps/couchbase-cxx-client/core/impl/subdoc/upsert.cxx +6 -6
  232. package/deps/couchbase-cxx-client/core/impl/term_facet.cxx +8 -8
  233. package/deps/couchbase-cxx-client/core/impl/term_facet_result.cxx +6 -6
  234. package/deps/couchbase-cxx-client/core/impl/term_query.cxx +25 -25
  235. package/deps/couchbase-cxx-client/core/impl/term_range_query.cxx +22 -22
  236. package/deps/couchbase-cxx-client/core/impl/transaction_error_category.cxx +21 -20
  237. package/deps/couchbase-cxx-client/core/impl/transaction_get_result.cxx +41 -30
  238. package/deps/couchbase-cxx-client/core/impl/transaction_op_error_category.cxx +55 -56
  239. package/deps/couchbase-cxx-client/core/impl/vector_query.cxx +15 -10
  240. package/deps/couchbase-cxx-client/core/impl/vector_search.cxx +9 -9
  241. package/deps/couchbase-cxx-client/core/impl/view_error_category.cxx +17 -16
  242. package/deps/couchbase-cxx-client/core/impl/wildcard_query.cxx +10 -10
  243. package/deps/couchbase-cxx-client/core/impl/with_legacy_durability.hxx +30 -29
  244. package/deps/couchbase-cxx-client/core/io/dns_client.cxx +257 -232
  245. package/deps/couchbase-cxx-client/core/io/dns_client.hxx +19 -18
  246. package/deps/couchbase-cxx-client/core/io/dns_codec.hxx +156 -154
  247. package/deps/couchbase-cxx-client/core/io/dns_config.cxx +114 -109
  248. package/deps/couchbase-cxx-client/core/io/dns_config.hxx +15 -13
  249. package/deps/couchbase-cxx-client/core/io/dns_message.hxx +365 -342
  250. package/deps/couchbase-cxx-client/core/io/http_command.hxx +155 -134
  251. package/deps/couchbase-cxx-client/core/io/http_context.hxx +5 -5
  252. package/deps/couchbase-cxx-client/core/io/http_message.hxx +75 -71
  253. package/deps/couchbase-cxx-client/core/io/http_parser.cxx +70 -67
  254. package/deps/couchbase-cxx-client/core/io/http_parser.hxx +18 -18
  255. package/deps/couchbase-cxx-client/core/io/http_session.hxx +620 -520
  256. package/deps/couchbase-cxx-client/core/io/http_session_manager.hxx +406 -315
  257. package/deps/couchbase-cxx-client/core/io/http_traits.hxx +7 -0
  258. package/deps/couchbase-cxx-client/core/io/ip_protocol.hxx +3 -3
  259. package/deps/couchbase-cxx-client/core/io/mcbp_command.hxx +298 -278
  260. package/deps/couchbase-cxx-client/core/io/mcbp_context.hxx +7 -6
  261. package/deps/couchbase-cxx-client/core/io/mcbp_message.cxx +8 -8
  262. package/deps/couchbase-cxx-client/core/io/mcbp_message.hxx +19 -19
  263. package/deps/couchbase-cxx-client/core/io/mcbp_parser.cxx +60 -51
  264. package/deps/couchbase-cxx-client/core/io/mcbp_parser.hxx +21 -17
  265. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +1769 -1616
  266. package/deps/couchbase-cxx-client/core/io/mcbp_session.hxx +63 -57
  267. package/deps/couchbase-cxx-client/core/io/query_cache.hxx +34 -34
  268. package/deps/couchbase-cxx-client/core/io/retry_context.hxx +45 -45
  269. package/deps/couchbase-cxx-client/core/io/retry_orchestrator.hxx +52 -42
  270. package/deps/couchbase-cxx-client/core/io/streams.hxx +210 -193
  271. package/deps/couchbase-cxx-client/core/json_string.hxx +47 -47
  272. package/deps/couchbase-cxx-client/core/key_value_config.cxx +8 -8
  273. package/deps/couchbase-cxx-client/core/key_value_config.hxx +12 -11
  274. package/deps/couchbase-cxx-client/core/logger/configuration.hxx +35 -35
  275. package/deps/couchbase-cxx-client/core/logger/custom_rotating_file_sink.cxx +73 -72
  276. package/deps/couchbase-cxx-client/core/logger/custom_rotating_file_sink.hxx +20 -18
  277. package/deps/couchbase-cxx-client/core/logger/level.hxx +9 -1
  278. package/deps/couchbase-cxx-client/core/logger/logger.cxx +279 -252
  279. package/deps/couchbase-cxx-client/core/logger/logger.hxx +110 -58
  280. package/deps/couchbase-cxx-client/core/management/analytics_dataset.hxx +4 -4
  281. package/deps/couchbase-cxx-client/core/management/analytics_index.hxx +4 -4
  282. package/deps/couchbase-cxx-client/core/management/analytics_link_azure_blob_external.cxx +35 -33
  283. package/deps/couchbase-cxx-client/core/management/analytics_link_azure_blob_external.hxx +36 -35
  284. package/deps/couchbase-cxx-client/core/management/analytics_link_azure_blob_external_json.hxx +24 -20
  285. package/deps/couchbase-cxx-client/core/management/analytics_link_couchbase_remote.cxx +66 -65
  286. package/deps/couchbase-cxx-client/core/management/analytics_link_couchbase_remote.hxx +77 -70
  287. package/deps/couchbase-cxx-client/core/management/analytics_link_couchbase_remote_json.hxx +38 -32
  288. package/deps/couchbase-cxx-client/core/management/analytics_link_s3_external.cxx +26 -25
  289. package/deps/couchbase-cxx-client/core/management/analytics_link_s3_external.hxx +30 -30
  290. package/deps/couchbase-cxx-client/core/management/analytics_link_s3_external_json.hxx +18 -16
  291. package/deps/couchbase-cxx-client/core/management/bucket_settings.hxx +109 -91
  292. package/deps/couchbase-cxx-client/core/management/bucket_settings_json.hxx +112 -94
  293. package/deps/couchbase-cxx-client/core/management/design_document.hxx +9 -9
  294. package/deps/couchbase-cxx-client/core/management/eventing_function.hxx +124 -121
  295. package/deps/couchbase-cxx-client/core/management/eventing_function_json.hxx +228 -184
  296. package/deps/couchbase-cxx-client/core/management/eventing_status.hxx +41 -41
  297. package/deps/couchbase-cxx-client/core/management/eventing_status_json.hxx +53 -45
  298. package/deps/couchbase-cxx-client/core/management/rbac.hxx +33 -28
  299. package/deps/couchbase-cxx-client/core/management/rbac_fmt.hxx +21 -21
  300. package/deps/couchbase-cxx-client/core/management/rbac_json.hxx +132 -125
  301. package/deps/couchbase-cxx-client/core/management/search_index.cxx +79 -0
  302. package/deps/couchbase-cxx-client/core/management/search_index.hxx +11 -10
  303. package/deps/couchbase-cxx-client/core/management/search_index_json.hxx +27 -26
  304. package/deps/couchbase-cxx-client/core/mcbp/barrier_frame.hxx +4 -3
  305. package/deps/couchbase-cxx-client/core/mcbp/big_endian.cxx +22 -22
  306. package/deps/couchbase-cxx-client/core/mcbp/buffer_writer.cxx +22 -19
  307. package/deps/couchbase-cxx-client/core/mcbp/buffer_writer.hxx +9 -9
  308. package/deps/couchbase-cxx-client/core/mcbp/codec.cxx +419 -397
  309. package/deps/couchbase-cxx-client/core/mcbp/codec.hxx +14 -12
  310. package/deps/couchbase-cxx-client/core/mcbp/command_code.cxx +48 -48
  311. package/deps/couchbase-cxx-client/core/mcbp/completion_token.hxx +33 -33
  312. package/deps/couchbase-cxx-client/core/mcbp/datatype.hxx +3 -3
  313. package/deps/couchbase-cxx-client/core/mcbp/durability_level.hxx +8 -7
  314. package/deps/couchbase-cxx-client/core/mcbp/durability_level_frame.hxx +3 -2
  315. package/deps/couchbase-cxx-client/core/mcbp/durability_timeout_frame.hxx +4 -3
  316. package/deps/couchbase-cxx-client/core/mcbp/open_tracing_frame.hxx +3 -2
  317. package/deps/couchbase-cxx-client/core/mcbp/operation_consumer.cxx +3 -3
  318. package/deps/couchbase-cxx-client/core/mcbp/operation_consumer.hxx +9 -9
  319. package/deps/couchbase-cxx-client/core/mcbp/operation_queue.cxx +76 -70
  320. package/deps/couchbase-cxx-client/core/mcbp/operation_queue.hxx +18 -17
  321. package/deps/couchbase-cxx-client/core/mcbp/packet.cxx +65 -51
  322. package/deps/couchbase-cxx-client/core/mcbp/packet.hxx +25 -25
  323. package/deps/couchbase-cxx-client/core/mcbp/preserve_expiry_frame.hxx +4 -2
  324. package/deps/couchbase-cxx-client/core/mcbp/queue_callback.hxx +3 -2
  325. package/deps/couchbase-cxx-client/core/mcbp/queue_request.cxx +65 -62
  326. package/deps/couchbase-cxx-client/core/mcbp/queue_request.hxx +54 -52
  327. package/deps/couchbase-cxx-client/core/mcbp/queue_request_connection_info.hxx +3 -3
  328. package/deps/couchbase-cxx-client/core/mcbp/queue_response.hxx +7 -7
  329. package/deps/couchbase-cxx-client/core/mcbp/read_units_frame.hxx +3 -2
  330. package/deps/couchbase-cxx-client/core/mcbp/server_duration.cxx +7 -7
  331. package/deps/couchbase-cxx-client/core/mcbp/server_duration_frame.hxx +3 -2
  332. package/deps/couchbase-cxx-client/core/mcbp/stream_id_frame.hxx +3 -2
  333. package/deps/couchbase-cxx-client/core/mcbp/unsupported_frame.hxx +4 -3
  334. package/deps/couchbase-cxx-client/core/mcbp/user_impersonation_frame.hxx +1 -1
  335. package/deps/couchbase-cxx-client/core/mcbp/write_units_frame.hxx +3 -2
  336. package/deps/couchbase-cxx-client/core/meta/features.hxx +58 -0
  337. package/deps/couchbase-cxx-client/core/meta/version.cxx +255 -204
  338. package/deps/couchbase-cxx-client/core/meta/version.hxx +31 -20
  339. package/deps/couchbase-cxx-client/core/metrics/logging_meter.cxx +160 -154
  340. package/deps/couchbase-cxx-client/core/metrics/logging_meter.hxx +16 -15
  341. package/deps/couchbase-cxx-client/core/metrics/logging_meter_options.hxx +1 -1
  342. package/deps/couchbase-cxx-client/core/metrics/noop_meter.hxx +14 -13
  343. package/deps/couchbase-cxx-client/core/mozilla_ca_bundle.hxx +2 -2
  344. package/deps/couchbase-cxx-client/core/n1ql_query_options.cxx +31 -31
  345. package/deps/couchbase-cxx-client/core/n1ql_query_options.hxx +22 -21
  346. package/deps/couchbase-cxx-client/core/operation_map.hxx +3 -3
  347. package/deps/couchbase-cxx-client/core/operations/document_analytics.cxx +187 -176
  348. package/deps/couchbase-cxx-client/core/operations/document_analytics.hxx +79 -71
  349. package/deps/couchbase-cxx-client/core/operations/document_append.cxx +18 -15
  350. package/deps/couchbase-cxx-client/core/operations/document_append.hxx +18 -16
  351. package/deps/couchbase-cxx-client/core/operations/document_decrement.cxx +26 -23
  352. package/deps/couchbase-cxx-client/core/operations/document_decrement.hxx +24 -20
  353. package/deps/couchbase-cxx-client/core/operations/document_exists.cxx +23 -21
  354. package/deps/couchbase-cxx-client/core/operations/document_exists.hxx +25 -23
  355. package/deps/couchbase-cxx-client/core/operations/document_get.cxx +17 -15
  356. package/deps/couchbase-cxx-client/core/operations/document_get.hxx +17 -15
  357. package/deps/couchbase-cxx-client/core/operations/document_get_all_replicas.hxx +121 -92
  358. package/deps/couchbase-cxx-client/core/operations/document_get_and_lock.cxx +19 -16
  359. package/deps/couchbase-cxx-client/core/operations/document_get_and_lock.hxx +21 -17
  360. package/deps/couchbase-cxx-client/core/operations/document_get_and_touch.cxx +19 -16
  361. package/deps/couchbase-cxx-client/core/operations/document_get_and_touch.hxx +22 -18
  362. package/deps/couchbase-cxx-client/core/operations/document_get_any_replica.hxx +111 -82
  363. package/deps/couchbase-cxx-client/core/operations/document_get_projected.cxx +193 -184
  364. package/deps/couchbase-cxx-client/core/operations/document_get_projected.hxx +25 -21
  365. package/deps/couchbase-cxx-client/core/operations/document_increment.cxx +26 -23
  366. package/deps/couchbase-cxx-client/core/operations/document_increment.hxx +24 -20
  367. package/deps/couchbase-cxx-client/core/operations/document_insert.cxx +23 -20
  368. package/deps/couchbase-cxx-client/core/operations/document_insert.hxx +20 -18
  369. package/deps/couchbase-cxx-client/core/operations/document_lookup_in.cxx +80 -67
  370. package/deps/couchbase-cxx-client/core/operations/document_lookup_in.hxx +31 -27
  371. package/deps/couchbase-cxx-client/core/operations/document_lookup_in_all_replicas.hxx +187 -149
  372. package/deps/couchbase-cxx-client/core/operations/document_lookup_in_any_replica.hxx +190 -145
  373. package/deps/couchbase-cxx-client/core/operations/document_mutate_in.cxx +98 -80
  374. package/deps/couchbase-cxx-client/core/operations/document_mutate_in.hxx +38 -33
  375. package/deps/couchbase-cxx-client/core/operations/document_prepend.cxx +18 -15
  376. package/deps/couchbase-cxx-client/core/operations/document_prepend.hxx +18 -16
  377. package/deps/couchbase-cxx-client/core/operations/document_query.cxx +367 -356
  378. package/deps/couchbase-cxx-client/core/operations/document_query.hxx +83 -79
  379. package/deps/couchbase-cxx-client/core/operations/document_remove.cxx +18 -15
  380. package/deps/couchbase-cxx-client/core/operations/document_remove.hxx +18 -16
  381. package/deps/couchbase-cxx-client/core/operations/document_replace.cxx +27 -24
  382. package/deps/couchbase-cxx-client/core/operations/document_replace.hxx +22 -20
  383. package/deps/couchbase-cxx-client/core/operations/document_search.cxx +322 -308
  384. package/deps/couchbase-cxx-client/core/operations/document_search.hxx +125 -121
  385. package/deps/couchbase-cxx-client/core/operations/document_touch.cxx +16 -14
  386. package/deps/couchbase-cxx-client/core/operations/document_touch.hxx +19 -17
  387. package/deps/couchbase-cxx-client/core/operations/document_unlock.cxx +16 -14
  388. package/deps/couchbase-cxx-client/core/operations/document_unlock.hxx +19 -17
  389. package/deps/couchbase-cxx-client/core/operations/document_upsert.cxx +26 -23
  390. package/deps/couchbase-cxx-client/core/operations/document_upsert.hxx +21 -19
  391. package/deps/couchbase-cxx-client/core/operations/document_view.cxx +169 -159
  392. package/deps/couchbase-cxx-client/core/operations/document_view.hxx +68 -65
  393. package/deps/couchbase-cxx-client/core/operations/http_noop.cxx +38 -35
  394. package/deps/couchbase-cxx-client/core/operations/http_noop.hxx +12 -10
  395. package/deps/couchbase-cxx-client/core/operations/management/analytics_dataset_create.cxx +58 -56
  396. package/deps/couchbase-cxx-client/core/operations/management/analytics_dataset_create.hxx +20 -17
  397. package/deps/couchbase-cxx-client/core/operations/management/analytics_dataset_drop.cxx +49 -44
  398. package/deps/couchbase-cxx-client/core/operations/management/analytics_dataset_drop.hxx +18 -15
  399. package/deps/couchbase-cxx-client/core/operations/management/analytics_dataset_get_all.cxx +46 -43
  400. package/deps/couchbase-cxx-client/core/operations/management/analytics_dataset_get_all.hxx +16 -13
  401. package/deps/couchbase-cxx-client/core/operations/management/analytics_dataverse_create.cxx +48 -43
  402. package/deps/couchbase-cxx-client/core/operations/management/analytics_dataverse_create.hxx +17 -14
  403. package/deps/couchbase-cxx-client/core/operations/management/analytics_dataverse_drop.cxx +48 -43
  404. package/deps/couchbase-cxx-client/core/operations/management/analytics_dataverse_drop.hxx +17 -14
  405. package/deps/couchbase-cxx-client/core/operations/management/analytics_get_pending_mutations.cxx +38 -35
  406. package/deps/couchbase-cxx-client/core/operations/management/analytics_get_pending_mutations.hxx +16 -14
  407. package/deps/couchbase-cxx-client/core/operations/management/analytics_index_create.cxx +68 -66
  408. package/deps/couchbase-cxx-client/core/operations/management/analytics_index_create.hxx +20 -17
  409. package/deps/couchbase-cxx-client/core/operations/management/analytics_index_drop.cxx +56 -51
  410. package/deps/couchbase-cxx-client/core/operations/management/analytics_index_drop.hxx +19 -16
  411. package/deps/couchbase-cxx-client/core/operations/management/analytics_index_get_all.cxx +44 -42
  412. package/deps/couchbase-cxx-client/core/operations/management/analytics_index_get_all.hxx +16 -13
  413. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_connect.cxx +49 -43
  414. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_connect.hxx +23 -20
  415. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_create.cxx +52 -51
  416. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_create.hxx +33 -30
  417. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_disconnect.cxx +46 -42
  418. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_disconnect.hxx +22 -19
  419. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_drop.cxx +70 -67
  420. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_drop.hxx +22 -19
  421. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_get_all.cxx +92 -85
  422. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_get_all.hxx +27 -24
  423. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_replace.cxx +52 -51
  424. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_replace.hxx +33 -30
  425. package/deps/couchbase-cxx-client/core/operations/management/analytics_link_utils.hxx +6 -4
  426. package/deps/couchbase-cxx-client/core/operations/management/analytics_problem.hxx +2 -2
  427. package/deps/couchbase-cxx-client/core/operations/management/bucket_create.cxx +158 -149
  428. package/deps/couchbase-cxx-client/core/operations/management/bucket_create.hxx +14 -12
  429. package/deps/couchbase-cxx-client/core/operations/management/bucket_describe.cxx +118 -42
  430. package/deps/couchbase-cxx-client/core/operations/management/bucket_describe.hxx +47 -22
  431. package/deps/couchbase-cxx-client/core/operations/management/bucket_drop.cxx +19 -18
  432. package/deps/couchbase-cxx-client/core/operations/management/bucket_drop.hxx +13 -11
  433. package/deps/couchbase-cxx-client/core/operations/management/bucket_flush.cxx +25 -24
  434. package/deps/couchbase-cxx-client/core/operations/management/bucket_flush.hxx +13 -11
  435. package/deps/couchbase-cxx-client/core/operations/management/bucket_get.cxx +24 -22
  436. package/deps/couchbase-cxx-client/core/operations/management/bucket_get.hxx +14 -12
  437. package/deps/couchbase-cxx-client/core/operations/management/bucket_get_all.cxx +25 -23
  438. package/deps/couchbase-cxx-client/core/operations/management/bucket_get_all.hxx +13 -11
  439. package/deps/couchbase-cxx-client/core/operations/management/bucket_update.cxx +112 -107
  440. package/deps/couchbase-cxx-client/core/operations/management/bucket_update.hxx +15 -13
  441. package/deps/couchbase-cxx-client/core/operations/management/change_password.cxx +22 -20
  442. package/deps/couchbase-cxx-client/core/operations/management/change_password.hxx +13 -11
  443. package/deps/couchbase-cxx-client/core/operations/management/cluster_describe.cxx +52 -50
  444. package/deps/couchbase-cxx-client/core/operations/management/cluster_describe.hxx +31 -29
  445. package/deps/couchbase-cxx-client/core/operations/management/cluster_developer_preview_enable.cxx +14 -12
  446. package/deps/couchbase-cxx-client/core/operations/management/cluster_developer_preview_enable.hxx +13 -11
  447. package/deps/couchbase-cxx-client/core/operations/management/collection_create.cxx +48 -46
  448. package/deps/couchbase-cxx-client/core/operations/management/collection_create.hxx +19 -16
  449. package/deps/couchbase-cxx-client/core/operations/management/collection_drop.cxx +37 -35
  450. package/deps/couchbase-cxx-client/core/operations/management/collection_drop.hxx +16 -14
  451. package/deps/couchbase-cxx-client/core/operations/management/collection_update.cxx +49 -47
  452. package/deps/couchbase-cxx-client/core/operations/management/collection_update.hxx +19 -16
  453. package/deps/couchbase-cxx-client/core/operations/management/collections_manifest_get.cxx +11 -9
  454. package/deps/couchbase-cxx-client/core/operations/management/collections_manifest_get.hxx +17 -13
  455. package/deps/couchbase-cxx-client/core/operations/management/error_utils.cxx +210 -198
  456. package/deps/couchbase-cxx-client/core/operations/management/error_utils.hxx +3 -1
  457. package/deps/couchbase-cxx-client/core/operations/management/eventing_deploy_function.cxx +30 -28
  458. package/deps/couchbase-cxx-client/core/operations/management/eventing_deploy_function.hxx +17 -14
  459. package/deps/couchbase-cxx-client/core/operations/management/eventing_drop_function.cxx +31 -29
  460. package/deps/couchbase-cxx-client/core/operations/management/eventing_drop_function.hxx +17 -14
  461. package/deps/couchbase-cxx-client/core/operations/management/eventing_get_all_functions.cxx +49 -43
  462. package/deps/couchbase-cxx-client/core/operations/management/eventing_get_all_functions.hxx +17 -14
  463. package/deps/couchbase-cxx-client/core/operations/management/eventing_get_function.cxx +29 -27
  464. package/deps/couchbase-cxx-client/core/operations/management/eventing_get_function.hxx +18 -15
  465. package/deps/couchbase-cxx-client/core/operations/management/eventing_get_status.cxx +45 -39
  466. package/deps/couchbase-cxx-client/core/operations/management/eventing_get_status.hxx +17 -14
  467. package/deps/couchbase-cxx-client/core/operations/management/eventing_pause_function.cxx +30 -28
  468. package/deps/couchbase-cxx-client/core/operations/management/eventing_pause_function.hxx +17 -14
  469. package/deps/couchbase-cxx-client/core/operations/management/eventing_problem.hxx +3 -3
  470. package/deps/couchbase-cxx-client/core/operations/management/eventing_resume_function.cxx +30 -28
  471. package/deps/couchbase-cxx-client/core/operations/management/eventing_resume_function.hxx +17 -14
  472. package/deps/couchbase-cxx-client/core/operations/management/eventing_undeploy_function.cxx +30 -28
  473. package/deps/couchbase-cxx-client/core/operations/management/eventing_undeploy_function.hxx +17 -14
  474. package/deps/couchbase-cxx-client/core/operations/management/eventing_upsert_function.cxx +328 -318
  475. package/deps/couchbase-cxx-client/core/operations/management/eventing_upsert_function.hxx +17 -14
  476. package/deps/couchbase-cxx-client/core/operations/management/freeform.cxx +23 -22
  477. package/deps/couchbase-cxx-client/core/operations/management/freeform.hxx +19 -17
  478. package/deps/couchbase-cxx-client/core/operations/management/group_drop.cxx +18 -17
  479. package/deps/couchbase-cxx-client/core/operations/management/group_drop.hxx +13 -11
  480. package/deps/couchbase-cxx-client/core/operations/management/group_get.cxx +25 -23
  481. package/deps/couchbase-cxx-client/core/operations/management/group_get.hxx +14 -12
  482. package/deps/couchbase-cxx-client/core/operations/management/group_get_all.cxx +23 -22
  483. package/deps/couchbase-cxx-client/core/operations/management/group_get_all.hxx +13 -11
  484. package/deps/couchbase-cxx-client/core/operations/management/group_upsert.cxx +58 -55
  485. package/deps/couchbase-cxx-client/core/operations/management/group_upsert.hxx +14 -12
  486. package/deps/couchbase-cxx-client/core/operations/management/query_index_build.cxx +53 -48
  487. package/deps/couchbase-cxx-client/core/operations/management/query_index_build.hxx +25 -22
  488. package/deps/couchbase-cxx-client/core/operations/management/query_index_build_deferred.hxx +75 -67
  489. package/deps/couchbase-cxx-client/core/operations/management/query_index_create.cxx +128 -122
  490. package/deps/couchbase-cxx-client/core/operations/management/query_index_create.hxx +31 -28
  491. package/deps/couchbase-cxx-client/core/operations/management/query_index_drop.cxx +95 -93
  492. package/deps/couchbase-cxx-client/core/operations/management/query_index_drop.hxx +26 -24
  493. package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all.cxx +97 -93
  494. package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all.hxx +24 -21
  495. package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all_deferred.cxx +66 -62
  496. package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all_deferred.hxx +24 -22
  497. package/deps/couchbase-cxx-client/core/operations/management/role_get_all.cxx +24 -22
  498. package/deps/couchbase-cxx-client/core/operations/management/role_get_all.hxx +13 -11
  499. package/deps/couchbase-cxx-client/core/operations/management/scope_create.cxx +38 -36
  500. package/deps/couchbase-cxx-client/core/operations/management/scope_create.hxx +15 -13
  501. package/deps/couchbase-cxx-client/core/operations/management/scope_drop.cxx +33 -32
  502. package/deps/couchbase-cxx-client/core/operations/management/scope_drop.hxx +15 -13
  503. package/deps/couchbase-cxx-client/core/operations/management/scope_get_all.cxx +27 -25
  504. package/deps/couchbase-cxx-client/core/operations/management/scope_get_all.hxx +14 -12
  505. package/deps/couchbase-cxx-client/core/operations/management/search_get_stats.cxx +12 -10
  506. package/deps/couchbase-cxx-client/core/operations/management/search_get_stats.hxx +13 -11
  507. package/deps/couchbase-cxx-client/core/operations/management/search_index_analyze_document.cxx +72 -67
  508. package/deps/couchbase-cxx-client/core/operations/management/search_index_analyze_document.hxx +20 -18
  509. package/deps/couchbase-cxx-client/core/operations/management/search_index_control_ingest.cxx +62 -59
  510. package/deps/couchbase-cxx-client/core/operations/management/search_index_control_ingest.hxx +19 -16
  511. package/deps/couchbase-cxx-client/core/operations/management/search_index_control_plan_freeze.cxx +62 -59
  512. package/deps/couchbase-cxx-client/core/operations/management/search_index_control_plan_freeze.hxx +19 -17
  513. package/deps/couchbase-cxx-client/core/operations/management/search_index_control_query.cxx +62 -59
  514. package/deps/couchbase-cxx-client/core/operations/management/search_index_control_query.hxx +19 -16
  515. package/deps/couchbase-cxx-client/core/operations/management/search_index_drop.cxx +58 -55
  516. package/deps/couchbase-cxx-client/core/operations/management/search_index_drop.hxx +18 -15
  517. package/deps/couchbase-cxx-client/core/operations/management/search_index_get.cxx +59 -56
  518. package/deps/couchbase-cxx-client/core/operations/management/search_index_get.hxx +18 -16
  519. package/deps/couchbase-cxx-client/core/operations/management/search_index_get_all.cxx +51 -46
  520. package/deps/couchbase-cxx-client/core/operations/management/search_index_get_all.hxx +18 -15
  521. package/deps/couchbase-cxx-client/core/operations/management/search_index_get_documents_count.cxx +66 -61
  522. package/deps/couchbase-cxx-client/core/operations/management/search_index_get_documents_count.hxx +19 -17
  523. package/deps/couchbase-cxx-client/core/operations/management/search_index_get_stats.cxx +38 -36
  524. package/deps/couchbase-cxx-client/core/operations/management/search_index_get_stats.hxx +17 -14
  525. package/deps/couchbase-cxx-client/core/operations/management/search_index_upsert.cxx +98 -95
  526. package/deps/couchbase-cxx-client/core/operations/management/search_index_upsert.hxx +20 -17
  527. package/deps/couchbase-cxx-client/core/operations/management/user_drop.cxx +18 -17
  528. package/deps/couchbase-cxx-client/core/operations/management/user_drop.hxx +16 -12
  529. package/deps/couchbase-cxx-client/core/operations/management/user_get.cxx +25 -23
  530. package/deps/couchbase-cxx-client/core/operations/management/user_get.hxx +17 -13
  531. package/deps/couchbase-cxx-client/core/operations/management/user_get_all.cxx +24 -22
  532. package/deps/couchbase-cxx-client/core/operations/management/user_get_all.hxx +16 -12
  533. package/deps/couchbase-cxx-client/core/operations/management/user_upsert.cxx +63 -60
  534. package/deps/couchbase-cxx-client/core/operations/management/user_upsert.hxx +17 -13
  535. package/deps/couchbase-cxx-client/core/operations/management/view_index_drop.cxx +16 -12
  536. package/deps/couchbase-cxx-client/core/operations/management/view_index_drop.hxx +15 -13
  537. package/deps/couchbase-cxx-client/core/operations/management/view_index_get.cxx +40 -35
  538. package/deps/couchbase-cxx-client/core/operations/management/view_index_get.hxx +16 -14
  539. package/deps/couchbase-cxx-client/core/operations/management/view_index_get_all.cxx +73 -69
  540. package/deps/couchbase-cxx-client/core/operations/management/view_index_get_all.hxx +16 -13
  541. package/deps/couchbase-cxx-client/core/operations/management/view_index_upsert.cxx +39 -35
  542. package/deps/couchbase-cxx-client/core/operations/management/view_index_upsert.hxx +15 -12
  543. package/deps/couchbase-cxx-client/core/origin.cxx +259 -249
  544. package/deps/couchbase-cxx-client/core/origin.hxx +55 -49
  545. package/deps/couchbase-cxx-client/core/pending_operation.hxx +3 -3
  546. package/deps/couchbase-cxx-client/core/ping_collector.hxx +3 -3
  547. package/deps/couchbase-cxx-client/core/ping_options.hxx +30 -30
  548. package/deps/couchbase-cxx-client/core/ping_reporter.hxx +3 -3
  549. package/deps/couchbase-cxx-client/core/platform/backtrace.c +100 -91
  550. package/deps/couchbase-cxx-client/core/platform/base64.cc +135 -134
  551. package/deps/couchbase-cxx-client/core/platform/dirutils.cc +66 -63
  552. package/deps/couchbase-cxx-client/core/platform/random.cc +43 -42
  553. package/deps/couchbase-cxx-client/core/platform/random.h +4 -4
  554. package/deps/couchbase-cxx-client/core/platform/string_hex.cc +42 -40
  555. package/deps/couchbase-cxx-client/core/platform/terminate_handler.cc +54 -52
  556. package/deps/couchbase-cxx-client/core/platform/uuid.cc +47 -47
  557. package/deps/couchbase-cxx-client/core/protocol/client_opcode.hxx +336 -327
  558. package/deps/couchbase-cxx-client/core/protocol/client_opcode_fmt.hxx +291 -291
  559. package/deps/couchbase-cxx-client/core/protocol/client_request.cxx +13 -10
  560. package/deps/couchbase-cxx-client/core/protocol/client_request.hxx +133 -130
  561. package/deps/couchbase-cxx-client/core/protocol/client_response.cxx +40 -40
  562. package/deps/couchbase-cxx-client/core/protocol/client_response.hxx +153 -150
  563. package/deps/couchbase-cxx-client/core/protocol/cmd_append.cxx +24 -23
  564. package/deps/couchbase-cxx-client/core/protocol/cmd_append.hxx +65 -65
  565. package/deps/couchbase-cxx-client/core/protocol/cmd_cluster_map_change_notification.cxx +25 -21
  566. package/deps/couchbase-cxx-client/core/protocol/cmd_cluster_map_change_notification.hxx +33 -25
  567. package/deps/couchbase-cxx-client/core/protocol/cmd_decrement.cxx +38 -38
  568. package/deps/couchbase-cxx-client/core/protocol/cmd_decrement.hxx +87 -87
  569. package/deps/couchbase-cxx-client/core/protocol/cmd_get.cxx +17 -17
  570. package/deps/couchbase-cxx-client/core/protocol/cmd_get.hxx +59 -59
  571. package/deps/couchbase-cxx-client/core/protocol/cmd_get_and_lock.cxx +20 -20
  572. package/deps/couchbase-cxx-client/core/protocol/cmd_get_and_lock.hxx +72 -72
  573. package/deps/couchbase-cxx-client/core/protocol/cmd_get_and_touch.cxx +20 -20
  574. package/deps/couchbase-cxx-client/core/protocol/cmd_get_and_touch.hxx +72 -72
  575. package/deps/couchbase-cxx-client/core/protocol/cmd_get_cluster_config.cxx +46 -39
  576. package/deps/couchbase-cxx-client/core/protocol/cmd_get_cluster_config.hxx +57 -49
  577. package/deps/couchbase-cxx-client/core/protocol/cmd_get_collection_id.cxx +17 -17
  578. package/deps/couchbase-cxx-client/core/protocol/cmd_get_collection_id.hxx +59 -59
  579. package/deps/couchbase-cxx-client/core/protocol/cmd_get_collections_manifest.cxx +16 -14
  580. package/deps/couchbase-cxx-client/core/protocol/cmd_get_collections_manifest.hxx +39 -39
  581. package/deps/couchbase-cxx-client/core/protocol/cmd_get_error_map.cxx +18 -17
  582. package/deps/couchbase-cxx-client/core/protocol/cmd_get_error_map.hxx +62 -62
  583. package/deps/couchbase-cxx-client/core/protocol/cmd_get_meta.cxx +24 -23
  584. package/deps/couchbase-cxx-client/core/protocol/cmd_get_meta.hxx +81 -79
  585. package/deps/couchbase-cxx-client/core/protocol/cmd_get_replica.cxx +23 -23
  586. package/deps/couchbase-cxx-client/core/protocol/cmd_get_replica.hxx +44 -44
  587. package/deps/couchbase-cxx-client/core/protocol/cmd_hello.cxx +28 -27
  588. package/deps/couchbase-cxx-client/core/protocol/cmd_hello.hxx +106 -105
  589. package/deps/couchbase-cxx-client/core/protocol/cmd_increment.cxx +38 -38
  590. package/deps/couchbase-cxx-client/core/protocol/cmd_increment.hxx +87 -87
  591. package/deps/couchbase-cxx-client/core/protocol/cmd_info.hxx +3 -3
  592. package/deps/couchbase-cxx-client/core/protocol/cmd_insert.cxx +27 -27
  593. package/deps/couchbase-cxx-client/core/protocol/cmd_insert.hxx +81 -81
  594. package/deps/couchbase-cxx-client/core/protocol/cmd_lookup_in.cxx +54 -51
  595. package/deps/couchbase-cxx-client/core/protocol/cmd_lookup_in.hxx +90 -90
  596. package/deps/couchbase-cxx-client/core/protocol/cmd_lookup_in_replica.cxx +54 -51
  597. package/deps/couchbase-cxx-client/core/protocol/cmd_lookup_in_replica.hxx +88 -88
  598. package/deps/couchbase-cxx-client/core/protocol/cmd_mutate_in.cxx +105 -97
  599. package/deps/couchbase-cxx-client/core/protocol/cmd_mutate_in.hxx +161 -153
  600. package/deps/couchbase-cxx-client/core/protocol/cmd_noop.cxx +4 -4
  601. package/deps/couchbase-cxx-client/core/protocol/cmd_noop.hxx +32 -32
  602. package/deps/couchbase-cxx-client/core/protocol/cmd_observe_seqno.cxx +36 -34
  603. package/deps/couchbase-cxx-client/core/protocol/cmd_observe_seqno.hxx +89 -89
  604. package/deps/couchbase-cxx-client/core/protocol/cmd_prepend.cxx +22 -22
  605. package/deps/couchbase-cxx-client/core/protocol/cmd_prepend.hxx +63 -63
  606. package/deps/couchbase-cxx-client/core/protocol/cmd_remove.cxx +23 -23
  607. package/deps/couchbase-cxx-client/core/protocol/cmd_remove.hxx +54 -54
  608. package/deps/couchbase-cxx-client/core/protocol/cmd_replace.cxx +28 -28
  609. package/deps/couchbase-cxx-client/core/protocol/cmd_replace.hxx +88 -88
  610. package/deps/couchbase-cxx-client/core/protocol/cmd_sasl_auth.cxx +17 -15
  611. package/deps/couchbase-cxx-client/core/protocol/cmd_sasl_auth.hxx +56 -56
  612. package/deps/couchbase-cxx-client/core/protocol/cmd_sasl_list_mechs.cxx +24 -19
  613. package/deps/couchbase-cxx-client/core/protocol/cmd_sasl_list_mechs.hxx +39 -39
  614. package/deps/couchbase-cxx-client/core/protocol/cmd_sasl_step.cxx +17 -15
  615. package/deps/couchbase-cxx-client/core/protocol/cmd_sasl_step.hxx +56 -56
  616. package/deps/couchbase-cxx-client/core/protocol/cmd_select_bucket.cxx +6 -6
  617. package/deps/couchbase-cxx-client/core/protocol/cmd_select_bucket.hxx +36 -36
  618. package/deps/couchbase-cxx-client/core/protocol/cmd_touch.cxx +8 -8
  619. package/deps/couchbase-cxx-client/core/protocol/cmd_touch.hxx +38 -38
  620. package/deps/couchbase-cxx-client/core/protocol/cmd_unlock.cxx +5 -5
  621. package/deps/couchbase-cxx-client/core/protocol/cmd_unlock.hxx +36 -36
  622. package/deps/couchbase-cxx-client/core/protocol/cmd_upsert.cxx +28 -28
  623. package/deps/couchbase-cxx-client/core/protocol/cmd_upsert.hxx +83 -83
  624. package/deps/couchbase-cxx-client/core/protocol/datatype.hxx +19 -18
  625. package/deps/couchbase-cxx-client/core/protocol/frame_info_id.hxx +108 -103
  626. package/deps/couchbase-cxx-client/core/protocol/frame_info_id_fmt.hxx +45 -45
  627. package/deps/couchbase-cxx-client/core/protocol/frame_info_utils.cxx +24 -21
  628. package/deps/couchbase-cxx-client/core/protocol/frame_info_utils.hxx +3 -1
  629. package/deps/couchbase-cxx-client/core/protocol/hello_feature.hxx +211 -175
  630. package/deps/couchbase-cxx-client/core/protocol/hello_feature_fmt.hxx +93 -90
  631. package/deps/couchbase-cxx-client/core/protocol/magic.hxx +24 -24
  632. package/deps/couchbase-cxx-client/core/protocol/magic_fmt.hxx +30 -30
  633. package/deps/couchbase-cxx-client/core/protocol/server_opcode.hxx +11 -11
  634. package/deps/couchbase-cxx-client/core/protocol/server_opcode_fmt.hxx +18 -18
  635. package/deps/couchbase-cxx-client/core/protocol/server_request.hxx +90 -86
  636. package/deps/couchbase-cxx-client/core/protocol/status.cxx +138 -138
  637. package/deps/couchbase-cxx-client/core/protocol/status.hxx +86 -86
  638. package/deps/couchbase-cxx-client/core/query_context.hxx +44 -43
  639. package/deps/couchbase-cxx-client/core/range_scan_load_balancer.cxx +51 -50
  640. package/deps/couchbase-cxx-client/core/range_scan_load_balancer.hxx +26 -25
  641. package/deps/couchbase-cxx-client/core/range_scan_options.cxx +2 -2
  642. package/deps/couchbase-cxx-client/core/range_scan_options.hxx +62 -59
  643. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +515 -470
  644. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.hxx +23 -18
  645. package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +10 -10
  646. package/deps/couchbase-cxx-client/core/resource_units.hxx +2 -2
  647. package/deps/couchbase-cxx-client/core/response_handler.hxx +8 -8
  648. package/deps/couchbase-cxx-client/core/retry_orchestrator.cxx +27 -19
  649. package/deps/couchbase-cxx-client/core/retry_orchestrator.hxx +3 -2
  650. package/deps/couchbase-cxx-client/core/sasl/client.cc +22 -18
  651. package/deps/couchbase-cxx-client/core/sasl/client.h +66 -62
  652. package/deps/couchbase-cxx-client/core/sasl/context.cc +4 -4
  653. package/deps/couchbase-cxx-client/core/sasl/context.h +19 -19
  654. package/deps/couchbase-cxx-client/core/sasl/error.h +12 -1
  655. package/deps/couchbase-cxx-client/core/sasl/error_fmt.h +42 -42
  656. package/deps/couchbase-cxx-client/core/sasl/mechanism.cc +13 -10
  657. package/deps/couchbase-cxx-client/core/sasl/mechanism.h +8 -3
  658. package/deps/couchbase-cxx-client/core/sasl/plain/plain.cc +8 -8
  659. package/deps/couchbase-cxx-client/core/sasl/plain/plain.h +25 -24
  660. package/deps/couchbase-cxx-client/core/sasl/scram-sha/scram-sha.cc +225 -218
  661. package/deps/couchbase-cxx-client/core/sasl/scram-sha/scram-sha.h +133 -115
  662. package/deps/couchbase-cxx-client/core/sasl/scram-sha/stringutils.cc +20 -20
  663. package/deps/couchbase-cxx-client/core/scan_result.cxx +38 -38
  664. package/deps/couchbase-cxx-client/core/scan_result.hxx +16 -16
  665. package/deps/couchbase-cxx-client/core/search_highlight_style.hxx +4 -1
  666. package/deps/couchbase-cxx-client/core/search_query_options.cxx +21 -21
  667. package/deps/couchbase-cxx-client/core/search_query_options.hxx +19 -18
  668. package/deps/couchbase-cxx-client/core/search_scan_consistency.hxx +3 -1
  669. package/deps/couchbase-cxx-client/core/seed_config.cxx +10 -7
  670. package/deps/couchbase-cxx-client/core/seed_config.hxx +8 -8
  671. package/deps/couchbase-cxx-client/core/service_type.hxx +7 -7
  672. package/deps/couchbase-cxx-client/core/service_type_fmt.hxx +33 -33
  673. package/deps/couchbase-cxx-client/core/stats_options.hxx +13 -13
  674. package/deps/couchbase-cxx-client/core/subdoc_options.hxx +60 -58
  675. package/deps/couchbase-cxx-client/core/tls_verify_mode.hxx +2 -2
  676. package/deps/couchbase-cxx-client/core/topology/capabilities.hxx +83 -83
  677. package/deps/couchbase-cxx-client/core/topology/capabilities_fmt.hxx +111 -111
  678. package/deps/couchbase-cxx-client/core/topology/collections_manifest.hxx +14 -14
  679. package/deps/couchbase-cxx-client/core/topology/collections_manifest_fmt.hxx +23 -21
  680. package/deps/couchbase-cxx-client/core/topology/collections_manifest_json.hxx +26 -25
  681. package/deps/couchbase-cxx-client/core/topology/configuration.cxx +213 -192
  682. package/deps/couchbase-cxx-client/core/topology/configuration.hxx +104 -91
  683. package/deps/couchbase-cxx-client/core/topology/configuration_fmt.hxx +131 -128
  684. package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +276 -242
  685. package/deps/couchbase-cxx-client/core/topology/error_map.hxx +5 -5
  686. package/deps/couchbase-cxx-client/core/topology/error_map_json.hxx +65 -60
  687. package/deps/couchbase-cxx-client/core/tracing/constants.hxx +153 -153
  688. package/deps/couchbase-cxx-client/core/tracing/noop_tracer.hxx +29 -28
  689. package/deps/couchbase-cxx-client/core/tracing/threshold_logging_options.hxx +30 -30
  690. package/deps/couchbase-cxx-client/core/tracing/threshold_logging_tracer.cxx +354 -344
  691. package/deps/couchbase-cxx-client/core/tracing/threshold_logging_tracer.hxx +12 -12
  692. package/deps/couchbase-cxx-client/core/transactions/active_transaction_record.cxx +153 -33
  693. package/deps/couchbase-cxx-client/core/transactions/active_transaction_record.hxx +30 -118
  694. package/deps/couchbase-cxx-client/core/transactions/async_attempt_context.cxx +8 -2
  695. package/deps/couchbase-cxx-client/core/transactions/async_attempt_context.hxx +163 -127
  696. package/deps/couchbase-cxx-client/core/transactions/atr_cleanup_entry.cxx +358 -334
  697. package/deps/couchbase-cxx-client/core/transactions/atr_ids.cxx +270 -185
  698. package/deps/couchbase-cxx-client/core/transactions/atr_ids.hxx +4 -4
  699. package/deps/couchbase-cxx-client/core/transactions/attempt_context.cxx +9 -5
  700. package/deps/couchbase-cxx-client/core/transactions/attempt_context.hxx +194 -154
  701. package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.cxx +3278 -2159
  702. package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.hxx +446 -573
  703. package/deps/couchbase-cxx-client/core/transactions/attempt_context_testing_hooks.cxx +15 -10
  704. package/deps/couchbase-cxx-client/core/transactions/attempt_context_testing_hooks.hxx +58 -49
  705. package/deps/couchbase-cxx-client/core/transactions/attempt_state.hxx +72 -72
  706. package/deps/couchbase-cxx-client/core/transactions/binary.cxx +3 -3
  707. package/deps/couchbase-cxx-client/core/transactions/cleanup_testing_hooks.cxx +2 -2
  708. package/deps/couchbase-cxx-client/core/transactions/cleanup_testing_hooks.hxx +28 -24
  709. package/deps/couchbase-cxx-client/core/transactions/document_metadata.hxx +68 -68
  710. package/deps/couchbase-cxx-client/core/transactions/durability_level.hxx +53 -53
  711. package/deps/couchbase-cxx-client/core/transactions/error_class.hxx +12 -12
  712. package/deps/couchbase-cxx-client/core/transactions/error_list.hxx +22 -22
  713. package/deps/couchbase-cxx-client/core/transactions/exceptions.cxx +167 -114
  714. package/deps/couchbase-cxx-client/core/transactions/exceptions.hxx +170 -139
  715. package/deps/couchbase-cxx-client/core/transactions/exceptions_fmt.hxx +105 -0
  716. package/deps/couchbase-cxx-client/core/transactions/forward_compat.cxx +220 -0
  717. package/deps/couchbase-cxx-client/core/transactions/forward_compat.hxx +63 -207
  718. package/deps/couchbase-cxx-client/core/transactions/internal/atr_cleanup_entry.hxx +110 -102
  719. package/deps/couchbase-cxx-client/core/transactions/internal/atr_entry.hxx +144 -144
  720. package/deps/couchbase-cxx-client/core/transactions/internal/client_record.hxx +53 -50
  721. package/deps/couchbase-cxx-client/core/transactions/internal/doc_record.cxx +5 -5
  722. package/deps/couchbase-cxx-client/core/transactions/internal/doc_record.hxx +38 -35
  723. package/deps/couchbase-cxx-client/core/transactions/internal/doc_record_fmt.hxx +17 -16
  724. package/deps/couchbase-cxx-client/core/transactions/internal/exceptions_internal.hxx +238 -281
  725. package/deps/couchbase-cxx-client/core/transactions/internal/exceptions_internal_fmt.hxx +103 -0
  726. package/deps/couchbase-cxx-client/core/transactions/internal/logging.hxx +52 -29
  727. package/deps/couchbase-cxx-client/core/transactions/internal/transaction_attempt.hxx +3 -3
  728. package/deps/couchbase-cxx-client/core/transactions/internal/transaction_context.hxx +136 -120
  729. package/deps/couchbase-cxx-client/core/transactions/internal/transaction_fields.hxx +2 -1
  730. package/deps/couchbase-cxx-client/core/transactions/internal/transactions_cleanup.hxx +127 -122
  731. package/deps/couchbase-cxx-client/core/transactions/internal/utils.hxx +244 -219
  732. package/deps/couchbase-cxx-client/core/transactions/result.cxx +41 -40
  733. package/deps/couchbase-cxx-client/core/transactions/result.hxx +143 -141
  734. package/deps/couchbase-cxx-client/core/transactions/result_fmt.hxx +21 -20
  735. package/deps/couchbase-cxx-client/core/transactions/staged_mutation.cxx +759 -627
  736. package/deps/couchbase-cxx-client/core/transactions/staged_mutation.hxx +175 -156
  737. package/deps/couchbase-cxx-client/core/transactions/transaction_context.cxx +231 -179
  738. package/deps/couchbase-cxx-client/core/transactions/transaction_get_result.cxx +185 -198
  739. package/deps/couchbase-cxx-client/core/transactions/transaction_get_result.hxx +207 -222
  740. package/deps/couchbase-cxx-client/core/transactions/transaction_keyspace.cxx +15 -11
  741. package/deps/couchbase-cxx-client/core/transactions/transaction_links.cxx +11 -7
  742. package/deps/couchbase-cxx-client/core/transactions/transaction_links.hxx +222 -201
  743. package/deps/couchbase-cxx-client/core/transactions/transaction_options.cxx +44 -41
  744. package/deps/couchbase-cxx-client/core/transactions/transactions.cxx +167 -125
  745. package/deps/couchbase-cxx-client/core/transactions/transactions_cleanup.cxx +491 -424
  746. package/deps/couchbase-cxx-client/core/transactions/transactions_config.cxx +25 -19
  747. package/deps/couchbase-cxx-client/core/transactions/uid_generator.cxx +3 -3
  748. package/deps/couchbase-cxx-client/core/transactions/uid_generator.hxx +2 -2
  749. package/deps/couchbase-cxx-client/core/transactions/utils.cxx +82 -69
  750. package/deps/couchbase-cxx-client/core/transactions/waitable_op_list.hxx +154 -140
  751. package/deps/couchbase-cxx-client/core/transactions.hxx +184 -180
  752. package/deps/couchbase-cxx-client/core/utils/binary.cxx +3 -3
  753. package/deps/couchbase-cxx-client/core/utils/binary.hxx +19 -15
  754. package/deps/couchbase-cxx-client/core/utils/byteswap.hxx +17 -17
  755. package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +395 -328
  756. package/deps/couchbase-cxx-client/core/utils/connection_string.hxx +37 -36
  757. package/deps/couchbase-cxx-client/core/utils/crc32.hxx +42 -34
  758. package/deps/couchbase-cxx-client/core/utils/duration_parser.cxx +142 -133
  759. package/deps/couchbase-cxx-client/core/utils/duration_parser.hxx +9 -9
  760. package/deps/couchbase-cxx-client/core/utils/join_strings.hxx +24 -24
  761. package/deps/couchbase-cxx-client/core/utils/json.cxx +234 -228
  762. package/deps/couchbase-cxx-client/core/utils/json.hxx +12 -12
  763. package/deps/couchbase-cxx-client/core/utils/json_stream_control.hxx +8 -8
  764. package/deps/couchbase-cxx-client/core/utils/json_streaming_lexer.cxx +288 -263
  765. package/deps/couchbase-cxx-client/core/utils/json_streaming_lexer.hxx +20 -17
  766. package/deps/couchbase-cxx-client/core/utils/keyspace.hxx +22 -21
  767. package/deps/couchbase-cxx-client/core/utils/movable_function.hxx +78 -76
  768. package/deps/couchbase-cxx-client/core/utils/mutation_token.cxx +7 -3
  769. package/deps/couchbase-cxx-client/core/utils/mutation_token.hxx +3 -1
  770. package/deps/couchbase-cxx-client/core/utils/name_codec.hxx +13 -13
  771. package/deps/couchbase-cxx-client/core/utils/split_string.cxx +9 -9
  772. package/deps/couchbase-cxx-client/core/utils/split_string.hxx +2 -2
  773. package/deps/couchbase-cxx-client/core/utils/unsigned_leb128.hxx +92 -88
  774. package/deps/couchbase-cxx-client/core/utils/url_codec.cxx +301 -297
  775. package/deps/couchbase-cxx-client/core/utils/url_codec.hxx +35 -35
  776. package/deps/couchbase-cxx-client/core/vector_query_combination.hxx +4 -1
  777. package/deps/couchbase-cxx-client/core/view_on_error.hxx +4 -3
  778. package/deps/couchbase-cxx-client/core/view_query_options.cxx +21 -21
  779. package/deps/couchbase-cxx-client/core/view_query_options.hxx +23 -22
  780. package/deps/couchbase-cxx-client/core/view_scan_consistency.hxx +3 -3
  781. package/deps/couchbase-cxx-client/core/view_sort_order.hxx +4 -1
  782. package/deps/couchbase-cxx-client/core/wait_until_ready_options.hxx +11 -10
  783. package/deps/couchbase-cxx-client/couchbase/allow_querying_search_index_options.hxx +11 -11
  784. package/deps/couchbase-cxx-client/couchbase/analytics_index_manager.hxx +423 -405
  785. package/deps/couchbase-cxx-client/couchbase/analytics_meta_data.hxx +105 -105
  786. package/deps/couchbase-cxx-client/couchbase/analytics_metrics.hxx +120 -118
  787. package/deps/couchbase-cxx-client/couchbase/analytics_options.hxx +318 -292
  788. package/deps/couchbase-cxx-client/couchbase/analytics_result.hxx +56 -55
  789. package/deps/couchbase-cxx-client/couchbase/analytics_scan_consistency.hxx +24 -21
  790. package/deps/couchbase-cxx-client/couchbase/analytics_status.hxx +10 -10
  791. package/deps/couchbase-cxx-client/couchbase/analytics_warning.hxx +44 -43
  792. package/deps/couchbase-cxx-client/couchbase/analyze_document_options.hxx +9 -9
  793. package/deps/couchbase-cxx-client/couchbase/append_options.hxx +51 -47
  794. package/deps/couchbase-cxx-client/couchbase/behavior_options.hxx +75 -69
  795. package/deps/couchbase-cxx-client/couchbase/best_effort_retry_strategy.hxx +12 -10
  796. package/deps/couchbase-cxx-client/couchbase/binary_collection.hxx +213 -183
  797. package/deps/couchbase-cxx-client/couchbase/boolean_field_query.hxx +38 -38
  798. package/deps/couchbase-cxx-client/couchbase/boolean_query.hxx +166 -157
  799. package/deps/couchbase-cxx-client/couchbase/bucket.hxx +69 -68
  800. package/deps/couchbase-cxx-client/couchbase/bucket_manager.hxx +97 -88
  801. package/deps/couchbase-cxx-client/couchbase/build_query_index_options.hxx +22 -21
  802. package/deps/couchbase-cxx-client/couchbase/cas.hxx +74 -73
  803. package/deps/couchbase-cxx-client/couchbase/certificate_authenticator.hxx +10 -10
  804. package/deps/couchbase-cxx-client/couchbase/cluster.hxx +266 -310
  805. package/deps/couchbase-cxx-client/couchbase/cluster_options.hxx +235 -241
  806. package/deps/couchbase-cxx-client/couchbase/codec/binary_noop_serializer.hxx +11 -11
  807. package/deps/couchbase-cxx-client/couchbase/codec/codec_flags.hxx +39 -35
  808. package/deps/couchbase-cxx-client/couchbase/codec/encoded_value.hxx +15 -2
  809. package/deps/couchbase-cxx-client/couchbase/codec/json_transcoder.hxx +17 -15
  810. package/deps/couchbase-cxx-client/couchbase/codec/raw_binary_transcoder.hxx +19 -17
  811. package/deps/couchbase-cxx-client/couchbase/codec/raw_json_transcoder.hxx +31 -24
  812. package/deps/couchbase-cxx-client/couchbase/codec/raw_string_transcoder.hxx +20 -18
  813. package/deps/couchbase-cxx-client/couchbase/codec/tao_json_serializer.hxx +38 -30
  814. package/deps/couchbase-cxx-client/couchbase/collection.hxx +1007 -902
  815. package/deps/couchbase-cxx-client/couchbase/collection_manager.hxx +115 -107
  816. package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +200 -188
  817. package/deps/couchbase-cxx-client/couchbase/common_durability_options.hxx +68 -62
  818. package/deps/couchbase-cxx-client/couchbase/common_options.hxx +67 -67
  819. package/deps/couchbase-cxx-client/couchbase/compression_options.hxx +33 -33
  820. package/deps/couchbase-cxx-client/couchbase/configuration_profile.hxx +12 -11
  821. package/deps/couchbase-cxx-client/couchbase/configuration_profiles_registry.hxx +24 -22
  822. package/deps/couchbase-cxx-client/couchbase/conjunction_query.hxx +47 -45
  823. package/deps/couchbase-cxx-client/couchbase/connect_link_analytics_options.hxx +74 -72
  824. package/deps/couchbase-cxx-client/couchbase/counter_result.hxx +32 -32
  825. package/deps/couchbase-cxx-client/couchbase/create_bucket_options.hxx +9 -10
  826. package/deps/couchbase-cxx-client/couchbase/create_collection_options.hxx +35 -34
  827. package/deps/couchbase-cxx-client/couchbase/create_dataset_analytics_options.hxx +76 -76
  828. package/deps/couchbase-cxx-client/couchbase/create_dataverse_analytics_options.hxx +44 -44
  829. package/deps/couchbase-cxx-client/couchbase/create_index_analytics_options.hxx +60 -60
  830. package/deps/couchbase-cxx-client/couchbase/create_link_analytics_options.hxx +25 -25
  831. package/deps/couchbase-cxx-client/couchbase/create_primary_query_index_options.hxx +95 -94
  832. package/deps/couchbase-cxx-client/couchbase/create_query_index_options.hxx +97 -96
  833. package/deps/couchbase-cxx-client/couchbase/create_scope_options.hxx +9 -9
  834. package/deps/couchbase-cxx-client/couchbase/date_range.hxx +29 -27
  835. package/deps/couchbase-cxx-client/couchbase/date_range_facet.hxx +20 -20
  836. package/deps/couchbase-cxx-client/couchbase/date_range_facet_result.hxx +14 -14
  837. package/deps/couchbase-cxx-client/couchbase/date_range_query.hxx +219 -205
  838. package/deps/couchbase-cxx-client/couchbase/decrement_options.hxx +93 -91
  839. package/deps/couchbase-cxx-client/couchbase/diagnostics_options.hxx +42 -41
  840. package/deps/couchbase-cxx-client/couchbase/diagnostics_result.hxx +82 -83
  841. package/deps/couchbase-cxx-client/couchbase/disallow_querying_search_index_options.hxx +11 -10
  842. package/deps/couchbase-cxx-client/couchbase/disconnect_link_analytics_options.hxx +62 -62
  843. package/deps/couchbase-cxx-client/couchbase/disjunction_query.hxx +61 -60
  844. package/deps/couchbase-cxx-client/couchbase/dns_options.hxx +30 -30
  845. package/deps/couchbase-cxx-client/couchbase/doc_id_query.hxx +69 -69
  846. package/deps/couchbase-cxx-client/couchbase/drop_bucket_options.hxx +9 -9
  847. package/deps/couchbase-cxx-client/couchbase/drop_collection_options.hxx +9 -9
  848. package/deps/couchbase-cxx-client/couchbase/drop_dataset_analytics_options.hxx +60 -60
  849. package/deps/couchbase-cxx-client/couchbase/drop_dataverse_analytics_options.hxx +44 -44
  850. package/deps/couchbase-cxx-client/couchbase/drop_index_analytics_options.hxx +60 -60
  851. package/deps/couchbase-cxx-client/couchbase/drop_link_analytics_options.hxx +25 -25
  852. package/deps/couchbase-cxx-client/couchbase/drop_primary_query_index_options.hxx +58 -58
  853. package/deps/couchbase-cxx-client/couchbase/drop_query_index_options.hxx +44 -44
  854. package/deps/couchbase-cxx-client/couchbase/drop_scope_options.hxx +9 -9
  855. package/deps/couchbase-cxx-client/couchbase/drop_search_index_options.hxx +9 -9
  856. package/deps/couchbase-cxx-client/couchbase/durability_level.hxx +32 -29
  857. package/deps/couchbase-cxx-client/couchbase/endpoint_diagnostics.hxx +171 -171
  858. package/deps/couchbase-cxx-client/couchbase/endpoint_ping_report.hxx +166 -169
  859. package/deps/couchbase-cxx-client/couchbase/error.hxx +51 -0
  860. package/deps/couchbase-cxx-client/couchbase/error_codes.hxx +975 -940
  861. package/deps/couchbase-cxx-client/couchbase/error_context.hxx +19 -152
  862. package/deps/couchbase-cxx-client/couchbase/exists_options.hxx +25 -24
  863. package/deps/couchbase-cxx-client/couchbase/exists_result.hxx +32 -32
  864. package/deps/couchbase-cxx-client/couchbase/fail_fast_retry_strategy.hxx +4 -4
  865. package/deps/couchbase-cxx-client/couchbase/flush_bucket_options.hxx +9 -9
  866. package/deps/couchbase-cxx-client/couchbase/fmt/analytics_scan_consistency.hxx +18 -18
  867. package/deps/couchbase-cxx-client/couchbase/fmt/analytics_status.hxx +42 -42
  868. package/deps/couchbase-cxx-client/couchbase/fmt/cas.hxx +10 -10
  869. package/deps/couchbase-cxx-client/couchbase/fmt/durability_level.hxx +24 -24
  870. package/deps/couchbase-cxx-client/couchbase/fmt/error.hxx +53 -0
  871. package/deps/couchbase-cxx-client/couchbase/fmt/error_context.hxx +43 -0
  872. package/deps/couchbase-cxx-client/couchbase/fmt/mutation_token.hxx +15 -11
  873. package/deps/couchbase-cxx-client/couchbase/fmt/query_profile.hxx +21 -21
  874. package/deps/couchbase-cxx-client/couchbase/fmt/query_scan_consistency.hxx +18 -18
  875. package/deps/couchbase-cxx-client/couchbase/fmt/query_status.hxx +42 -42
  876. package/deps/couchbase-cxx-client/couchbase/fmt/retry_reason.hxx +75 -75
  877. package/deps/couchbase-cxx-client/couchbase/fmt/search_scan_consistency.hxx +15 -15
  878. package/deps/couchbase-cxx-client/couchbase/fmt/tls_verify_mode.hxx +18 -18
  879. package/deps/couchbase-cxx-client/couchbase/fmt/transaction_keyspace.hxx +15 -11
  880. package/deps/couchbase-cxx-client/couchbase/fork_event.hxx +12 -12
  881. package/deps/couchbase-cxx-client/couchbase/freeze_plan_search_index_options.hxx +9 -9
  882. package/deps/couchbase-cxx-client/couchbase/geo_bounding_box_query.hxx +71 -64
  883. package/deps/couchbase-cxx-client/couchbase/geo_distance_query.hxx +73 -66
  884. package/deps/couchbase-cxx-client/couchbase/geo_point.hxx +2 -2
  885. package/deps/couchbase-cxx-client/couchbase/geo_polygon_query.hxx +40 -39
  886. package/deps/couchbase-cxx-client/couchbase/get_all_buckets_options.hxx +9 -9
  887. package/deps/couchbase-cxx-client/couchbase/get_all_datasets_analytics_options.hxx +25 -25
  888. package/deps/couchbase-cxx-client/couchbase/get_all_indexes_analytics_options.hxx +26 -25
  889. package/deps/couchbase-cxx-client/couchbase/get_all_query_indexes_options.hxx +27 -25
  890. package/deps/couchbase-cxx-client/couchbase/get_all_replicas_options.hxx +49 -26
  891. package/deps/couchbase-cxx-client/couchbase/get_all_scopes_options.hxx +9 -9
  892. package/deps/couchbase-cxx-client/couchbase/get_all_search_indexes_options.hxx +9 -9
  893. package/deps/couchbase-cxx-client/couchbase/get_and_lock_options.hxx +25 -24
  894. package/deps/couchbase-cxx-client/couchbase/get_and_touch_options.hxx +25 -24
  895. package/deps/couchbase-cxx-client/couchbase/get_any_replica_options.hxx +49 -26
  896. package/deps/couchbase-cxx-client/couchbase/get_bucket_options.hxx +9 -9
  897. package/deps/couchbase-cxx-client/couchbase/get_indexed_search_index_options.hxx +9 -9
  898. package/deps/couchbase-cxx-client/couchbase/get_links_analytics_options.hxx +74 -74
  899. package/deps/couchbase-cxx-client/couchbase/get_options.hxx +63 -60
  900. package/deps/couchbase-cxx-client/couchbase/get_pending_mutations_analytics_options.hxx +30 -28
  901. package/deps/couchbase-cxx-client/couchbase/get_replica_result.hxx +79 -75
  902. package/deps/couchbase-cxx-client/couchbase/get_result.hxx +86 -80
  903. package/deps/couchbase-cxx-client/couchbase/get_search_index_options.hxx +9 -9
  904. package/deps/couchbase-cxx-client/couchbase/highlight_style.hxx +14 -14
  905. package/deps/couchbase-cxx-client/couchbase/increment_options.hxx +94 -91
  906. package/deps/couchbase-cxx-client/couchbase/insert_options.hxx +62 -59
  907. package/deps/couchbase-cxx-client/couchbase/ip_protocol.hxx +3 -3
  908. package/deps/couchbase-cxx-client/couchbase/logger.hxx +51 -0
  909. package/deps/couchbase-cxx-client/couchbase/lookup_in_all_replicas_options.hxx +54 -43
  910. package/deps/couchbase-cxx-client/couchbase/lookup_in_any_replica_options.hxx +54 -44
  911. package/deps/couchbase-cxx-client/couchbase/lookup_in_options.hxx +40 -40
  912. package/deps/couchbase-cxx-client/couchbase/lookup_in_replica_result.hxx +38 -35
  913. package/deps/couchbase-cxx-client/couchbase/lookup_in_result.hxx +222 -216
  914. package/deps/couchbase-cxx-client/couchbase/lookup_in_specs.hxx +101 -101
  915. package/deps/couchbase-cxx-client/couchbase/management/analytics_dataset.hxx +16 -16
  916. package/deps/couchbase-cxx-client/couchbase/management/analytics_index.hxx +16 -16
  917. package/deps/couchbase-cxx-client/couchbase/management/analytics_link.hxx +193 -189
  918. package/deps/couchbase-cxx-client/couchbase/management/bucket_settings.hxx +91 -75
  919. package/deps/couchbase-cxx-client/couchbase/management/collection_spec.hxx +4 -4
  920. package/deps/couchbase-cxx-client/couchbase/management/query_index.hxx +10 -10
  921. package/deps/couchbase-cxx-client/couchbase/management/scope_spec.hxx +2 -2
  922. package/deps/couchbase-cxx-client/couchbase/management/search_index.hxx +9 -9
  923. package/deps/couchbase-cxx-client/couchbase/match_all_query.hxx +10 -9
  924. package/deps/couchbase-cxx-client/couchbase/match_none_query.hxx +10 -9
  925. package/deps/couchbase-cxx-client/couchbase/match_operator.hxx +15 -14
  926. package/deps/couchbase-cxx-client/couchbase/match_phrase_query.hxx +70 -65
  927. package/deps/couchbase-cxx-client/couchbase/match_query.hxx +115 -114
  928. package/deps/couchbase-cxx-client/couchbase/metrics/meter.hxx +33 -30
  929. package/deps/couchbase-cxx-client/couchbase/metrics/otel_meter.hxx +86 -74
  930. package/deps/couchbase-cxx-client/couchbase/metrics_options.hxx +34 -34
  931. package/deps/couchbase-cxx-client/couchbase/mutate_in_options.hxx +160 -149
  932. package/deps/couchbase-cxx-client/couchbase/mutate_in_result.hxx +130 -123
  933. package/deps/couchbase-cxx-client/couchbase/mutate_in_specs.hxx +473 -454
  934. package/deps/couchbase-cxx-client/couchbase/mutation_result.hxx +32 -32
  935. package/deps/couchbase-cxx-client/couchbase/mutation_state.hxx +35 -34
  936. package/deps/couchbase-cxx-client/couchbase/mutation_token.hxx +78 -78
  937. package/deps/couchbase-cxx-client/couchbase/network_options.hxx +101 -72
  938. package/deps/couchbase-cxx-client/couchbase/numeric_range.hxx +26 -26
  939. package/deps/couchbase-cxx-client/couchbase/numeric_range_facet.hxx +20 -20
  940. package/deps/couchbase-cxx-client/couchbase/numeric_range_facet_result.hxx +14 -14
  941. package/deps/couchbase-cxx-client/couchbase/numeric_range_query.hxx +97 -95
  942. package/deps/couchbase-cxx-client/couchbase/password_authenticator.hxx +17 -17
  943. package/deps/couchbase-cxx-client/couchbase/pause_ingest_search_index_options.hxx +11 -10
  944. package/deps/couchbase-cxx-client/couchbase/persist_to.hxx +45 -44
  945. package/deps/couchbase-cxx-client/couchbase/phrase_query.hxx +69 -65
  946. package/deps/couchbase-cxx-client/couchbase/ping_options.hxx +55 -54
  947. package/deps/couchbase-cxx-client/couchbase/ping_result.hxx +79 -77
  948. package/deps/couchbase-cxx-client/couchbase/prefix_query.hxx +43 -40
  949. package/deps/couchbase-cxx-client/couchbase/prepend_options.hxx +51 -47
  950. package/deps/couchbase-cxx-client/couchbase/query_index_manager.hxx +207 -199
  951. package/deps/couchbase-cxx-client/couchbase/query_meta_data.hxx +120 -120
  952. package/deps/couchbase-cxx-client/couchbase/query_metrics.hxx +135 -133
  953. package/deps/couchbase-cxx-client/couchbase/query_options.hxx +518 -493
  954. package/deps/couchbase-cxx-client/couchbase/query_profile.hxx +29 -26
  955. package/deps/couchbase-cxx-client/couchbase/query_result.hxx +56 -55
  956. package/deps/couchbase-cxx-client/couchbase/query_scan_consistency.hxx +24 -21
  957. package/deps/couchbase-cxx-client/couchbase/query_status.hxx +10 -10
  958. package/deps/couchbase-cxx-client/couchbase/query_string_query.hxx +34 -29
  959. package/deps/couchbase-cxx-client/couchbase/query_warning.hxx +75 -71
  960. package/deps/couchbase-cxx-client/couchbase/read_preference.hxx +58 -0
  961. package/deps/couchbase-cxx-client/couchbase/regexp_query.hxx +40 -39
  962. package/deps/couchbase-cxx-client/couchbase/remove_options.hxx +51 -47
  963. package/deps/couchbase-cxx-client/couchbase/replace_link_analytics_options.hxx +25 -25
  964. package/deps/couchbase-cxx-client/couchbase/replace_options.hxx +112 -104
  965. package/deps/couchbase-cxx-client/couchbase/replicate_to.hxx +28 -28
  966. package/deps/couchbase-cxx-client/couchbase/result.hxx +28 -28
  967. package/deps/couchbase-cxx-client/couchbase/resume_ingest_search_index_options.hxx +11 -10
  968. package/deps/couchbase-cxx-client/couchbase/retry_action.hxx +10 -10
  969. package/deps/couchbase-cxx-client/couchbase/retry_reason.hxx +53 -51
  970. package/deps/couchbase-cxx-client/couchbase/retry_request.hxx +7 -7
  971. package/deps/couchbase-cxx-client/couchbase/retry_strategy.hxx +4 -4
  972. package/deps/couchbase-cxx-client/couchbase/scan_options.hxx +114 -108
  973. package/deps/couchbase-cxx-client/couchbase/scan_result.hxx +97 -96
  974. package/deps/couchbase-cxx-client/couchbase/scan_result_item.hxx +120 -118
  975. package/deps/couchbase-cxx-client/couchbase/scan_type.hxx +237 -232
  976. package/deps/couchbase-cxx-client/couchbase/scope.hxx +164 -157
  977. package/deps/couchbase-cxx-client/couchbase/scope_search_index_manager.hxx +263 -238
  978. package/deps/couchbase-cxx-client/couchbase/search_date_range.hxx +32 -29
  979. package/deps/couchbase-cxx-client/couchbase/search_facet.hxx +25 -25
  980. package/deps/couchbase-cxx-client/couchbase/search_facet_result.hxx +11 -11
  981. package/deps/couchbase-cxx-client/couchbase/search_geo_distance_units.hxx +11 -1
  982. package/deps/couchbase-cxx-client/couchbase/search_index_manager.hxx +261 -238
  983. package/deps/couchbase-cxx-client/couchbase/search_meta_data.hxx +37 -37
  984. package/deps/couchbase-cxx-client/couchbase/search_metrics.hxx +84 -83
  985. package/deps/couchbase-cxx-client/couchbase/search_numeric_range.hxx +32 -32
  986. package/deps/couchbase-cxx-client/couchbase/search_options.hxx +449 -435
  987. package/deps/couchbase-cxx-client/couchbase/search_query.hxx +32 -30
  988. package/deps/couchbase-cxx-client/couchbase/search_request.hxx +69 -68
  989. package/deps/couchbase-cxx-client/couchbase/search_result.hxx +29 -26
  990. package/deps/couchbase-cxx-client/couchbase/search_row.hxx +52 -52
  991. package/deps/couchbase-cxx-client/couchbase/search_row_location.hxx +20 -20
  992. package/deps/couchbase-cxx-client/couchbase/search_row_locations.hxx +39 -38
  993. package/deps/couchbase-cxx-client/couchbase/search_scan_consistency.hxx +11 -10
  994. package/deps/couchbase-cxx-client/couchbase/search_sort.hxx +20 -20
  995. package/deps/couchbase-cxx-client/couchbase/search_sort_field.hxx +77 -71
  996. package/deps/couchbase-cxx-client/couchbase/search_sort_field_missing.hxx +2 -2
  997. package/deps/couchbase-cxx-client/couchbase/search_sort_field_mode.hxx +3 -3
  998. package/deps/couchbase-cxx-client/couchbase/search_sort_field_type.hxx +4 -4
  999. package/deps/couchbase-cxx-client/couchbase/search_sort_geo_distance.hxx +41 -41
  1000. package/deps/couchbase-cxx-client/couchbase/search_sort_id.hxx +23 -23
  1001. package/deps/couchbase-cxx-client/couchbase/search_sort_score.hxx +23 -23
  1002. package/deps/couchbase-cxx-client/couchbase/search_term_range.hxx +17 -17
  1003. package/deps/couchbase-cxx-client/couchbase/security_options.hxx +50 -50
  1004. package/deps/couchbase-cxx-client/couchbase/service_type.hxx +34 -34
  1005. package/deps/couchbase-cxx-client/couchbase/store_semantics.hxx +28 -28
  1006. package/deps/couchbase-cxx-client/couchbase/subdoc/array_add_unique.hxx +54 -54
  1007. package/deps/couchbase-cxx-client/couchbase/subdoc/array_append.hxx +40 -40
  1008. package/deps/couchbase-cxx-client/couchbase/subdoc/array_insert.hxx +41 -41
  1009. package/deps/couchbase-cxx-client/couchbase/subdoc/array_prepend.hxx +41 -41
  1010. package/deps/couchbase-cxx-client/couchbase/subdoc/count.hxx +24 -24
  1011. package/deps/couchbase-cxx-client/couchbase/subdoc/counter.hxx +41 -41
  1012. package/deps/couchbase-cxx-client/couchbase/subdoc/exists.hxx +24 -24
  1013. package/deps/couchbase-cxx-client/couchbase/subdoc/get.hxx +45 -29
  1014. package/deps/couchbase-cxx-client/couchbase/subdoc/insert.hxx +70 -54
  1015. package/deps/couchbase-cxx-client/couchbase/subdoc/lookup_in_macro.hxx +13 -12
  1016. package/deps/couchbase-cxx-client/couchbase/subdoc/mutate_in_macro.hxx +7 -2
  1017. package/deps/couchbase-cxx-client/couchbase/subdoc/remove.hxx +24 -24
  1018. package/deps/couchbase-cxx-client/couchbase/subdoc/replace.hxx +55 -39
  1019. package/deps/couchbase-cxx-client/couchbase/subdoc/upsert.hxx +70 -54
  1020. package/deps/couchbase-cxx-client/couchbase/term_facet.hxx +16 -16
  1021. package/deps/couchbase-cxx-client/couchbase/term_facet_result.hxx +14 -14
  1022. package/deps/couchbase-cxx-client/couchbase/term_query.hxx +107 -104
  1023. package/deps/couchbase-cxx-client/couchbase/term_range_query.hxx +99 -96
  1024. package/deps/couchbase-cxx-client/couchbase/timeout_options.hxx +118 -112
  1025. package/deps/couchbase-cxx-client/couchbase/tls_verify_mode.hxx +2 -2
  1026. package/deps/couchbase-cxx-client/couchbase/touch_options.hxx +25 -24
  1027. package/deps/couchbase-cxx-client/couchbase/tracing/otel_tracer.hxx +45 -44
  1028. package/deps/couchbase-cxx-client/couchbase/tracing/request_span.hxx +34 -34
  1029. package/deps/couchbase-cxx-client/couchbase/tracing/request_tracer.hxx +27 -25
  1030. package/deps/couchbase-cxx-client/couchbase/tracing_options.hxx +147 -142
  1031. package/deps/couchbase-cxx-client/couchbase/transactions/async_attempt_context.hxx +149 -115
  1032. package/deps/couchbase-cxx-client/couchbase/transactions/attempt_context.hxx +146 -95
  1033. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_result.hxx +52 -80
  1034. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_keyspace.hxx +33 -29
  1035. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_options.hxx +101 -96
  1036. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_query_options.hxx +228 -223
  1037. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_query_result.hxx +11 -12
  1038. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_result.hxx +2 -3
  1039. package/deps/couchbase-cxx-client/couchbase/transactions/transactions_cleanup_config.hxx +105 -104
  1040. package/deps/couchbase-cxx-client/couchbase/transactions/transactions_config.hxx +191 -187
  1041. package/deps/couchbase-cxx-client/couchbase/transactions/transactions_query_config.hxx +32 -32
  1042. package/deps/couchbase-cxx-client/couchbase/transactions.hxx +56 -37
  1043. package/deps/couchbase-cxx-client/couchbase/unfreeze_plan_search_index_options.hxx +11 -10
  1044. package/deps/couchbase-cxx-client/couchbase/unlock_options.hxx +25 -24
  1045. package/deps/couchbase-cxx-client/couchbase/update_bucket_options.hxx +9 -9
  1046. package/deps/couchbase-cxx-client/couchbase/update_collection_options.hxx +35 -34
  1047. package/deps/couchbase-cxx-client/couchbase/upsert_options.hxx +85 -80
  1048. package/deps/couchbase-cxx-client/couchbase/upsert_search_index_options.hxx +9 -9
  1049. package/deps/couchbase-cxx-client/couchbase/vector_query.hxx +82 -62
  1050. package/deps/couchbase-cxx-client/couchbase/vector_search.hxx +51 -47
  1051. package/deps/couchbase-cxx-client/couchbase/vector_search_options.hxx +45 -41
  1052. package/deps/couchbase-cxx-client/couchbase/wan_development_configuration_profile.hxx +13 -13
  1053. package/deps/couchbase-cxx-client/couchbase/watch_query_indexes_options.hxx +41 -41
  1054. package/deps/couchbase-cxx-client/couchbase/wildcard_query.hxx +42 -41
  1055. package/deps/couchbase-cxx-client/third_party/expected/include/tl/expected.hpp +1746 -1584
  1056. package/deps/couchbase-cxx-client/third_party/jsonsl/jsonsl.c +2664 -2638
  1057. package/deps/couchbase-cxx-client/third_party/jsonsl/jsonsl.h +359 -342
  1058. package/dist/binding.d.ts +39 -4
  1059. package/dist/binding.js +4 -1
  1060. package/dist/collection.js +0 -1
  1061. package/dist/diagnosticstypes.js +2 -2
  1062. package/dist/searchtypes.d.ts +0 -4
  1063. package/dist/searchtypes.js +0 -4
  1064. package/dist/transactions.d.ts +1 -0
  1065. package/dist/transactions.js +12 -2
  1066. package/dist/vectorsearch.d.ts +4 -19
  1067. package/dist/vectorsearch.js +24 -19
  1068. package/package.json +29 -28
  1069. package/src/constants.cpp +111 -75
  1070. package/src/jstocbpp_autogen.hpp +146 -15
  1071. package/src/jstocbpp_basic.hpp +23 -0
  1072. package/src/jstocbpp_errors.hpp +9 -9
  1073. package/src/jstocbpp_transactions.hpp +17 -12
  1074. package/src/transaction.cpp +10 -5
  1075. package/tools/gen-bindings-js.js +1 -0
  1076. package/tools/gen-bindings-json.py +5 -2
  1077. package/deps/couchbase-cxx-cache/asio/41f31469d0dd420500b334dc8c2fd3ffe7320d8e/asio/asio/COPYING +0 -4
  1078. package/deps/couchbase-cxx-cache/asio/41f31469d0dd420500b334dc8c2fd3ffe7320d8e/asio/asio/README +0 -4
  1079. package/deps/couchbase-cxx-cache/boringssl/e31ea00c1ea52052d2d78d44006cc88c80fa24a9/boringssl/src/crypto/obj/README +0 -15
  1080. package/deps/couchbase-cxx-cache/boringssl/e31ea00c1ea52052d2d78d44006cc88c80fa24a9/boringssl/src/crypto/perlasm/readme +0 -100
  1081. package/deps/couchbase-cxx-cache/boringssl/e31ea00c1ea52052d2d78d44006cc88c80fa24a9/boringssl/src/pki/testdata/nist-pkits/README.chromium +0 -19
  1082. package/deps/couchbase-cxx-cache/boringssl/e31ea00c1ea52052d2d78d44006cc88c80fa24a9/boringssl/src/pki/testdata/ssl/certificates/README +0 -318
  1083. package/deps/couchbase-cxx-cache/boringssl/e31ea00c1ea52052d2d78d44006cc88c80fa24a9/boringssl/src/pki/testdata/verify_certificate_chain_unittest/README +0 -87
  1084. package/deps/couchbase-cxx-cache/boringssl/e31ea00c1ea52052d2d78d44006cc88c80fa24a9/boringssl/src/pki/testdata/verify_signed_data_unittest/README +0 -35
  1085. package/deps/couchbase-cxx-cache/boringssl/e31ea00c1ea52052d2d78d44006cc88c80fa24a9/boringssl/src/third_party/fiat/README.chromium +0 -11
  1086. package/deps/couchbase-cxx-cache/boringssl/e31ea00c1ea52052d2d78d44006cc88c80fa24a9/boringssl/src/util/bot/README +0 -3
  1087. package/deps/couchbase-cxx-cache/fmt/d3c862243fcf1c41b4c09903f35479bd42f135b7/fmt/support/README +0 -4
  1088. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.cxx +0 -113
  1089. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.hxx +0 -60
  1090. package/deps/couchbase-cxx-client/core/impl/manager_error_context.cxx +0 -100
  1091. package/deps/couchbase-cxx-client/core/impl/search_error_context.cxx +0 -147
  1092. package/deps/couchbase-cxx-client/couchbase/analytics_error_context.hxx +0 -143
  1093. package/deps/couchbase-cxx-client/couchbase/fmt/key_value_error_map_attribute.hxx +0 -100
  1094. package/deps/couchbase-cxx-client/couchbase/fmt/key_value_status_code.hxx +0 -269
  1095. package/deps/couchbase-cxx-client/couchbase/key_value_error_context.hxx +0 -229
  1096. package/deps/couchbase-cxx-client/couchbase/key_value_error_map_attribute.hxx +0 -136
  1097. package/deps/couchbase-cxx-client/couchbase/key_value_error_map_info.hxx +0 -138
  1098. package/deps/couchbase-cxx-client/couchbase/key_value_extended_error_info.hxx +0 -86
  1099. package/deps/couchbase-cxx-client/couchbase/key_value_status_code.hxx +0 -109
  1100. package/deps/couchbase-cxx-client/couchbase/manager_error_context.hxx +0 -111
  1101. package/deps/couchbase-cxx-client/couchbase/query_error_context.hxx +0 -145
  1102. package/deps/couchbase-cxx-client/couchbase/search_error_context.hxx +0 -138
  1103. package/deps/couchbase-cxx-client/couchbase/subdocument_error_context.hxx +0 -147
  1104. package/deps/couchbase-cxx-client/couchbase/transaction_op_error_context.hxx +0 -76
@@ -64,1682 +64,1829 @@ namespace
64
64
  {
65
65
  template<typename Container>
66
66
  struct mcbp_header_view {
67
- const Container& buf_;
67
+ const Container& buf_;
68
68
 
69
- mcbp_header_view(const Container& buf)
70
- : buf_{ buf }
71
- {
72
- }
69
+ mcbp_header_view(const Container& buf)
70
+ : buf_{ buf }
71
+ {
72
+ }
73
73
  };
74
74
 
75
75
  struct mcbp_header_layout {
76
- std::uint8_t magic;
77
- std::uint8_t opcode;
78
- union {
79
- std::uint16_t normal;
80
- struct {
81
- std::uint8_t framing_extras;
82
- std::uint8_t key;
83
- } alt;
84
- } keylen;
85
- std::uint8_t extlen;
86
- std::uint8_t datatype;
87
- std::uint16_t specific;
88
- std::uint32_t bodylen;
89
- std::uint32_t opaque;
90
- std::uint64_t cas;
91
-
92
- [[nodiscard]] constexpr auto specific_name() const -> std::string_view
93
- {
94
- if (magic == 0x18 || magic == 0x81) {
95
- return "status";
96
- }
97
- return "vbucket";
76
+ std::uint8_t magic;
77
+ std::uint8_t opcode;
78
+ union {
79
+ std::uint16_t normal;
80
+ struct {
81
+ std::uint8_t framing_extras;
82
+ std::uint8_t key;
83
+ } alt;
84
+ } keylen;
85
+ std::uint8_t extlen;
86
+ std::uint8_t datatype;
87
+ std::uint16_t specific;
88
+ std::uint32_t bodylen;
89
+ std::uint32_t opaque;
90
+ std::uint64_t cas;
91
+
92
+ [[nodiscard]] constexpr auto specific_name() const -> std::string_view
93
+ {
94
+ if (magic == 0x18 || magic == 0x81) {
95
+ return "status";
98
96
  }
97
+ return "vbucket";
98
+ }
99
99
 
100
- [[nodiscard]] constexpr auto key_length() const -> std::uint16_t
101
- {
102
- if (magic == 0x18 || magic == 0x08) {
103
- return keylen.alt.key;
104
- }
105
- return couchbase::core::utils::byte_swap(keylen.normal);
100
+ [[nodiscard]] constexpr auto key_length() const -> std::uint16_t
101
+ {
102
+ if (magic == 0x18 || magic == 0x08) {
103
+ return keylen.alt.key;
106
104
  }
105
+ return couchbase::core::utils::byte_swap(keylen.normal);
106
+ }
107
107
 
108
- [[nodiscard]] constexpr auto framing_extras_length() const -> std::uint8_t
109
- {
110
- if (magic == 0x18 || magic == 0x08) {
111
- return keylen.alt.framing_extras;
112
- }
113
- return 0;
108
+ [[nodiscard]] constexpr auto framing_extras_length() const -> std::uint8_t
109
+ {
110
+ if (magic == 0x18 || magic == 0x08) {
111
+ return keylen.alt.framing_extras;
114
112
  }
113
+ return 0;
114
+ }
115
115
  };
116
116
  } // namespace
117
117
 
118
118
  template<typename Container>
119
119
  struct fmt::formatter<mcbp_header_view<Container>> {
120
- template<typename ParseContext>
121
- constexpr auto parse(ParseContext& ctx)
122
- {
123
- return ctx.begin();
120
+ template<typename ParseContext>
121
+ constexpr auto parse(ParseContext& ctx)
122
+ {
123
+ return ctx.begin();
124
+ }
125
+
126
+ template<typename FormatContext>
127
+ auto format(const mcbp_header_view<Container>& view, FormatContext& ctx) const
128
+ {
129
+ if (view.buf_.size() < sizeof(couchbase::core::io::binary_header)) {
130
+ return format_to(ctx.out(), "{:n}", spdlog::to_hex(view.buf_));
124
131
  }
125
132
 
126
- template<typename FormatContext>
127
- auto format(const mcbp_header_view<Container>& view, FormatContext& ctx) const
128
- {
129
- if (view.buf_.size() < sizeof(couchbase::core::io::binary_header)) {
130
- return format_to(ctx.out(), "{:n}", spdlog::to_hex(view.buf_));
131
- }
132
-
133
- const auto* header = reinterpret_cast<const mcbp_header_layout*>(view.buf_.data());
134
- return format_to(
135
- ctx.out(),
136
- "{{magic=0x{:x}, opcode=0x{:x}, fextlen={}, keylen={}, extlen={}, datatype={}, {}={}, bodylen={}, opaque={}, cas={}}}",
137
- header->magic,
138
- header->opcode,
139
- header->framing_extras_length(),
140
- header->key_length(),
141
- header->extlen,
142
- header->datatype,
143
- header->specific_name(),
144
- couchbase::core::utils::byte_swap(header->specific),
145
- couchbase::core::utils::byte_swap(header->bodylen),
146
- couchbase::core::utils::byte_swap(header->opaque),
147
- couchbase::core::utils::byte_swap(header->cas));
148
- }
133
+ const auto* header = reinterpret_cast<const mcbp_header_layout*>(view.buf_.data());
134
+ return format_to(ctx.out(),
135
+ "{{magic=0x{:x}, opcode=0x{:x}, fextlen={}, keylen={}, extlen={}, "
136
+ "datatype={}, {}={}, bodylen={}, "
137
+ "opaque={}, cas={}}}",
138
+ header->magic,
139
+ header->opcode,
140
+ header->framing_extras_length(),
141
+ header->key_length(),
142
+ header->extlen,
143
+ header->datatype,
144
+ header->specific_name(),
145
+ couchbase::core::utils::byte_swap(header->specific),
146
+ couchbase::core::utils::byte_swap(header->bodylen),
147
+ couchbase::core::utils::byte_swap(header->opaque),
148
+ couchbase::core::utils::byte_swap(header->cas));
149
+ }
149
150
  };
150
151
 
151
152
  namespace couchbase::core::io
152
153
  {
153
154
  struct connection_endpoints {
154
- connection_endpoints(asio::ip::tcp::endpoint remote_endpoint, asio::ip::tcp::endpoint local_endpoint)
155
- : remote{ std::move(remote_endpoint) }
156
- , remote_address{ remote.address().to_string() }
157
- , remote_address_with_port{ remote.protocol() == asio::ip::tcp::v6() ? fmt::format("[{}]:{}", remote_address, remote.port())
158
- : fmt::format("{}:{}", remote_address, remote.port()) }
159
- , local{ std::move(local_endpoint) }
160
- , local_address{ local.address().to_string() }
161
- , local_address_with_port{ local.protocol() == asio::ip::tcp::v6() ? fmt::format("[{}]:{}", local_address, local.port())
162
- : fmt::format("{}:{}", local_address, local.port()) }
163
- {
164
- }
165
-
166
- asio::ip::tcp::endpoint remote;
167
- std::string remote_address{};
168
- std::string remote_address_with_port{};
169
-
170
- asio::ip::tcp::endpoint local;
171
- std::string local_address{};
172
- std::string local_address_with_port{};
155
+ connection_endpoints(asio::ip::tcp::endpoint remote_endpoint,
156
+ asio::ip::tcp::endpoint local_endpoint)
157
+ : remote{ std::move(remote_endpoint) }
158
+ , remote_address{ remote.address().to_string() }
159
+ , remote_address_with_port{ remote.protocol() == asio::ip::tcp::v6()
160
+ ? fmt::format("[{}]:{}", remote_address, remote.port())
161
+ : fmt::format("{}:{}", remote_address, remote.port()) }
162
+ , local{ std::move(local_endpoint) }
163
+ , local_address{ local.address().to_string() }
164
+ , local_address_with_port{ local.protocol() == asio::ip::tcp::v6()
165
+ ? fmt::format("[{}]:{}", local_address, local.port())
166
+ : fmt::format("{}:{}", local_address, local.port()) }
167
+ {
168
+ }
169
+
170
+ asio::ip::tcp::endpoint remote;
171
+ std::string remote_address{};
172
+ std::string remote_address_with_port{};
173
+
174
+ asio::ip::tcp::endpoint local;
175
+ std::string local_address{};
176
+ std::string local_address_with_port{};
173
177
  };
174
178
 
175
179
  class collection_cache
176
180
  {
177
- private:
178
- std::map<std::string, std::uint32_t> cid_map_{ { "_default._default", 0 } };
179
-
180
- public:
181
- [[nodiscard]] std::optional<std::uint32_t> get(const std::string& path)
182
- {
183
- Expects(!path.empty());
184
- if (auto ptr = cid_map_.find(path); ptr != cid_map_.end()) {
185
- return ptr->second;
186
- }
187
- return std::nullopt;
188
- }
189
-
190
- void update(const std::string& path, std::uint32_t id)
191
- {
192
- Expects(!path.empty());
193
- cid_map_[path] = id;
194
- }
195
-
196
- void reset()
197
- {
198
- cid_map_.clear();
199
- cid_map_["_default._default"] = 0;
181
+ private:
182
+ std::map<std::string, std::uint32_t> cid_map_{ { "_default._default", 0 } };
183
+
184
+ public:
185
+ [[nodiscard]] auto get(const std::string& path) -> std::optional<std::uint32_t>
186
+ {
187
+ Expects(!path.empty());
188
+ if (auto ptr = cid_map_.find(path); ptr != cid_map_.end()) {
189
+ return ptr->second;
200
190
  }
191
+ return std::nullopt;
192
+ }
193
+
194
+ void update(const std::string& path, std::uint32_t id)
195
+ {
196
+ Expects(!path.empty());
197
+ cid_map_[path] = id;
198
+ }
199
+
200
+ void reset()
201
+ {
202
+ cid_map_.clear();
203
+ cid_map_["_default._default"] = 0;
204
+ }
201
205
  };
202
206
 
203
207
  class mcbp_session_impl
204
208
  : public std::enable_shared_from_this<mcbp_session_impl>
205
209
  , public operation_map
206
210
  {
207
- class bootstrap_handler : public std::enable_shared_from_this<bootstrap_handler>
208
- {
209
- private:
210
- std::shared_ptr<mcbp_session_impl> session_;
211
- sasl::ClientContext sasl_;
212
- std::atomic_bool stopped_{ false };
213
- std::string last_error_message_;
214
-
215
- public:
216
- ~bootstrap_handler()
217
- {
218
- stop();
219
- }
220
-
221
- void stop()
222
- {
223
- bool expected_state{ false };
224
- stopped_.compare_exchange_strong(expected_state, true);
225
- }
226
-
227
- static auto sasl_mechanisms(const std::shared_ptr<mcbp_session_impl>& session) -> std::vector<std::string>
228
- {
229
- if (const auto user_mechanisms = session->origin_.credentials().allowed_sasl_mechanisms; user_mechanisms.has_value()) {
230
- return user_mechanisms.value();
231
- }
232
- if (session->is_tls_) {
233
- return { "PLAIN" };
234
- }
235
- return { "SCRAM-SHA512", "SCRAM-SHA256", "SCRAM-SHA1" };
236
- }
237
-
238
- std::string last_error_message() &&
239
- {
240
- return std::move(last_error_message_);
241
- }
242
-
243
- [[nodiscard]] const std::string& last_error_message() const&
244
- {
245
- return last_error_message_;
246
- }
247
-
248
- explicit bootstrap_handler(std::shared_ptr<mcbp_session_impl> session)
249
- : session_(std::move(session))
250
- , sasl_([origin = session_->origin_]() { return origin.username(); },
251
- [origin = session_->origin_]() { return origin.password(); },
252
- sasl_mechanisms(session_))
253
- {
254
- protocol::client_request<protocol::hello_request_body> hello_req;
255
- if (session_->origin_.options().enable_unordered_execution) {
256
- hello_req.body().enable_unordered_execution();
257
- }
258
- if (session_->origin_.options().enable_clustermap_notification) {
259
- hello_req.body().enable_clustermap_change_notification();
260
- hello_req.body().enable_deduplicate_not_my_vbucket_clustermap();
261
- }
262
- if (session_->origin_.options().enable_compression) {
263
- hello_req.body().enable_compression();
264
- }
265
- if (session_->origin_.options().enable_mutation_tokens) {
266
- hello_req.body().enable_mutation_tokens();
267
- }
268
- hello_req.opaque(session_->next_opaque());
269
- auto user_agent =
270
- meta::user_agent_for_mcbp(session_->client_id_, session_->id_, session_->origin_.options().user_agent_extra, 250);
271
- hello_req.body().user_agent(user_agent);
272
- CB_LOG_DEBUG("{} user_agent={}, requested_features=[{}]",
273
- session_->log_prefix_,
274
- user_agent,
275
- utils::join_strings_fmt(hello_req.body().features(), ", "));
276
- session_->write(hello_req.data());
277
-
278
- if (!session_->origin_.credentials().uses_certificate()) {
279
- protocol::client_request<protocol::sasl_list_mechs_request_body> list_req;
280
- list_req.opaque(session_->next_opaque());
281
- session_->write(list_req.data());
282
-
283
- protocol::client_request<protocol::sasl_auth_request_body> auth_req;
284
- auto [sasl_code, sasl_payload] = sasl_.start();
285
- auth_req.opaque(session_->next_opaque());
286
- auth_req.body().mechanism(sasl_.get_name());
287
- auth_req.body().sasl_data(sasl_payload);
288
- session_->write(auth_req.data());
289
- }
290
-
291
- session_->flush();
292
- }
293
-
294
- void complete(std::error_code ec)
295
- {
296
- if (bool expected_state{ false }; stopped_.compare_exchange_strong(expected_state, true)) {
297
- session_->invoke_bootstrap_handler(ec);
298
- }
299
- }
300
-
301
- void auth_success()
302
- {
303
- session_->authenticated_ = true;
304
- if (session_->supports_feature(protocol::hello_feature::xerror)) {
305
- protocol::client_request<protocol::get_error_map_request_body> errmap_req;
306
- errmap_req.opaque(session_->next_opaque());
307
- session_->write(errmap_req.data());
308
- }
309
- if (session_->bucket_name_) {
310
- protocol::client_request<protocol::select_bucket_request_body> sb_req;
311
- sb_req.opaque(session_->next_opaque());
312
- sb_req.body().bucket_name(session_->bucket_name_.value());
313
- session_->write(sb_req.data());
314
- }
315
- protocol::client_request<protocol::get_cluster_config_request_body> cfg_req;
316
- cfg_req.opaque(session_->next_opaque());
317
- session_->write(cfg_req.data());
318
- session_->flush();
319
- }
320
-
321
- void handle(mcbp_message&& msg)
322
- {
323
- if (stopped_ || !session_) {
324
- return;
325
- }
326
- Expects(protocol::is_valid_magic(msg.header.magic));
327
- switch (auto magic = static_cast<protocol::magic>(msg.header.magic)) {
328
- case protocol::magic::client_response:
329
- case protocol::magic::alt_client_response:
330
- Expects(protocol::is_valid_client_opcode(msg.header.opcode));
331
- switch (auto status = static_cast<key_value_status_code>(msg.header.status())) {
332
- case key_value_status_code::rate_limited_max_commands:
333
- case key_value_status_code::rate_limited_max_connections:
334
- case key_value_status_code::rate_limited_network_egress:
335
- case key_value_status_code::rate_limited_network_ingress:
336
- last_error_message_ = fmt::format(
337
- "unable to bootstrap MCBP session (bucket={}, opcode={}, status={}), the user has reached rate limit",
338
- session_->bucket_name_.value_or(""),
339
- protocol::client_opcode(msg.header.opcode),
340
- status);
341
- CB_LOG_DEBUG("{} {}", session_->log_prefix_, last_error_message_);
342
- return complete(errc::common::rate_limited);
343
-
344
- case key_value_status_code::scope_size_limit_exceeded:
345
- last_error_message_ = fmt::format(
346
- "unable to bootstrap MCBP session (bucket={}, opcode={}, status={}), the user has reached quota limit",
347
- session_->bucket_name_.value_or(""),
348
- protocol::client_opcode(msg.header.opcode),
349
- status);
350
- CB_LOG_DEBUG("{} {}", session_->log_prefix_, last_error_message_);
351
- return complete(errc::common::quota_limited);
352
-
353
- default:
354
- break;
355
- }
356
- switch (auto opcode = static_cast<protocol::client_opcode>(msg.header.opcode)) {
357
- case protocol::client_opcode::hello: {
358
- protocol::client_response<protocol::hello_response_body> resp(std::move(msg));
359
- if (resp.status() == key_value_status_code::success) {
360
- session_->supported_features_ = resp.body().supported_features();
361
- CB_LOG_DEBUG("{} supported_features=[{}]",
362
- session_->log_prefix_,
363
- utils::join_strings_fmt(session_->supported_features_, ", "));
364
- if (session_->origin_.credentials().uses_certificate()) {
365
- CB_LOG_DEBUG("{} skip SASL authentication, because TLS certificate was specified",
366
- session_->log_prefix_);
367
- return auth_success();
368
- }
369
- } else {
370
- last_error_message_ = fmt::format(
371
- "unexpected message status during bootstrap: {} (opaque={})", resp.error_message(), resp.opaque());
372
- CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
373
- return complete(errc::network::handshake_failure);
374
- }
375
- } break;
376
- case protocol::client_opcode::sasl_list_mechs: {
377
- protocol::client_response<protocol::sasl_list_mechs_response_body> resp(std::move(msg));
378
- if (resp.status() != key_value_status_code::success) {
379
- last_error_message_ = fmt::format(
380
- "unexpected message status during bootstrap: {} (opaque={})", resp.error_message(), resp.opaque());
381
- CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
382
- return complete(errc::common::authentication_failure);
383
- }
384
- } break;
385
- case protocol::client_opcode::sasl_auth: {
386
- protocol::client_response<protocol::sasl_auth_response_body> resp(std::move(msg));
387
- if (resp.status() == key_value_status_code::success) {
388
- return auth_success();
389
- }
390
- if (resp.status() == key_value_status_code::auth_continue) {
391
- auto [sasl_code, sasl_payload] = sasl_.step(resp.body().value());
392
- if (sasl_code == sasl::error::OK) {
393
- return auth_success();
394
- }
395
- if (sasl_code == sasl::error::CONTINUE) {
396
- protocol::client_request<protocol::sasl_step_request_body> req;
397
- req.opaque(session_->next_opaque());
398
- req.body().mechanism(sasl_.get_name());
399
- req.body().sasl_data(sasl_payload);
400
- session_->write_and_flush(req.data());
401
- } else {
402
- last_error_message_ =
403
- fmt::format("unable to authenticate: (sasl_code={}, opaque={})", sasl_code, resp.opaque());
404
- CB_LOG_ERROR("{} {}", session_->log_prefix_, last_error_message_);
405
- return complete(errc::common::authentication_failure);
406
- }
407
- } else {
408
- last_error_message_ = fmt::format("{} unexpected message status during bootstrap: {} (opaque={})",
409
- session_->log_prefix_,
410
- resp.error_message(),
411
- resp.opaque());
412
- CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
413
- return complete(errc::common::authentication_failure);
414
- }
415
- } break;
416
- case protocol::client_opcode::sasl_step: {
417
- protocol::client_response<protocol::sasl_step_response_body> resp(std::move(msg));
418
- if (resp.status() == key_value_status_code::success) {
419
- return auth_success();
420
- }
421
- last_error_message_ =
422
- fmt::format("unable to authenticate (opcode={}, status={}, opaque={})", opcode, resp.status(), resp.opaque());
423
- CB_LOG_ERROR("{} {}", session_->log_prefix_, last_error_message_);
424
- return complete(errc::common::authentication_failure);
425
- }
426
- case protocol::client_opcode::get_error_map: {
427
- protocol::client_response<protocol::get_error_map_response_body> resp(std::move(msg));
428
- if (resp.status() == key_value_status_code::success) {
429
- session_->error_map_.emplace(resp.body().errmap());
430
- } else {
431
- last_error_message_ = fmt::format("unexpected message status during bootstrap: {} (opaque={}, {:n})",
432
- resp.error_message(),
433
- resp.opaque(),
434
- spdlog::to_hex(resp.header()));
435
- CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
436
- return complete(errc::network::protocol_error);
437
- }
438
- } break;
439
- case protocol::client_opcode::select_bucket: {
440
- protocol::client_response<protocol::select_bucket_response_body> resp(std::move(msg));
441
- if (resp.status() == key_value_status_code::success) {
442
- CB_LOG_DEBUG("{} selected bucket: {}", session_->log_prefix_, session_->bucket_name_.value_or(""));
443
- session_->bucket_selected_ = true;
444
- } else if (resp.status() == key_value_status_code::not_found) {
445
- last_error_message_ =
446
- fmt::format("kv_engine node does not have configuration propagated yet (opcode={}, status={}, opaque={})",
447
- opcode,
448
- resp.status(),
449
- resp.opaque());
450
- CB_LOG_DEBUG("{} {}", session_->log_prefix_, last_error_message_);
451
- return complete(errc::network::configuration_not_available);
452
- } else if (resp.status() == key_value_status_code::no_access) {
453
- last_error_message_ = fmt::format("unable to select bucket: {}, probably the bucket does not exist",
454
- session_->bucket_name_.value_or(""));
455
- CB_LOG_DEBUG("{} {}", session_->log_prefix_, last_error_message_);
456
- session_->bucket_selected_ = false;
457
- return complete(errc::common::bucket_not_found);
458
- } else {
459
- last_error_message_ = fmt::format("unexpected message status during bootstrap: {} (opaque={}, {:n})",
460
- resp.error_message(),
461
- resp.opaque(),
462
- spdlog::to_hex(resp.header()));
463
- CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
464
- return complete(errc::common::bucket_not_found);
465
- }
466
- } break;
467
- case protocol::client_opcode::get_cluster_config: {
468
- protocol::cmd_info info{ session_->connection_endpoints_.remote_address,
469
- session_->connection_endpoints_.remote.port() };
470
- if (session_->origin_.options().dump_configuration) {
471
- std::string_view config_text{ reinterpret_cast<const char*>(msg.body.data()), msg.body.size() };
472
- CB_LOG_TRACE(
473
- "{} configuration from get_cluster_config request (bootstrap, size={}, endpoint=\"{}:{}\"), {}",
474
- session_->log_prefix_,
475
- config_text.size(),
476
- info.endpoint_address,
477
- info.endpoint_port,
478
- config_text);
479
- }
480
- protocol::client_response<protocol::get_cluster_config_response_body> resp(std::move(msg), info);
481
- if (resp.status() == key_value_status_code::success) {
482
- // MB-60405 fixes this for 7.6.2, but for earlier versions we need to protect against using a
483
- // config that has an empty vbucket map. Ideally we don't timeout if we retry here, but a timeout
484
- // would be more acceptable than a crash and if we do timeout, we have a clear indication of the
485
- // problem (i.e. it is a server bug and we cannot use a config w/ an empty vbucket map).
486
- if (resp.body().config().vbmap && resp.body().config().vbmap->size() == 0) {
487
- CB_LOG_WARNING("{} received a configuration with an empty vbucket map, retrying",
488
- session_->log_prefix_);
489
- return complete(errc::network::configuration_not_available);
490
- }
491
- session_->update_configuration(resp.body().config());
492
- complete({});
493
- } else if (resp.status() == key_value_status_code::not_found) {
494
- last_error_message_ =
495
- fmt::format("kv_engine node does not have configuration propagated yet (opcode={}, status={}, opaque={})",
496
- opcode,
497
- resp.status(),
498
- resp.opaque());
499
- CB_LOG_DEBUG("{} {}", session_->log_prefix_, last_error_message_);
500
- return complete(errc::network::configuration_not_available);
501
- } else if (resp.status() == key_value_status_code::no_bucket && !session_->bucket_name_) {
502
- // bucket-less session, but the server wants bucket
503
- session_->supports_gcccp_ = false;
504
- CB_LOG_WARNING("{} this server does not support GCCCP, open bucket before making any cluster-level command",
505
- session_->log_prefix_);
506
- session_->update_configuration(topology::make_blank_configuration(
507
- session_->connection_endpoints_.remote_address, session_->connection_endpoints_.remote.port(), 0));
508
- complete({});
509
- } else {
510
- last_error_message_ = fmt::format("unexpected message status during bootstrap: {} (opaque={}, {:n})",
511
- resp.error_message(),
512
- resp.opaque(),
513
- spdlog::to_hex(resp.header()));
514
- CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
515
- return complete(errc::network::protocol_error);
516
- }
517
- } break;
518
- default:
519
- last_error_message_ = fmt::format("unexpected message during bootstrap: {}", opcode);
520
- CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
521
- return complete(errc::network::protocol_error);
522
- }
523
- break;
524
- case protocol::magic::server_request:
525
- Expects(protocol::is_valid_server_request_opcode(msg.header.opcode));
526
- switch (static_cast<protocol::server_opcode>(msg.header.opcode)) {
527
- case protocol::server_opcode::cluster_map_change_notification: {
528
- protocol::cmd_info info{ session_->bootstrap_hostname_, session_->bootstrap_port_number_ };
529
- if (session_->origin_.options().dump_configuration) {
530
- std::string_view config_text{ reinterpret_cast<const char*>(msg.body.data()), msg.body.size() };
531
- CB_LOG_TRACE(
532
- "{} configuration from cluster_map_change_notification request (size={}, endpoint=\"{}:{}\"), {}",
533
- session_->log_prefix_,
534
- config_text.size(),
535
- info.endpoint_address,
536
- info.endpoint_port,
537
- config_text);
538
- }
539
- protocol::server_request<protocol::cluster_map_change_notification_request_body> req(std::move(msg), info);
540
- std::optional<topology::configuration> config = req.body().config();
541
- if (session_ && config.has_value()) {
542
- if ((!config->bucket.has_value() && req.body().bucket().empty()) ||
543
- (session_->bucket_name_.has_value() && !req.body().bucket().empty() &&
544
- session_->bucket_name_.value() == req.body().bucket())) {
545
- session_->update_configuration(std::move(config.value()));
546
- }
547
- }
548
- } break;
549
- default:
550
- CB_LOG_WARNING("{} unexpected server request: opcode={:x}, opaque={}{:a}{:a}",
551
- session_->log_prefix_,
552
- msg.header.opcode,
553
- utils::byte_swap(msg.header.opaque),
554
- spdlog::to_hex(msg.header_data()),
555
- spdlog::to_hex(msg.body));
556
- }
557
- break;
558
- case protocol::magic::client_request:
559
- case protocol::magic::alt_client_request:
560
- case protocol::magic::server_response:
561
- CB_LOG_WARNING("{} unexpected magic: {} (opcode={:x}, opaque={}){:a}{:a}",
562
- session_->log_prefix_,
563
- magic,
564
- msg.header.opcode,
565
- utils::byte_swap(msg.header.opaque),
566
- spdlog::to_hex(msg.header_data()),
567
- spdlog::to_hex(msg.body));
568
- break;
569
- }
570
- }
571
- };
572
-
573
- class message_handler : public std::enable_shared_from_this<message_handler>
574
- {
575
- private:
576
- std::shared_ptr<mcbp_session_impl> session_;
577
- std::atomic_bool stopped_{ false };
578
-
579
- public:
580
- explicit message_handler(std::shared_ptr<mcbp_session_impl> session)
581
- : session_(std::move(session))
582
- {
583
- }
584
-
585
- ~message_handler()
586
- {
587
- stop();
588
- }
589
-
590
- void start()
591
- {
592
- }
593
-
594
- void stop()
595
- {
596
- }
597
-
598
- void handle(mcbp_message&& msg)
599
- {
600
- if (stopped_ || !session_) {
601
- return;
602
- }
603
- Expects(protocol::is_valid_magic(msg.header.magic));
604
- switch (auto magic = static_cast<protocol::magic>(msg.header.magic)) {
605
- case protocol::magic::client_response:
606
- case protocol::magic::alt_client_response:
607
- Expects(protocol::is_valid_client_opcode(msg.header.opcode));
608
- switch (auto opcode = static_cast<protocol::client_opcode>(msg.header.opcode)) {
609
- case protocol::client_opcode::get_cluster_config: {
610
- protocol::cmd_info info{ session_->bootstrap_hostname_, session_->bootstrap_port_number_ };
611
- if (session_->origin_.options().dump_configuration) {
612
- std::string_view config_text{ reinterpret_cast<const char*>(msg.body.data()), msg.body.size() };
613
- CB_LOG_TRACE("{} configuration from get_cluster_config response (size={}, endpoint=\"{}:{}\"), {}",
614
- session_->log_prefix_,
615
- config_text.size(),
616
- info.endpoint_address,
617
- info.endpoint_port,
618
- config_text);
619
- }
620
- protocol::client_response<protocol::get_cluster_config_response_body> resp(std::move(msg), info);
621
- if (resp.status() == key_value_status_code::success) {
622
- if (session_) {
623
- session_->update_configuration(resp.body().config());
624
- }
625
- } else {
626
- CB_LOG_WARNING("{} unexpected message status: {} (opaque={})",
627
- session_->log_prefix_,
628
- resp.error_message(),
629
- resp.opaque());
630
- }
631
- } break;
632
- case protocol::client_opcode::noop:
633
- case protocol::client_opcode::get_collections_manifest:
634
- case protocol::client_opcode::get_collection_id:
635
- case protocol::client_opcode::get:
636
- case protocol::client_opcode::get_and_lock:
637
- case protocol::client_opcode::get_and_touch:
638
- case protocol::client_opcode::get_meta:
639
- case protocol::client_opcode::get_replica:
640
- case protocol::client_opcode::touch:
641
- case protocol::client_opcode::insert:
642
- case protocol::client_opcode::replace:
643
- case protocol::client_opcode::upsert:
644
- case protocol::client_opcode::append:
645
- case protocol::client_opcode::prepend:
646
- case protocol::client_opcode::remove:
647
- case protocol::client_opcode::observe_seqno:
648
- case protocol::client_opcode::unlock:
649
- case protocol::client_opcode::increment:
650
- case protocol::client_opcode::range_scan_create:
651
- case protocol::client_opcode::range_scan_continue:
652
- case protocol::client_opcode::range_scan_cancel:
653
- case protocol::client_opcode::decrement:
654
- case protocol::client_opcode::subdoc_multi_lookup:
655
- case protocol::client_opcode::subdoc_multi_mutation: {
656
- std::uint16_t status = utils::byte_swap(msg.header.specific);
657
- if (status == static_cast<std::uint16_t>(key_value_status_code::not_my_vbucket)) {
658
- session_->handle_not_my_vbucket(msg);
659
- }
660
-
661
- std::uint32_t opaque = utils::byte_swap(msg.header.opaque);
662
- if (session_->handle_request(opcode, status, opaque, std::move(msg))) {
663
- CB_LOG_TRACE("{} MCBP invoked operation handler: opcode={}, opaque={}, status={}",
664
- session_->log_prefix_,
665
- opcode,
666
- opaque,
667
- protocol::status_to_string(status));
668
- } else {
669
- CB_LOG_DEBUG("{} unexpected orphan response: opcode={}, opaque={}, status={}",
670
- session_->log_prefix_,
671
- opcode,
672
- opaque,
673
- protocol::status_to_string(status));
674
- }
675
- } break;
676
- default:
677
- CB_LOG_WARNING("{} unexpected client response: opcode={}, opaque={}{:a}{:a})",
678
- session_->log_prefix_,
679
- opcode,
680
- msg.header.opaque,
681
- spdlog::to_hex(msg.header_data()),
682
- spdlog::to_hex(msg.body));
683
- }
684
- break;
685
- case protocol::magic::server_request:
686
- Expects(protocol::is_valid_server_request_opcode(msg.header.opcode));
687
- switch (static_cast<protocol::server_opcode>(msg.header.opcode)) {
688
- case protocol::server_opcode::cluster_map_change_notification: {
689
- protocol::cmd_info info{ session_->bootstrap_hostname_, session_->bootstrap_port_number_ };
690
- if (session_->origin_.options().dump_configuration) {
691
- std::string_view config_text{ reinterpret_cast<const char*>(msg.body.data()), msg.body.size() };
692
- CB_LOG_TRACE(
693
- "{} configuration from cluster_map_change_notification request (size={}, endpoint=\"{}:{}\"), {}",
694
- session_->log_prefix_,
695
- config_text.size(),
696
- info.endpoint_address,
697
- info.endpoint_port,
698
- config_text);
699
- }
700
- protocol::server_request<protocol::cluster_map_change_notification_request_body> req(std::move(msg), info);
701
- std::optional<topology::configuration> config = req.body().config();
702
- if (session_ && config.has_value()) {
703
- if ((!config->bucket.has_value() && req.body().bucket().empty()) ||
704
- (session_->bucket_name_.has_value() && !req.body().bucket().empty() &&
705
- session_->bucket_name_.value() == req.body().bucket())) {
706
- session_->update_configuration(std::move(config.value()));
707
- }
708
- }
709
- } break;
710
- default:
711
- CB_LOG_WARNING("{} unexpected server request: opcode={:x}, opaque={}{:a}{:a}",
712
- session_->log_prefix_,
713
- msg.header.opcode,
714
- msg.header.opaque,
715
- spdlog::to_hex(msg.header_data()),
716
- spdlog::to_hex(msg.body));
717
- }
718
- break;
719
- case protocol::magic::client_request:
720
- case protocol::magic::alt_client_request:
721
- case protocol::magic::server_response:
722
- CB_LOG_WARNING("{} unexpected magic: {} (opcode={:x}, opaque={}){:a}{:a}",
723
- session_->log_prefix_,
724
- magic,
725
- msg.header.opcode,
726
- msg.header.opaque,
727
- spdlog::to_hex(msg.header_data()),
728
- spdlog::to_hex(msg.body));
729
- break;
730
- }
731
- }
732
- };
211
+ class bootstrap_handler : public std::enable_shared_from_this<bootstrap_handler>
212
+ {
213
+ private:
214
+ std::shared_ptr<mcbp_session_impl> session_;
215
+ sasl::ClientContext sasl_;
216
+ std::atomic_bool stopped_{ false };
217
+ std::string last_error_message_;
733
218
 
734
219
  public:
735
- mcbp_session_impl() = delete;
736
- mcbp_session_impl(std::string_view client_id,
737
- asio::io_context& ctx,
738
- couchbase::core::origin origin,
739
- std::shared_ptr<impl::bootstrap_state_listener> state_listener,
740
- std::optional<std::string> bucket_name = {},
741
- std::vector<protocol::hello_feature> known_features = {})
742
- : client_id_(client_id)
743
- , ctx_(ctx)
744
- , resolver_(ctx_)
745
- , stream_(std::make_unique<plain_stream_impl>(ctx_))
746
- , bootstrap_deadline_(ctx_)
747
- , connection_deadline_(ctx_)
748
- , retry_backoff_(ctx_)
749
- , ping_deadline_(ctx_)
750
- , origin_{ std::move(origin) }
751
- , bucket_name_{ std::move(bucket_name) }
752
- , supported_features_{ std::move(known_features) }
753
- , is_tls_{ false }
754
- , state_listener_{ std::move(state_listener) }
755
- , codec_{ { supported_features_.begin(), supported_features_.end() } }
220
+ ~bootstrap_handler()
756
221
  {
757
- log_prefix_ = fmt::format("[{}/{}/{}/{}]", client_id_, id_, stream_->log_prefix(), bucket_name_.value_or("-"));
758
- }
759
-
760
- mcbp_session_impl(std::string_view client_id,
761
- asio::io_context& ctx,
762
- asio::ssl::context& tls,
763
- couchbase::core::origin origin,
764
- std::shared_ptr<impl::bootstrap_state_listener> state_listener,
765
- std::optional<std::string> bucket_name = {},
766
- std::vector<protocol::hello_feature> known_features = {})
767
- : client_id_(client_id)
768
- , ctx_(ctx)
769
- , resolver_(ctx_)
770
- , stream_(std::make_unique<tls_stream_impl>(ctx_, tls))
771
- , bootstrap_deadline_(ctx_)
772
- , connection_deadline_(ctx_)
773
- , retry_backoff_(ctx_)
774
- , ping_deadline_(ctx_)
775
- , origin_(std::move(origin))
776
- , bucket_name_(std::move(bucket_name))
777
- , supported_features_(std::move(known_features))
778
- , is_tls_{ true }
779
- , state_listener_{ std::move(state_listener) }
780
- , codec_{ { supported_features_.begin(), supported_features_.end() } }
781
- {
782
- log_prefix_ = fmt::format("[{}/{}/{}/{}]", client_id_, id_, stream_->log_prefix(), bucket_name_.value_or("-"));
222
+ stop();
783
223
  }
784
224
 
785
- ~mcbp_session_impl()
225
+ void stop()
786
226
  {
787
- CB_LOG_DEBUG("{} destroy MCBP connection", log_prefix_);
788
- stop(retry_reason::do_not_retry);
227
+ bool expected_state{ false };
228
+ stopped_.compare_exchange_strong(expected_state, true);
789
229
  }
790
230
 
791
- [[nodiscard]] const std::string& log_prefix() const
231
+ static auto sasl_mechanisms(const std::shared_ptr<mcbp_session_impl>& session)
232
+ -> std::vector<std::string>
792
233
  {
793
- return log_prefix_;
234
+ if (const auto user_mechanisms = session->origin_.credentials().allowed_sasl_mechanisms;
235
+ user_mechanisms.has_value()) {
236
+ return user_mechanisms.value();
237
+ }
238
+ if (session->is_tls_) {
239
+ return { "PLAIN" };
240
+ }
241
+ return { "SCRAM-SHA512", "SCRAM-SHA256", "SCRAM-SHA1" };
794
242
  }
795
243
 
796
- std::string remote_address() const
244
+ auto last_error_message() && -> std::string
797
245
  {
798
- return connection_endpoints_.remote_address_with_port;
246
+ return std::move(last_error_message_);
799
247
  }
800
248
 
801
- std::string local_address() const
249
+ [[nodiscard]] auto last_error_message() const& -> const std::string&
802
250
  {
803
- return connection_endpoints_.local_address_with_port;
251
+ return last_error_message_;
804
252
  }
805
253
 
806
- [[nodiscard]] diag::endpoint_diag_info diag_info() const
807
- {
808
- return { service_type::key_value,
809
- id_,
810
- last_active_.time_since_epoch().count() == 0 ? std::nullopt
811
- : std::make_optional(std::chrono::duration_cast<std::chrono::microseconds>(
812
- std::chrono::steady_clock::now() - last_active_)),
813
- remote_address(),
814
- local_address(),
815
- state_,
816
- bucket_name_ };
817
- }
818
-
819
- void ping(std::shared_ptr<diag::ping_reporter> handler, std::optional<std::chrono::milliseconds> timeout)
254
+ explicit bootstrap_handler(std::shared_ptr<mcbp_session_impl> session)
255
+ : session_(std::move(session))
256
+ , sasl_(
257
+ [origin = session_->origin_]() {
258
+ return origin.username();
259
+ },
260
+ [origin = session_->origin_]() {
261
+ return origin.password();
262
+ },
263
+ sasl_mechanisms(session_))
820
264
  {
821
- if (!bootstrapped_) {
822
- handler->report({
823
- service_type::key_value,
824
- id_,
825
- std::chrono::microseconds(0),
826
- remote_address(),
827
- local_address(),
828
- diag::ping_state::error,
829
- bucket_name_,
830
- last_bootstrap_error_message_.has_value() ? last_bootstrap_error_message_.value()
831
- : "Bootstrap incomplete, cannot perform ping.",
832
- });
833
- return;
834
- }
835
- protocol::client_request<protocol::mcbp_noop_request_body> req;
836
- req.opaque(next_opaque());
837
- write_and_subscribe(req.opaque(),
838
- req.data(false),
839
- [start = std::chrono::steady_clock::now(), self = shared_from_this(), handler](
840
- std::error_code ec,
841
- retry_reason reason,
842
- io::mcbp_message&& /* msg */,
843
- std::optional<key_value_error_map_info> /* error_info */) {
844
- diag::ping_state state = diag::ping_state::ok;
845
- std::optional<std::string> error{};
846
- if (ec) {
847
- if (ec == errc::common::unambiguous_timeout || ec == errc::common::ambiguous_timeout) {
848
- state = diag::ping_state::timeout;
849
- } else {
850
- state = diag::ping_state::error;
851
- }
852
- error.emplace(fmt::format("code={}, message={}, reason={}", ec.value(), ec.message(), reason));
853
- }
854
- handler->report({
855
- service_type::key_value,
856
- self->id_,
857
- std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start),
858
- self->remote_address(),
859
- self->local_address(),
860
- state,
861
- self->bucket_name_,
862
- error,
863
- });
864
- });
865
- ping_deadline_.expires_after(timeout.value_or(origin_.options().key_value_timeout));
866
- ping_deadline_.async_wait([self = this->shared_from_this(), opaque = req.opaque()](std::error_code ec) {
867
- if (ec == asio::error::operation_aborted) {
868
- return;
869
- }
870
- static_cast<void>(self->cancel(opaque, errc::common::unambiguous_timeout, retry_reason::do_not_retry));
871
- });
265
+ protocol::client_request<protocol::hello_request_body> hello_req;
266
+ if (session_->origin_.options().enable_unordered_execution) {
267
+ hello_req.body().enable_unordered_execution();
268
+ }
269
+ if (session_->origin_.options().enable_clustermap_notification) {
270
+ hello_req.body().enable_clustermap_change_notification();
271
+ hello_req.body().enable_deduplicate_not_my_vbucket_clustermap();
272
+ }
273
+ if (session_->origin_.options().enable_compression) {
274
+ hello_req.body().enable_compression();
275
+ }
276
+ if (session_->origin_.options().enable_mutation_tokens) {
277
+ hello_req.body().enable_mutation_tokens();
278
+ }
279
+ hello_req.opaque(session_->next_opaque());
280
+ auto user_agent = meta::user_agent_for_mcbp(
281
+ session_->client_id_, session_->id_, session_->origin_.options().user_agent_extra, 250);
282
+ hello_req.body().user_agent(user_agent);
283
+ CB_LOG_DEBUG("{} user_agent={}, requested_features=[{}]",
284
+ session_->log_prefix_,
285
+ user_agent,
286
+ utils::join_strings_fmt(hello_req.body().features(), ", "));
287
+ session_->write(hello_req.data());
288
+
289
+ if (!session_->origin_.credentials().uses_certificate()) {
290
+ protocol::client_request<protocol::sasl_list_mechs_request_body> list_req;
291
+ list_req.opaque(session_->next_opaque());
292
+ session_->write(list_req.data());
293
+
294
+ protocol::client_request<protocol::sasl_auth_request_body> auth_req;
295
+ auto [sasl_code, sasl_payload] = sasl_.start();
296
+ auth_req.opaque(session_->next_opaque());
297
+ auth_req.body().mechanism(sasl_.get_name());
298
+ auth_req.body().sasl_data(sasl_payload);
299
+ session_->write(auth_req.data());
300
+ }
301
+
302
+ session_->flush();
872
303
  }
873
304
 
874
- [[nodiscard]] mcbp_context context() const
305
+ void complete(std::error_code ec)
875
306
  {
876
- return { config_, supported_features_ };
307
+ if (bool expected_state{ false }; stopped_.compare_exchange_strong(expected_state, true)) {
308
+ session_->invoke_bootstrap_handler(ec);
309
+ }
877
310
  }
878
311
 
879
- void bootstrap(utils::movable_function<void(std::error_code, topology::configuration)>&& callback,
880
- bool retry_on_bucket_not_found = false)
312
+ void auth_success()
881
313
  {
882
- retry_bootstrap_on_bucket_not_found_ = retry_on_bucket_not_found;
883
- bootstrap_callback_ = std::move(callback);
884
- bootstrap_deadline_.expires_after(origin_.options().bootstrap_timeout);
885
- bootstrap_deadline_.async_wait([self = shared_from_this()](std::error_code ec) {
886
- if (ec == asio::error::operation_aborted || self->stopped_) {
887
- return;
888
- }
889
- if (!ec) {
890
- ec = errc::common::unambiguous_timeout;
891
- }
892
- if (self->state_listener_) {
893
- self->state_listener_->report_bootstrap_error(fmt::format("{}:{}", self->bootstrap_hostname_, self->bootstrap_port_), ec);
894
- }
895
- CB_LOG_WARNING("{} unable to bootstrap in time", self->log_prefix_);
896
- if (auto h = std::move(self->bootstrap_callback_); h) {
897
- h(ec, {});
898
- }
899
- self->stop(retry_reason::do_not_retry);
900
- });
901
- initiate_bootstrap();
314
+ session_->authenticated_ = true;
315
+ if (session_->supports_feature(protocol::hello_feature::xerror)) {
316
+ protocol::client_request<protocol::get_error_map_request_body> errmap_req;
317
+ errmap_req.opaque(session_->next_opaque());
318
+ session_->write(errmap_req.data());
319
+ }
320
+ if (session_->bucket_name_) {
321
+ protocol::client_request<protocol::select_bucket_request_body> sb_req;
322
+ sb_req.opaque(session_->next_opaque());
323
+ sb_req.body().bucket_name(session_->bucket_name_.value());
324
+ session_->write(sb_req.data());
325
+ }
326
+ protocol::client_request<protocol::get_cluster_config_request_body> cfg_req;
327
+ cfg_req.opaque(session_->next_opaque());
328
+ session_->write(cfg_req.data());
329
+ session_->flush();
902
330
  }
903
331
 
904
- void initiate_bootstrap()
332
+ void handle(mcbp_message&& msg)
905
333
  {
906
- if (stopped_) {
907
- return;
908
- }
909
- bootstrapped_ = false;
910
- if (bootstrap_handler_) {
911
- last_bootstrap_error_message_ = std::move(bootstrap_handler_)->last_error_message();
912
- }
913
- bootstrap_handler_ = nullptr;
914
- state_ = diag::endpoint_state::connecting;
915
- if (stream_->is_open()) {
916
- std::string old_id = stream_->id();
917
- stream_->reopen();
918
- CB_LOG_TRACE(R"({} reopen socket connection "{}" -> "{}", host="{}", port={})",
919
- log_prefix_,
920
- old_id,
921
- stream_->id(),
922
- bootstrap_hostname_,
923
- bootstrap_port_);
924
- }
925
- if (origin_.exhausted()) {
926
- auto backoff = std::chrono::milliseconds(500);
927
- CB_LOG_DEBUG("{} reached the end of list of bootstrap nodes, waiting for {}ms before restart", log_prefix_, backoff.count());
928
- retry_backoff_.expires_after(backoff);
929
- retry_backoff_.async_wait([self = shared_from_this()](std::error_code ec) mutable {
930
- if (ec == asio::error::operation_aborted || self->stopped_) {
931
- return;
334
+ if (stopped_ || !session_) {
335
+ return;
336
+ }
337
+ Expects(protocol::is_valid_magic(msg.header.magic));
338
+ switch (auto magic = static_cast<protocol::magic>(msg.header.magic)) {
339
+ case protocol::magic::client_response:
340
+ case protocol::magic::alt_client_response:
341
+ Expects(protocol::is_valid_client_opcode(msg.header.opcode));
342
+ switch (auto status = static_cast<key_value_status_code>(msg.header.status())) {
343
+ case key_value_status_code::rate_limited_max_commands:
344
+ case key_value_status_code::rate_limited_max_connections:
345
+ case key_value_status_code::rate_limited_network_egress:
346
+ case key_value_status_code::rate_limited_network_ingress:
347
+ last_error_message_ =
348
+ fmt::format("unable to bootstrap MCBP session (bucket={}, opcode={}, status={}), "
349
+ "the user has reached rate limit",
350
+ session_->bucket_name_.value_or(""),
351
+ protocol::client_opcode(msg.header.opcode),
352
+ status);
353
+ CB_LOG_DEBUG("{} {}", session_->log_prefix_, last_error_message_);
354
+ return complete(errc::common::rate_limited);
355
+
356
+ case key_value_status_code::scope_size_limit_exceeded:
357
+ last_error_message_ =
358
+ fmt::format("unable to bootstrap MCBP session (bucket={}, opcode={}, status={}), "
359
+ "the user has reached quota limit",
360
+ session_->bucket_name_.value_or(""),
361
+ protocol::client_opcode(msg.header.opcode),
362
+ status);
363
+ CB_LOG_DEBUG("{} {}", session_->log_prefix_, last_error_message_);
364
+ return complete(errc::common::quota_limited);
365
+
366
+ default:
367
+ break;
368
+ }
369
+ switch (auto opcode = static_cast<protocol::client_opcode>(msg.header.opcode)) {
370
+ case protocol::client_opcode::hello: {
371
+ protocol::client_response<protocol::hello_response_body> resp(std::move(msg));
372
+ if (resp.status() == key_value_status_code::success) {
373
+ session_->supported_features_ = resp.body().supported_features();
374
+ CB_LOG_DEBUG("{} supported_features=[{}]",
375
+ session_->log_prefix_,
376
+ utils::join_strings_fmt(session_->supported_features_, ", "));
377
+ if (session_->origin_.credentials().uses_certificate()) {
378
+ CB_LOG_DEBUG("{} skip SASL authentication, because TLS certificate was specified",
379
+ session_->log_prefix_);
380
+ return auth_success();
932
381
  }
933
- self->origin_.restart();
934
- self->initiate_bootstrap();
935
- });
936
- return;
937
- }
938
- std::tie(bootstrap_hostname_, bootstrap_port_) = origin_.next_address();
939
- bootstrap_port_number_ = gsl::narrow_cast<std::uint16_t>(std::stoul(bootstrap_port_, nullptr, 10));
940
- bootstrap_address_ = fmt::format("{}:{}", bootstrap_hostname_, bootstrap_port_);
941
- log_prefix_ =
942
- fmt::format("[{}/{}/{}/{}] <{}>", client_id_, id_, stream_->log_prefix(), bucket_name_.value_or("-"), bootstrap_address_);
943
- CB_LOG_DEBUG("{} attempt to establish MCBP connection", log_prefix_);
944
-
945
- async_resolve(origin_.options().use_ip_protocol,
946
- resolver_,
947
- bootstrap_hostname_,
948
- bootstrap_port_,
949
- std::bind(&mcbp_session_impl::on_resolve, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
382
+ } else {
383
+ last_error_message_ =
384
+ fmt::format("unexpected message status during bootstrap: {} (opaque={})",
385
+ resp.error_message(),
386
+ resp.opaque());
387
+ CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
388
+ return complete(errc::network::handshake_failure);
389
+ }
390
+ } break;
391
+ case protocol::client_opcode::sasl_list_mechs: {
392
+ protocol::client_response<protocol::sasl_list_mechs_response_body> resp(
393
+ std::move(msg));
394
+ if (resp.status() != key_value_status_code::success) {
395
+ last_error_message_ =
396
+ fmt::format("unexpected message status during bootstrap: {} (opaque={})",
397
+ resp.error_message(),
398
+ resp.opaque());
399
+ CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
400
+ return complete(errc::common::authentication_failure);
401
+ }
402
+ } break;
403
+ case protocol::client_opcode::sasl_auth: {
404
+ protocol::client_response<protocol::sasl_auth_response_body> resp(std::move(msg));
405
+ if (resp.status() == key_value_status_code::success) {
406
+ return auth_success();
407
+ }
408
+ if (resp.status() == key_value_status_code::auth_continue) {
409
+ auto [sasl_code, sasl_payload] = sasl_.step(resp.body().value());
410
+ if (sasl_code == sasl::error::OK) {
411
+ return auth_success();
412
+ }
413
+ if (sasl_code == sasl::error::CONTINUE) {
414
+ protocol::client_request<protocol::sasl_step_request_body> req;
415
+ req.opaque(session_->next_opaque());
416
+ req.body().mechanism(sasl_.get_name());
417
+ req.body().sasl_data(sasl_payload);
418
+ session_->write_and_flush(req.data());
419
+ } else {
420
+ last_error_message_ = fmt::format(
421
+ "unable to authenticate: (sasl_code={}, opaque={})", sasl_code, resp.opaque());
422
+ CB_LOG_ERROR("{} {}", session_->log_prefix_, last_error_message_);
423
+ return complete(errc::common::authentication_failure);
424
+ }
425
+ } else {
426
+ last_error_message_ =
427
+ fmt::format("{} unexpected message status during bootstrap: {} (opaque={})",
428
+ session_->log_prefix_,
429
+ resp.error_message(),
430
+ resp.opaque());
431
+ CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
432
+ return complete(errc::common::authentication_failure);
433
+ }
434
+ } break;
435
+ case protocol::client_opcode::sasl_step: {
436
+ protocol::client_response<protocol::sasl_step_response_body> resp(std::move(msg));
437
+ if (resp.status() == key_value_status_code::success) {
438
+ return auth_success();
439
+ }
440
+ last_error_message_ =
441
+ fmt::format("unable to authenticate (opcode={}, status={}, opaque={})",
442
+ opcode,
443
+ resp.status(),
444
+ resp.opaque());
445
+ CB_LOG_ERROR("{} {}", session_->log_prefix_, last_error_message_);
446
+ return complete(errc::common::authentication_failure);
447
+ }
448
+ case protocol::client_opcode::get_error_map: {
449
+ protocol::client_response<protocol::get_error_map_response_body> resp(std::move(msg));
450
+ if (resp.status() == key_value_status_code::success) {
451
+ session_->error_map_.emplace(resp.body().errmap());
452
+ } else {
453
+ last_error_message_ =
454
+ fmt::format("unexpected message status during bootstrap: {} (opaque={}, {:n})",
455
+ resp.error_message(),
456
+ resp.opaque(),
457
+ spdlog::to_hex(resp.header()));
458
+ CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
459
+ return complete(errc::network::protocol_error);
460
+ }
461
+ } break;
462
+ case protocol::client_opcode::select_bucket: {
463
+ protocol::client_response<protocol::select_bucket_response_body> resp(std::move(msg));
464
+ if (resp.status() == key_value_status_code::success) {
465
+ CB_LOG_DEBUG("{} selected bucket: {}",
466
+ session_->log_prefix_,
467
+ session_->bucket_name_.value_or(""));
468
+ session_->bucket_selected_ = true;
469
+ } else if (resp.status() == key_value_status_code::not_found) {
470
+ last_error_message_ =
471
+ fmt::format("kv_engine node does not have configuration propagated yet "
472
+ "(opcode={}, status={}, opaque={})",
473
+ opcode,
474
+ resp.status(),
475
+ resp.opaque());
476
+ CB_LOG_DEBUG("{} {}", session_->log_prefix_, last_error_message_);
477
+ return complete(errc::network::configuration_not_available);
478
+ } else if (resp.status() == key_value_status_code::no_access) {
479
+ last_error_message_ =
480
+ fmt::format("unable to select bucket: {}, probably the bucket does not exist",
481
+ session_->bucket_name_.value_or(""));
482
+ CB_LOG_DEBUG("{} {}", session_->log_prefix_, last_error_message_);
483
+ session_->bucket_selected_ = false;
484
+ return complete(errc::common::bucket_not_found);
485
+ } else {
486
+ last_error_message_ =
487
+ fmt::format("unexpected message status during bootstrap: {} (opaque={}, {:n})",
488
+ resp.error_message(),
489
+ resp.opaque(),
490
+ spdlog::to_hex(resp.header()));
491
+ CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
492
+ return complete(errc::common::bucket_not_found);
493
+ }
494
+ } break;
495
+ case protocol::client_opcode::get_cluster_config: {
496
+ protocol::cmd_info info{ session_->connection_endpoints_.remote_address,
497
+ session_->connection_endpoints_.remote.port() };
498
+ protocol::client_response<protocol::get_cluster_config_response_body> resp(
499
+ std::move(msg), info);
500
+ if (session_->origin_.options().dump_configuration &&
501
+ resp.body().config_text().has_value()) {
502
+ CB_LOG_TRACE("{} configuration from get_cluster_config request (bootstrap, "
503
+ "size={}, endpoint=\"{}:{}\"), {}",
504
+ session_->log_prefix_,
505
+ resp.body().config_text().value().size(),
506
+ info.endpoint_address,
507
+ info.endpoint_port,
508
+ resp.body().config_text().value());
509
+ }
510
+ if (resp.status() == key_value_status_code::success) {
511
+ // MB-60405 fixes this for 7.6.2, but for earlier versions we need to protect
512
+ // against using a config that has an empty vbucket map. Ideally we don't timeout
513
+ // if we retry here, but a timeout would be more acceptable than a crash and if we
514
+ // do timeout, we have a clear indication of the problem (i.e. it is a server bug
515
+ // and we cannot use a config w/ an empty vbucket map).
516
+ if (resp.body().config().vbmap && resp.body().config().vbmap->size() == 0) {
517
+ CB_LOG_WARNING("{} received a configuration with an empty vbucket map, retrying",
518
+ session_->log_prefix_);
519
+ return complete(errc::network::configuration_not_available);
520
+ }
521
+ session_->update_configuration(resp.body().config());
522
+ complete({});
523
+ } else if (resp.status() == key_value_status_code::not_found) {
524
+ last_error_message_ =
525
+ fmt::format("kv_engine node does not have configuration propagated yet "
526
+ "(opcode={}, status={}, opaque={})",
527
+ opcode,
528
+ resp.status(),
529
+ resp.opaque());
530
+ CB_LOG_DEBUG("{} {}", session_->log_prefix_, last_error_message_);
531
+ return complete(errc::network::configuration_not_available);
532
+ } else if (resp.status() == key_value_status_code::no_bucket &&
533
+ !session_->bucket_name_) {
534
+ // bucket-less session, but the server wants bucket
535
+ session_->supports_gcccp_ = false;
536
+ CB_LOG_WARNING("{} this server does not support GCCCP, open bucket before making "
537
+ "any cluster-level command",
538
+ session_->log_prefix_);
539
+ session_->update_configuration(
540
+ topology::make_blank_configuration(session_->connection_endpoints_.remote_address,
541
+ session_->connection_endpoints_.remote.port(),
542
+ 0));
543
+ complete({});
544
+ } else {
545
+ last_error_message_ =
546
+ fmt::format("unexpected message status during bootstrap: {} (opaque={}, {:n})",
547
+ resp.error_message(),
548
+ resp.opaque(),
549
+ spdlog::to_hex(resp.header()));
550
+ CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
551
+ return complete(errc::network::protocol_error);
552
+ }
553
+ } break;
554
+ default:
555
+ last_error_message_ = fmt::format("unexpected message during bootstrap: {}", opcode);
556
+ CB_LOG_WARNING("{} {}", session_->log_prefix_, last_error_message_);
557
+ return complete(errc::network::protocol_error);
558
+ }
559
+ break;
560
+ case protocol::magic::server_request:
561
+ Expects(protocol::is_valid_server_request_opcode(msg.header.opcode));
562
+ switch (static_cast<protocol::server_opcode>(msg.header.opcode)) {
563
+ case protocol::server_opcode::cluster_map_change_notification: {
564
+ protocol::cmd_info info{ session_->bootstrap_hostname_,
565
+ session_->bootstrap_port_number_ };
566
+ protocol::server_request<protocol::cluster_map_change_notification_request_body> req(
567
+ std::move(msg), info);
568
+ if (session_->origin_.options().dump_configuration &&
569
+ req.body().config_text().has_value()) {
570
+ CB_LOG_TRACE("{} configuration from cluster_map_change_notification request "
571
+ "(size={}, endpoint=\"{}:{}\"), {}",
572
+ session_->log_prefix_,
573
+ req.body().config_text().value().size(),
574
+ info.endpoint_address,
575
+ info.endpoint_port,
576
+ req.body().config_text().value());
577
+ }
578
+ std::optional<topology::configuration> config = req.body().config();
579
+ if (session_ && config.has_value()) {
580
+ if ((!config->bucket.has_value() && req.body().bucket().empty()) ||
581
+ (session_->bucket_name_.has_value() && !req.body().bucket().empty() &&
582
+ session_->bucket_name_.value() == req.body().bucket())) {
583
+ session_->update_configuration(std::move(config.value()));
584
+ }
585
+ }
586
+ } break;
587
+ default:
588
+ CB_LOG_WARNING("{} unexpected server request: opcode={:x}, opaque={}{:a}{:a}",
589
+ session_->log_prefix_,
590
+ msg.header.opcode,
591
+ utils::byte_swap(msg.header.opaque),
592
+ spdlog::to_hex(msg.header_data()),
593
+ spdlog::to_hex(msg.body));
594
+ }
595
+ break;
596
+ case protocol::magic::client_request:
597
+ case protocol::magic::alt_client_request:
598
+ case protocol::magic::server_response:
599
+ CB_LOG_WARNING("{} unexpected magic: {} (opcode={:x}, opaque={}){:a}{:a}",
600
+ session_->log_prefix_,
601
+ magic,
602
+ msg.header.opcode,
603
+ utils::byte_swap(msg.header.opaque),
604
+ spdlog::to_hex(msg.header_data()),
605
+ spdlog::to_hex(msg.body));
606
+ break;
607
+ }
950
608
  }
609
+ };
610
+
611
+ class message_handler : public std::enable_shared_from_this<message_handler>
612
+ {
613
+ private:
614
+ std::shared_ptr<mcbp_session_impl> session_;
615
+ std::atomic_bool stopped_{ false };
951
616
 
952
- [[nodiscard]] const std::string& id() const
617
+ public:
618
+ explicit message_handler(std::shared_ptr<mcbp_session_impl> session)
619
+ : session_(std::move(session))
953
620
  {
954
- return id_;
955
621
  }
956
622
 
957
- [[nodiscard]] bool is_stopped() const
623
+ ~message_handler()
958
624
  {
959
- return stopped_;
625
+ stop();
960
626
  }
961
627
 
962
- [[nodiscard]] bool is_bootstrapped() const
628
+ void start()
963
629
  {
964
- return bootstrapped_;
965
630
  }
966
631
 
967
- void on_stop(utils::movable_function<void()> handler)
632
+ void stop()
968
633
  {
969
- on_stop_handler_ = std::move(handler);
970
634
  }
971
635
 
972
- void stop(retry_reason reason)
636
+ void handle(mcbp_message&& msg)
973
637
  {
974
- if (stopped_) {
975
- return;
976
- }
977
- state_ = diag::endpoint_state::disconnecting;
978
- CB_LOG_DEBUG("{} stop MCBP connection, reason={}", log_prefix_, reason);
979
- stopped_ = true;
980
- bootstrap_deadline_.cancel();
981
- connection_deadline_.cancel();
982
- retry_backoff_.cancel();
983
- ping_deadline_.cancel();
984
- resolver_.cancel();
985
- stream_->close([](std::error_code) {});
986
- if (auto h = std::move(bootstrap_handler_); h) {
987
- h->stop();
988
- }
989
- if (auto h = std::move(handler_); h) {
990
- h->stop();
991
- }
992
- std::error_code ec = errc::common::request_canceled;
993
- if (!bootstrapped_) {
994
- if (auto h = std::move(bootstrap_callback_); h) {
995
- h(ec, {});
996
- }
997
- }
998
- {
999
- std::scoped_lock lock(command_handlers_mutex_);
1000
- for (auto& [opaque, handler] : command_handlers_) {
1001
- if (handler) {
1002
- CB_LOG_DEBUG("{} MCBP cancel operation during session close, opaque={}, ec={}", log_prefix_, opaque, ec.message());
1003
- auto fun = std::move(handler);
1004
- fun(ec, reason, {}, {});
638
+ if (stopped_ || !session_) {
639
+ return;
640
+ }
641
+ Expects(protocol::is_valid_magic(msg.header.magic));
642
+ switch (auto magic = static_cast<protocol::magic>(msg.header.magic)) {
643
+ case protocol::magic::client_response:
644
+ case protocol::magic::alt_client_response:
645
+ Expects(protocol::is_valid_client_opcode(msg.header.opcode));
646
+ switch (auto opcode = static_cast<protocol::client_opcode>(msg.header.opcode)) {
647
+ case protocol::client_opcode::get_cluster_config: {
648
+ protocol::cmd_info info{ session_->bootstrap_hostname_,
649
+ session_->bootstrap_port_number_ };
650
+ protocol::client_response<protocol::get_cluster_config_response_body> resp(
651
+ std::move(msg), info);
652
+ if (session_->origin_.options().dump_configuration &&
653
+ resp.body().config_text().has_value()) {
654
+ CB_LOG_TRACE("{} configuration from get_cluster_config response (size={}, "
655
+ "endpoint=\"{}:{}\"), {}",
656
+ session_->log_prefix_,
657
+ resp.body().config_text().value().size(),
658
+ info.endpoint_address,
659
+ info.endpoint_port,
660
+ resp.body().config_text().value());
661
+ }
662
+ if (resp.status() == key_value_status_code::success) {
663
+ if (session_) {
664
+ session_->update_configuration(resp.body().config());
1005
665
  }
1006
- }
1007
- command_handlers_.clear();
1008
- }
1009
- {
1010
- std::scoped_lock lock(operations_mutex_);
1011
- auto operations = std::move(operations_);
1012
- for (auto& [opaque, operation] : operations) {
1013
- auto& [request, handler] = operation;
1014
- if (handler) {
1015
- CB_LOG_DEBUG("{} MCBP cancel operation during session close, opaque={}, ec={}", log_prefix_, opaque, ec.message());
1016
- handler->handle_response(std::move(request), {}, reason, {}, {});
666
+ } else {
667
+ CB_LOG_WARNING("{} unexpected message status: {} (opaque={})",
668
+ session_->log_prefix_,
669
+ resp.error_message(),
670
+ resp.opaque());
671
+ }
672
+ } break;
673
+ case protocol::client_opcode::noop:
674
+ case protocol::client_opcode::get_collections_manifest:
675
+ case protocol::client_opcode::get_collection_id:
676
+ case protocol::client_opcode::get:
677
+ case protocol::client_opcode::get_and_lock:
678
+ case protocol::client_opcode::get_and_touch:
679
+ case protocol::client_opcode::get_meta:
680
+ case protocol::client_opcode::get_replica:
681
+ case protocol::client_opcode::touch:
682
+ case protocol::client_opcode::insert:
683
+ case protocol::client_opcode::replace:
684
+ case protocol::client_opcode::upsert:
685
+ case protocol::client_opcode::append:
686
+ case protocol::client_opcode::prepend:
687
+ case protocol::client_opcode::remove:
688
+ case protocol::client_opcode::observe_seqno:
689
+ case protocol::client_opcode::unlock:
690
+ case protocol::client_opcode::increment:
691
+ case protocol::client_opcode::range_scan_create:
692
+ case protocol::client_opcode::range_scan_continue:
693
+ case protocol::client_opcode::range_scan_cancel:
694
+ case protocol::client_opcode::decrement:
695
+ case protocol::client_opcode::subdoc_multi_lookup:
696
+ case protocol::client_opcode::subdoc_multi_mutation: {
697
+ std::uint16_t status = utils::byte_swap(msg.header.specific);
698
+ if (status == static_cast<std::uint16_t>(key_value_status_code::not_my_vbucket)) {
699
+ session_->handle_not_my_vbucket(msg);
700
+ }
701
+
702
+ std::uint32_t opaque = utils::byte_swap(msg.header.opaque);
703
+ if (session_->handle_request(opcode, status, opaque, std::move(msg))) {
704
+ CB_LOG_TRACE("{} MCBP invoked operation handler: opcode={}, opaque={}, status={}",
705
+ session_->log_prefix_,
706
+ opcode,
707
+ opaque,
708
+ protocol::status_to_string(status));
709
+ } else {
710
+ CB_LOG_DEBUG("{} unexpected orphan response: opcode={}, opaque={}, status={}",
711
+ session_->log_prefix_,
712
+ opcode,
713
+ opaque,
714
+ protocol::status_to_string(status));
715
+ }
716
+ } break;
717
+ default:
718
+ CB_LOG_WARNING("{} unexpected client response: opcode={}, opaque={}{:a}{:a})",
719
+ session_->log_prefix_,
720
+ opcode,
721
+ msg.header.opaque,
722
+ spdlog::to_hex(msg.header_data()),
723
+ spdlog::to_hex(msg.body));
724
+ }
725
+ break;
726
+ case protocol::magic::server_request:
727
+ Expects(protocol::is_valid_server_request_opcode(msg.header.opcode));
728
+ switch (static_cast<protocol::server_opcode>(msg.header.opcode)) {
729
+ case protocol::server_opcode::cluster_map_change_notification: {
730
+ protocol::cmd_info info{ session_->bootstrap_hostname_,
731
+ session_->bootstrap_port_number_ };
732
+ protocol::server_request<protocol::cluster_map_change_notification_request_body> req(
733
+ std::move(msg), info);
734
+ if (session_->origin_.options().dump_configuration &&
735
+ req.body().config_text().has_value()) {
736
+ CB_LOG_TRACE("{} configuration from cluster_map_change_notification request "
737
+ "(size={}, endpoint=\"{}:{}\"), {}",
738
+ session_->log_prefix_,
739
+ req.body().config_text().value().size(),
740
+ info.endpoint_address,
741
+ info.endpoint_port,
742
+ req.body().config_text().value());
743
+ }
744
+ std::optional<topology::configuration> config = req.body().config();
745
+ if (session_ && config.has_value()) {
746
+ if ((!config->bucket.has_value() && req.body().bucket().empty()) ||
747
+ (session_->bucket_name_.has_value() && !req.body().bucket().empty() &&
748
+ session_->bucket_name_.value() == req.body().bucket())) {
749
+ session_->update_configuration(std::move(config.value()));
1017
750
  }
1018
- }
1019
- operations_.clear();
1020
- }
1021
- config_listeners_.clear();
1022
- state_ = diag::endpoint_state::disconnected;
1023
- if (auto on_stop = std::move(on_stop_handler_); on_stop) {
1024
- on_stop();
1025
- }
751
+ }
752
+ } break;
753
+ default:
754
+ CB_LOG_WARNING("{} unexpected server request: opcode={:x}, opaque={}{:a}{:a}",
755
+ session_->log_prefix_,
756
+ msg.header.opcode,
757
+ msg.header.opaque,
758
+ spdlog::to_hex(msg.header_data()),
759
+ spdlog::to_hex(msg.body));
760
+ }
761
+ break;
762
+ case protocol::magic::client_request:
763
+ case protocol::magic::alt_client_request:
764
+ case protocol::magic::server_response:
765
+ CB_LOG_WARNING("{} unexpected magic: {} (opcode={:x}, opaque={}){:a}{:a}",
766
+ session_->log_prefix_,
767
+ magic,
768
+ msg.header.opcode,
769
+ msg.header.opaque,
770
+ spdlog::to_hex(msg.header_data()),
771
+ spdlog::to_hex(msg.body));
772
+ break;
773
+ }
1026
774
  }
1027
-
1028
- void write(std::vector<std::byte>&& buf)
1029
- {
1030
- if (stopped_) {
1031
- return;
1032
- }
1033
- CB_LOG_TRACE("{} MCBP send {}", log_prefix_, mcbp_header_view(buf));
1034
- std::scoped_lock lock(output_buffer_mutex_);
1035
- output_buffer_.emplace_back(std::move(buf));
775
+ };
776
+
777
+ public:
778
+ mcbp_session_impl() = delete;
779
+ mcbp_session_impl(std::string_view client_id,
780
+ asio::io_context& ctx,
781
+ couchbase::core::origin origin,
782
+ std::shared_ptr<impl::bootstrap_state_listener> state_listener,
783
+ std::optional<std::string> bucket_name = {},
784
+ std::vector<protocol::hello_feature> known_features = {})
785
+ : client_id_(client_id)
786
+ , ctx_(ctx)
787
+ , resolver_(ctx_)
788
+ , stream_(std::make_unique<plain_stream_impl>(ctx_))
789
+ , bootstrap_deadline_(ctx_)
790
+ , connection_deadline_(ctx_)
791
+ , retry_backoff_(ctx_)
792
+ , ping_deadline_(ctx_)
793
+ , origin_{ std::move(origin) }
794
+ , bucket_name_{ std::move(bucket_name) }
795
+ , supported_features_{ std::move(known_features) }
796
+ , is_tls_{ false }
797
+ , state_listener_{ std::move(state_listener) }
798
+ , codec_{ { supported_features_.begin(), supported_features_.end() } }
799
+ {
800
+ log_prefix_ = fmt::format(
801
+ "[{}/{}/{}/{}]", client_id_, id_, stream_->log_prefix(), bucket_name_.value_or("-"));
802
+ }
803
+
804
+ mcbp_session_impl(std::string_view client_id,
805
+ asio::io_context& ctx,
806
+ asio::ssl::context& tls,
807
+ couchbase::core::origin origin,
808
+ std::shared_ptr<impl::bootstrap_state_listener> state_listener,
809
+ std::optional<std::string> bucket_name = {},
810
+ std::vector<protocol::hello_feature> known_features = {})
811
+ : client_id_(client_id)
812
+ , ctx_(ctx)
813
+ , resolver_(ctx_)
814
+ , stream_(std::make_unique<tls_stream_impl>(ctx_, tls))
815
+ , bootstrap_deadline_(ctx_)
816
+ , connection_deadline_(ctx_)
817
+ , retry_backoff_(ctx_)
818
+ , ping_deadline_(ctx_)
819
+ , origin_(std::move(origin))
820
+ , bucket_name_(std::move(bucket_name))
821
+ , supported_features_(std::move(known_features))
822
+ , is_tls_{ true }
823
+ , state_listener_{ std::move(state_listener) }
824
+ , codec_{ { supported_features_.begin(), supported_features_.end() } }
825
+ {
826
+ log_prefix_ = fmt::format(
827
+ "[{}/{}/{}/{}]", client_id_, id_, stream_->log_prefix(), bucket_name_.value_or("-"));
828
+ }
829
+
830
+ ~mcbp_session_impl()
831
+ {
832
+ CB_LOG_DEBUG("{} destroy MCBP connection", log_prefix_);
833
+ stop(retry_reason::do_not_retry);
834
+ }
835
+
836
+ [[nodiscard]] auto log_prefix() const -> const std::string&
837
+ {
838
+ return log_prefix_;
839
+ }
840
+
841
+ auto remote_address() const -> std::string
842
+ {
843
+ return connection_endpoints_.remote_address_with_port;
844
+ }
845
+
846
+ auto local_address() const -> std::string
847
+ {
848
+ return connection_endpoints_.local_address_with_port;
849
+ }
850
+
851
+ [[nodiscard]] auto diag_info() const -> diag::endpoint_diag_info
852
+ {
853
+ return { service_type::key_value,
854
+ id_,
855
+ last_active_.time_since_epoch().count() == 0
856
+ ? std::nullopt
857
+ : std::make_optional(std::chrono::duration_cast<std::chrono::microseconds>(
858
+ std::chrono::steady_clock::now() - last_active_)),
859
+ remote_address(),
860
+ local_address(),
861
+ state_,
862
+ bucket_name_ };
863
+ }
864
+
865
+ void ping(std::shared_ptr<diag::ping_reporter> handler,
866
+ std::optional<std::chrono::milliseconds> timeout)
867
+ {
868
+ if (!bootstrapped_) {
869
+ handler->report({
870
+ service_type::key_value,
871
+ id_,
872
+ std::chrono::microseconds(0),
873
+ remote_address(),
874
+ local_address(),
875
+ diag::ping_state::error,
876
+ bucket_name_,
877
+ last_bootstrap_error_message_.has_value() ? last_bootstrap_error_message_.value()
878
+ : "Bootstrap incomplete, cannot perform ping.",
879
+ });
880
+ return;
1036
881
  }
1037
-
1038
- void flush()
1039
- {
1040
- if (stopped_) {
1041
- return;
1042
- }
1043
- asio::post(asio::bind_executor(ctx_, [self = shared_from_this()]() { self->do_write(); }));
882
+ protocol::client_request<protocol::mcbp_noop_request_body> req;
883
+ req.opaque(next_opaque());
884
+ write_and_subscribe(
885
+ req.opaque(),
886
+ req.data(false),
887
+ [start = std::chrono::steady_clock::now(), self = shared_from_this(), handler](
888
+ std::error_code ec,
889
+ retry_reason reason,
890
+ io::mcbp_message&& /* msg */,
891
+ std::optional<key_value_error_map_info> /* error_info */) {
892
+ diag::ping_state state = diag::ping_state::ok;
893
+ std::optional<std::string> error{};
894
+ if (ec) {
895
+ if (ec == errc::common::unambiguous_timeout || ec == errc::common::ambiguous_timeout) {
896
+ state = diag::ping_state::timeout;
897
+ } else {
898
+ state = diag::ping_state::error;
899
+ }
900
+ error.emplace(
901
+ fmt::format("code={}, message={}, reason={}", ec.value(), ec.message(), reason));
902
+ }
903
+ handler->report({
904
+ service_type::key_value,
905
+ self->id_,
906
+ std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() -
907
+ start),
908
+ self->remote_address(),
909
+ self->local_address(),
910
+ state,
911
+ self->bucket_name_,
912
+ error,
913
+ });
914
+ });
915
+ ping_deadline_.expires_after(timeout.value_or(origin_.options().key_value_timeout));
916
+ ping_deadline_.async_wait(
917
+ [self = this->shared_from_this(), opaque = req.opaque()](std::error_code ec) {
918
+ if (ec == asio::error::operation_aborted) {
919
+ return;
920
+ }
921
+ static_cast<void>(
922
+ self->cancel(opaque, errc::common::unambiguous_timeout, retry_reason::do_not_retry));
923
+ });
924
+ }
925
+
926
+ [[nodiscard]] auto context() const -> mcbp_context
927
+ {
928
+ return { config_, supported_features_ };
929
+ }
930
+
931
+ void bootstrap(utils::movable_function<void(std::error_code, topology::configuration)>&& callback,
932
+ bool retry_on_bucket_not_found = false)
933
+ {
934
+ retry_bootstrap_on_bucket_not_found_ = retry_on_bucket_not_found;
935
+ bootstrap_callback_ = std::move(callback);
936
+ bootstrap_deadline_.expires_after(origin_.options().bootstrap_timeout);
937
+ bootstrap_deadline_.async_wait([self = shared_from_this()](std::error_code ec) {
938
+ if (ec == asio::error::operation_aborted || self->stopped_) {
939
+ return;
940
+ }
941
+ if (!ec) {
942
+ ec = errc::common::unambiguous_timeout;
943
+ }
944
+ if (self->state_listener_) {
945
+ self->state_listener_->report_bootstrap_error(
946
+ fmt::format("{}:{}", self->bootstrap_hostname_, self->bootstrap_port_), ec);
947
+ }
948
+ CB_LOG_WARNING("{} unable to bootstrap in time", self->log_prefix_);
949
+ if (auto h = std::move(self->bootstrap_callback_); h) {
950
+ h(ec, {});
951
+ }
952
+ self->stop(retry_reason::do_not_retry);
953
+ });
954
+ initiate_bootstrap();
955
+ }
956
+
957
+ void initiate_bootstrap()
958
+ {
959
+ if (stopped_) {
960
+ return;
1044
961
  }
1045
-
1046
- void write_and_flush(std::vector<std::byte>&& buf)
1047
- {
1048
- if (stopped_) {
1049
- return;
1050
- }
1051
- write(std::move(buf));
1052
- flush();
962
+ bootstrapped_ = false;
963
+ if (bootstrap_handler_) {
964
+ last_bootstrap_error_message_ = std::move(bootstrap_handler_)->last_error_message();
1053
965
  }
1054
-
1055
- void remove_request(std::shared_ptr<mcbp::queue_request> request) override
1056
- {
1057
- std::scoped_lock lock(operations_mutex_);
1058
- if (auto iter = operations_.find(request->opaque_); iter != operations_.end()) {
1059
- operations_.erase(iter);
1060
- }
966
+ bootstrap_handler_ = nullptr;
967
+ state_ = diag::endpoint_state::connecting;
968
+ if (stream_->is_open()) {
969
+ std::string old_id = stream_->id();
970
+ stream_->reopen();
971
+ CB_LOG_TRACE(R"({} reopen socket connection "{}" -> "{}", host="{}", port={})",
972
+ log_prefix_,
973
+ old_id,
974
+ stream_->id(),
975
+ bootstrap_hostname_,
976
+ bootstrap_port_);
1061
977
  }
1062
-
1063
- void enqueue_request(std::uint32_t opaque, std::shared_ptr<mcbp::queue_request> request, std::shared_ptr<response_handler> handler)
1064
- {
1065
- std::scoped_lock lock(operations_mutex_);
1066
- request->waiting_in_ = this;
1067
- operations_.try_emplace(opaque, std::move(request), std::move(handler));
978
+ if (origin_.exhausted()) {
979
+ auto backoff = std::chrono::milliseconds(500);
980
+ CB_LOG_DEBUG("{} reached the end of list of bootstrap nodes, waiting for {}ms before restart",
981
+ log_prefix_,
982
+ backoff.count());
983
+ retry_backoff_.expires_after(backoff);
984
+ retry_backoff_.async_wait([self = shared_from_this()](std::error_code ec) mutable {
985
+ if (ec == asio::error::operation_aborted || self->stopped_) {
986
+ return;
987
+ }
988
+ self->origin_.restart();
989
+ self->initiate_bootstrap();
990
+ });
991
+ return;
1068
992
  }
1069
-
1070
- auto handle_request(protocol::client_opcode opcode, std::uint16_t status, std::uint32_t opaque, mcbp_message&& msg) -> bool
1071
- {
1072
- // handle request old style
1073
- command_handler fun{};
1074
- {
1075
- std::scoped_lock lock(command_handlers_mutex_);
1076
- if (auto handler = command_handlers_.find(opaque); handler != command_handlers_.end() && handler->second) {
1077
- fun = std::move(handler->second);
1078
- command_handlers_.erase(handler);
1079
- }
1080
- }
1081
-
1082
- auto reason = status == static_cast<std::uint16_t>(key_value_status_code::not_my_vbucket) ? retry_reason::key_value_not_my_vbucket
1083
- : retry_reason::do_not_retry;
1084
- if (fun) {
1085
- fun(protocol::map_status_code(opcode, status), reason, std::move(msg), decode_error_code(status));
1086
- return true;
1087
- }
1088
-
1089
- // handle request new style
1090
- std::shared_ptr<mcbp::queue_request> request{};
1091
- std::shared_ptr<response_handler> handler{};
1092
- std::scoped_lock lock(operations_mutex_);
1093
- {
1094
- if (auto pair = operations_.find(opaque); pair != operations_.end() && pair->second.first) {
1095
- request = pair->second.first;
1096
- handler = pair->second.second;
1097
- if (!request->persistent_) {
1098
- operations_.erase(pair);
1099
- }
1100
- }
1101
- }
1102
- if (request) {
1103
- handler->handle_response(
1104
- std::move(request), protocol::map_status_code(opcode, status), reason, std::move(msg), decode_error_code(status));
1105
- return true;
1106
- }
1107
- return false;
993
+ std::tie(bootstrap_hostname_, bootstrap_port_) = origin_.next_address();
994
+ bootstrap_port_number_ =
995
+ gsl::narrow_cast<std::uint16_t>(std::stoul(bootstrap_port_, nullptr, 10));
996
+ bootstrap_address_ = fmt::format("{}:{}", bootstrap_hostname_, bootstrap_port_);
997
+ log_prefix_ = fmt::format("[{}/{}/{}/{}] <{}>",
998
+ client_id_,
999
+ id_,
1000
+ stream_->log_prefix(),
1001
+ bucket_name_.value_or("-"),
1002
+ bootstrap_address_);
1003
+ CB_LOG_DEBUG("{} attempt to establish MCBP connection", log_prefix_);
1004
+
1005
+ async_resolve(origin_.options().use_ip_protocol,
1006
+ resolver_,
1007
+ bootstrap_hostname_,
1008
+ bootstrap_port_,
1009
+ std::bind(&mcbp_session_impl::on_resolve,
1010
+ shared_from_this(),
1011
+ std::placeholders::_1,
1012
+ std::placeholders::_2));
1013
+ }
1014
+
1015
+ [[nodiscard]] auto id() const -> const std::string&
1016
+ {
1017
+ return id_;
1018
+ }
1019
+
1020
+ [[nodiscard]] auto is_stopped() const -> bool
1021
+ {
1022
+ return stopped_;
1023
+ }
1024
+
1025
+ [[nodiscard]] auto is_bootstrapped() const -> bool
1026
+ {
1027
+ return bootstrapped_;
1028
+ }
1029
+
1030
+ void on_stop(utils::movable_function<void()> handler)
1031
+ {
1032
+ on_stop_handler_ = std::move(handler);
1033
+ }
1034
+
1035
+ void stop(retry_reason reason)
1036
+ {
1037
+ if (stopped_) {
1038
+ return;
1108
1039
  }
1109
-
1110
- void write_and_subscribe(std::shared_ptr<mcbp::queue_request> request, std::shared_ptr<response_handler> handler)
1111
- {
1112
- auto opaque = request->opaque_;
1113
- auto data = codec_.encode_packet(*request);
1114
- if (!data) {
1115
- CB_LOG_DEBUG("unable to encode packet. opaque={}, ec={}", opaque, data.error().message());
1116
- request->try_callback({}, data.error());
1117
- return;
1118
- }
1119
-
1120
- if (stopped_) {
1121
- CB_LOG_WARNING("cancel operation while trying to write to closed mcbp session, opaque={}", opaque);
1122
- handler->handle_response(request, errc::common::request_canceled, retry_reason::socket_closed_while_in_flight, {}, {});
1123
- return;
1124
- }
1125
- enqueue_request(opaque, std::move(request), std::move(handler));
1126
- if (bootstrapped_ && stream_->is_open()) {
1127
- write_and_flush(std::move(data.value()));
1128
- } else {
1129
- CB_LOG_DEBUG("{} the stream is not ready yet, put the message into pending buffer, opaque={}", log_prefix_, opaque);
1130
- std::scoped_lock lock(pending_buffer_mutex_);
1131
- if (bootstrapped_ && stream_->is_open()) {
1132
- write_and_flush(std::move(data.value()));
1133
- } else {
1134
- pending_buffer_.emplace_back(data.value());
1135
- }
1136
- }
1040
+ state_ = diag::endpoint_state::disconnecting;
1041
+ CB_LOG_DEBUG("{} stop MCBP connection, reason={}", log_prefix_, reason);
1042
+ stopped_ = true;
1043
+ bootstrap_deadline_.cancel();
1044
+ connection_deadline_.cancel();
1045
+ retry_backoff_.cancel();
1046
+ ping_deadline_.cancel();
1047
+ resolver_.cancel();
1048
+ stream_->close([](std::error_code) {
1049
+ });
1050
+ if (auto h = std::move(bootstrap_handler_); h) {
1051
+ h->stop();
1137
1052
  }
1138
-
1139
- void write_and_subscribe(std::uint32_t opaque, std::vector<std::byte>&& data, command_handler&& handler)
1140
- {
1141
- if (stopped_) {
1142
- CB_LOG_WARNING("{} MCBP cancel operation, while trying to write to closed session, opaque={}", log_prefix_, opaque);
1143
- handler(errc::common::request_canceled, retry_reason::socket_closed_while_in_flight, {}, {});
1144
- return;
1145
- }
1146
- {
1147
- std::scoped_lock lock(command_handlers_mutex_);
1148
- command_handlers_.try_emplace(opaque, std::move(handler));
1149
- }
1150
- if (bootstrapped_ && stream_->is_open()) {
1151
- write_and_flush(std::move(data));
1152
- } else {
1153
- CB_LOG_DEBUG("{} the stream is not ready yet, put the message into pending buffer, opaque={}", log_prefix_, opaque);
1154
- std::scoped_lock lock(pending_buffer_mutex_);
1155
- if (bootstrapped_ && stream_->is_open()) {
1156
- write_and_flush(std::move(data));
1157
- } else {
1158
- pending_buffer_.emplace_back(data);
1159
- }
1160
- }
1053
+ if (auto h = std::move(handler_); h) {
1054
+ h->stop();
1161
1055
  }
1162
-
1163
- [[nodiscard]] bool cancel(std::uint32_t opaque, std::error_code ec, retry_reason reason)
1164
- {
1165
- if (stopped_) {
1166
- return false;
1167
- }
1168
- command_handlers_mutex_.lock();
1169
- if (auto handler = command_handlers_.find(opaque); handler != command_handlers_.end()) {
1170
- CB_LOG_DEBUG("{} MCBP cancel operation, opaque={}, ec={} ({})", log_prefix_, opaque, ec.value(), ec.message());
1171
- if (handler->second) {
1172
- auto fun = std::move(handler->second);
1173
- command_handlers_.erase(handler);
1174
- command_handlers_mutex_.unlock();
1175
- fun(ec, reason, {}, {});
1176
- return true;
1177
- }
1178
- }
1179
- command_handlers_mutex_.unlock();
1180
- return false;
1056
+ std::error_code ec = errc::common::request_canceled;
1057
+ if (!bootstrapped_) {
1058
+ if (auto h = std::move(bootstrap_callback_); h) {
1059
+ h(ec, {});
1060
+ }
1181
1061
  }
1182
-
1183
- [[nodiscard]] bool supports_feature(protocol::hello_feature feature)
1184
1062
  {
1185
- return std::find(supported_features_.begin(), supported_features_.end(), feature) != supported_features_.end();
1063
+ std::scoped_lock lock(command_handlers_mutex_);
1064
+ for (auto& [opaque, handler] : command_handlers_) {
1065
+ if (handler) {
1066
+ CB_LOG_DEBUG("{} MCBP cancel operation during session close, opaque={}, ec={}",
1067
+ log_prefix_,
1068
+ opaque,
1069
+ ec.message());
1070
+ auto fun = std::move(handler);
1071
+ fun(ec, reason, {}, {});
1072
+ }
1073
+ }
1074
+ command_handlers_.clear();
1186
1075
  }
1187
-
1188
- [[nodiscard]] std::vector<protocol::hello_feature> supported_features() const
1189
1076
  {
1190
- return supported_features_;
1077
+ std::scoped_lock lock(operations_mutex_);
1078
+ auto operations = std::move(operations_);
1079
+ for (auto& [opaque, operation] : operations) {
1080
+ auto& [request, handler] = operation;
1081
+ if (handler) {
1082
+ CB_LOG_DEBUG("{} MCBP cancel operation during session close, opaque={}, ec={}",
1083
+ log_prefix_,
1084
+ opaque,
1085
+ ec.message());
1086
+ handler->handle_response(std::move(request), {}, reason, {}, {});
1087
+ }
1088
+ }
1089
+ operations_.clear();
1191
1090
  }
1192
-
1193
- [[nodiscard]] bool supports_gcccp() const
1194
- {
1195
- return supports_gcccp_;
1091
+ config_listeners_.clear();
1092
+ state_ = diag::endpoint_state::disconnected;
1093
+ if (auto on_stop = std::move(on_stop_handler_); on_stop) {
1094
+ on_stop();
1196
1095
  }
1096
+ }
1197
1097
 
1198
- std::optional<topology::configuration> config() const
1199
- {
1200
- return config_;
1098
+ void write(std::vector<std::byte>&& buf)
1099
+ {
1100
+ if (stopped_) {
1101
+ return;
1201
1102
  }
1202
-
1203
- [[nodiscard]] bool has_config() const
1204
- {
1205
- return configured_;
1103
+ CB_LOG_TRACE("{} MCBP send {}", log_prefix_, mcbp_header_view(buf));
1104
+ std::scoped_lock lock(output_buffer_mutex_);
1105
+ output_buffer_.emplace_back(std::move(buf));
1106
+ }
1107
+
1108
+ void flush()
1109
+ {
1110
+ if (stopped_) {
1111
+ return;
1206
1112
  }
1207
-
1208
- [[nodiscard]] topology::configuration config()
1209
- {
1210
- std::scoped_lock lock(config_mutex_);
1211
- return config_.value();
1113
+ asio::post(asio::bind_executor(ctx_, [self = shared_from_this()]() {
1114
+ self->do_write();
1115
+ }));
1116
+ }
1117
+
1118
+ void write_and_flush(std::vector<std::byte>&& buf)
1119
+ {
1120
+ if (stopped_) {
1121
+ return;
1212
1122
  }
1213
-
1214
- [[nodiscard]] std::size_t index() const
1215
- {
1216
- std::scoped_lock lock(config_mutex_);
1217
- Expects(config_.has_value());
1218
- return config_->index_for_this_node();
1123
+ write(std::move(buf));
1124
+ flush();
1125
+ }
1126
+
1127
+ void remove_request(std::shared_ptr<mcbp::queue_request> request) override
1128
+ {
1129
+ std::scoped_lock lock(operations_mutex_);
1130
+ if (auto iter = operations_.find(request->opaque_); iter != operations_.end()) {
1131
+ operations_.erase(iter);
1219
1132
  }
1220
-
1221
- [[nodiscard]] const std::string& bootstrap_address() const
1133
+ }
1134
+
1135
+ void enqueue_request(std::uint32_t opaque,
1136
+ std::shared_ptr<mcbp::queue_request> request,
1137
+ std::shared_ptr<response_handler> handler)
1138
+ {
1139
+ std::scoped_lock lock(operations_mutex_);
1140
+ request->waiting_in_ = this;
1141
+ operations_.try_emplace(opaque, std::move(request), std::move(handler));
1142
+ }
1143
+
1144
+ auto handle_request(protocol::client_opcode opcode,
1145
+ std::uint16_t status,
1146
+ std::uint32_t opaque,
1147
+ mcbp_message&& msg) -> bool
1148
+ {
1149
+ // handle request old style
1150
+ command_handler fun{};
1222
1151
  {
1223
- return bootstrap_address_;
1152
+ std::scoped_lock lock(command_handlers_mutex_);
1153
+ if (auto handler = command_handlers_.find(opaque);
1154
+ handler != command_handlers_.end() && handler->second) {
1155
+ fun = std::move(handler->second);
1156
+ command_handlers_.erase(handler);
1157
+ }
1224
1158
  }
1225
1159
 
1226
- [[nodiscard]] const std::string& bootstrap_hostname() const
1227
- {
1228
- return bootstrap_hostname_;
1160
+ auto reason = status == static_cast<std::uint16_t>(key_value_status_code::not_my_vbucket)
1161
+ ? retry_reason::key_value_not_my_vbucket
1162
+ : retry_reason::do_not_retry;
1163
+ if (fun) {
1164
+ fun(protocol::map_status_code(opcode, status),
1165
+ reason,
1166
+ std::move(msg),
1167
+ decode_error_code(status));
1168
+ return true;
1229
1169
  }
1230
1170
 
1231
- [[nodiscard]] const std::string& bootstrap_port() const
1171
+ // handle request new style
1172
+ std::shared_ptr<mcbp::queue_request> request{};
1173
+ std::shared_ptr<response_handler> handler{};
1232
1174
  {
1233
- return bootstrap_port_;
1175
+ std::scoped_lock lock(operations_mutex_);
1176
+ if (auto pair = operations_.find(opaque); pair != operations_.end() && pair->second.first) {
1177
+ request = pair->second.first;
1178
+ handler = pair->second.second;
1179
+ if (!request->persistent_) {
1180
+ operations_.erase(pair);
1181
+ }
1182
+ }
1234
1183
  }
1235
-
1236
- [[nodiscard]] std::uint16_t bootstrap_port_number() const
1237
- {
1238
- return bootstrap_port_number_;
1184
+ if (request) {
1185
+ handler->handle_response(std::move(request),
1186
+ protocol::map_status_code(opcode, status),
1187
+ reason,
1188
+ std::move(msg),
1189
+ decode_error_code(status));
1190
+ return true;
1239
1191
  }
1240
-
1241
- [[nodiscard]] std::uint32_t next_opaque()
1242
- {
1243
- return ++opaque_;
1192
+ return false;
1193
+ }
1194
+
1195
+ void write_and_subscribe(std::shared_ptr<mcbp::queue_request> request,
1196
+ std::shared_ptr<response_handler> handler)
1197
+ {
1198
+ auto opaque = request->opaque_;
1199
+ auto data = codec_.encode_packet(*request);
1200
+ if (!data) {
1201
+ CB_LOG_DEBUG("unable to encode packet. opaque={}, ec={}", opaque, data.error().message());
1202
+ request->try_callback({}, data.error());
1203
+ return;
1244
1204
  }
1245
1205
 
1246
- std::optional<key_value_error_map_info> decode_error_code(std::uint16_t code)
1247
- {
1248
- if (error_map_) {
1249
- auto info = error_map_->errors.find(code);
1250
- if (info != error_map_->errors.end()) {
1251
- return info->second;
1252
- }
1253
- }
1254
- return {};
1206
+ if (stopped_) {
1207
+ CB_LOG_WARNING("cancel operation while trying to write to closed mcbp session, opaque={}",
1208
+ opaque);
1209
+ handler->handle_response(request,
1210
+ errc::common::request_canceled,
1211
+ retry_reason::socket_closed_while_in_flight,
1212
+ {},
1213
+ {});
1214
+ return;
1255
1215
  }
1256
-
1257
- void on_configuration_update(std::shared_ptr<config_listener> handler)
1258
- {
1259
- config_listeners_.emplace_back(std::move(handler));
1216
+ enqueue_request(opaque, std::move(request), std::move(handler));
1217
+ if (bootstrapped_ && stream_->is_open()) {
1218
+ write_and_flush(std::move(data.value()));
1219
+ } else {
1220
+ CB_LOG_DEBUG("{} the stream is not ready yet, put the message into pending buffer, opaque={}",
1221
+ log_prefix_,
1222
+ opaque);
1223
+ std::scoped_lock lock(pending_buffer_mutex_);
1224
+ if (bootstrapped_ && stream_->is_open()) {
1225
+ write_and_flush(std::move(data.value()));
1226
+ } else {
1227
+ pending_buffer_.emplace_back(data.value());
1228
+ }
1260
1229
  }
1261
-
1262
- void update_configuration(topology::configuration&& config)
1263
- {
1264
- if (stopped_) {
1265
- return;
1266
- }
1267
- std::scoped_lock lock(config_mutex_);
1268
- // MB-60405 fixes this for 7.6.2, but for earlier versions we need to protect against using a
1269
- // config that has an empty vbucket map. We should be okay to ignore at this point b/c we should
1270
- // already have a config w/ a non-empty vbucket map (bootstrap will not complete successfully
1271
- // unless we have a config w/ a non-empty vbucket map).
1272
- if (config.vbmap && config.vbmap->size() == 0) {
1273
- CB_LOG_DEBUG("{} received a configuration with an empty vbucket map, ignoring", log_prefix_);
1274
- return;
1275
- }
1276
- if (config_) {
1277
- if (config_->vbmap && config.vbmap && config_->vbmap->size() != config.vbmap->size()) {
1278
- CB_LOG_DEBUG("{} received a configuration with a different number of vbuckets, ignoring", log_prefix_);
1279
- return;
1280
- }
1281
- if (config == config_) {
1282
- CB_LOG_TRACE("{} received a configuration with identical revision (new={}, old={}), ignoring",
1283
- log_prefix_,
1284
- config.rev_str(),
1285
- config_->rev_str());
1286
- return;
1287
- }
1288
- if (config < config_) {
1289
- CB_LOG_DEBUG("{} received a configuration with older revision (new={}, old={}), ignoring",
1290
- log_prefix_,
1291
- config.rev_str(),
1292
- config_->rev_str());
1293
- return;
1294
- }
1295
- }
1296
- bool this_node_found = false;
1297
- for (auto& node : config.nodes) {
1298
- if (node.hostname.empty()) {
1299
- node.hostname = bootstrap_hostname_;
1300
- }
1301
- if (node.this_node) {
1302
- this_node_found = true;
1303
- }
1304
- }
1305
- if (!this_node_found) {
1306
- for (auto& node : config.nodes) {
1307
- if (node.hostname == bootstrap_hostname_) {
1308
- if ((node.services_plain.key_value && std::to_string(node.services_plain.key_value.value()) == bootstrap_port_) ||
1309
- (node.services_tls.key_value && std::to_string(node.services_tls.key_value.value()) == bootstrap_port_)) {
1310
- node.this_node = true;
1311
- }
1312
- }
1313
- }
1314
- }
1315
- config_.reset();
1316
- config_.emplace(std::move(config));
1317
- configured_ = true;
1318
- for (const auto& listener : config_listeners_) {
1319
- asio::post(
1320
- asio::bind_executor(ctx_, [listener, c = config_.value()]() mutable { return listener->update_config(std::move(c)); }));
1321
- }
1230
+ }
1231
+
1232
+ void write_and_subscribe(std::uint32_t opaque,
1233
+ std::vector<std::byte>&& data,
1234
+ command_handler&& handler)
1235
+ {
1236
+ if (stopped_) {
1237
+ CB_LOG_WARNING("{} MCBP cancel operation, while trying to write to closed session, opaque={}",
1238
+ log_prefix_,
1239
+ opaque);
1240
+ handler(errc::common::request_canceled, retry_reason::socket_closed_while_in_flight, {}, {});
1241
+ return;
1322
1242
  }
1323
-
1324
- void handle_not_my_vbucket(const io::mcbp_message& msg)
1325
1243
  {
1326
- if (stopped_) {
1327
- return;
1328
- }
1329
- Expects(msg.header.magic == static_cast<std::uint8_t>(protocol::magic::alt_client_response) ||
1330
- msg.header.magic == static_cast<std::uint8_t>(protocol::magic::client_response));
1331
- if (protocol::has_json_datatype(msg.header.datatype)) {
1332
- auto magic = static_cast<protocol::magic>(msg.header.magic);
1333
- std::uint8_t extras_size = msg.header.extlen;
1334
- std::uint8_t framing_extras_size = 0;
1335
- std::uint16_t key_size = utils::byte_swap(msg.header.keylen);
1336
- if (magic == protocol::magic::alt_client_response) {
1337
- framing_extras_size = static_cast<std::uint8_t>(msg.header.keylen >> 8U);
1338
- key_size = msg.header.keylen & 0xffU;
1339
- }
1244
+ std::scoped_lock lock(command_handlers_mutex_);
1245
+ command_handlers_.try_emplace(opaque, std::move(handler));
1246
+ }
1247
+ if (bootstrapped_ && stream_->is_open()) {
1248
+ write_and_flush(std::move(data));
1249
+ } else {
1250
+ CB_LOG_DEBUG("{} the stream is not ready yet, put the message into pending buffer, opaque={}",
1251
+ log_prefix_,
1252
+ opaque);
1253
+ std::scoped_lock lock(pending_buffer_mutex_);
1254
+ if (bootstrapped_ && stream_->is_open()) {
1255
+ write_and_flush(std::move(data));
1256
+ } else {
1257
+ pending_buffer_.emplace_back(data);
1258
+ }
1259
+ }
1260
+ }
1340
1261
 
1341
- std::vector<std::uint8_t>::difference_type offset = framing_extras_size + key_size + extras_size;
1342
- if (utils::byte_swap(msg.header.bodylen) - offset > 0) {
1343
- std::string_view config_text{ reinterpret_cast<const char*>(msg.body.data()) + offset,
1344
- msg.body.size() - static_cast<std::size_t>(offset) };
1345
- if (origin_.options().dump_configuration) {
1346
- CB_LOG_TRACE("{} configuration from not_my_vbucket response (size={}, endpoint=\"{}:{}\"), {}",
1347
- log_prefix_,
1348
- config_text.size(),
1349
- bootstrap_hostname_,
1350
- bootstrap_port_number_,
1351
- config_text);
1352
- }
1353
- auto config = protocol::parse_config(config_text, bootstrap_hostname_, bootstrap_port_number_);
1354
- CB_LOG_DEBUG("{} received not_my_vbucket status for {}, opaque={} with config rev={} in the payload",
1355
- log_prefix_,
1356
- protocol::client_opcode(msg.header.opcode),
1357
- utils::byte_swap(msg.header.opaque),
1358
- config.rev_str());
1359
- update_configuration(std::move(config));
1360
- }
1361
- }
1262
+ [[nodiscard]] auto cancel(std::uint32_t opaque, std::error_code ec, retry_reason reason) -> bool
1263
+ {
1264
+ if (stopped_) {
1265
+ return false;
1266
+ }
1267
+ command_handlers_mutex_.lock();
1268
+ if (auto handler = command_handlers_.find(opaque); handler != command_handlers_.end()) {
1269
+ CB_LOG_DEBUG("{} MCBP cancel operation, opaque={}, ec={} ({})",
1270
+ log_prefix_,
1271
+ opaque,
1272
+ ec.value(),
1273
+ ec.message());
1274
+ if (handler->second) {
1275
+ auto fun = std::move(handler->second);
1276
+ command_handlers_.erase(handler);
1277
+ command_handlers_mutex_.unlock();
1278
+ fun(ec, reason, {}, {});
1279
+ return true;
1280
+ }
1281
+ }
1282
+ command_handlers_mutex_.unlock();
1283
+ return false;
1284
+ }
1285
+
1286
+ [[nodiscard]] auto supports_feature(protocol::hello_feature feature) -> bool
1287
+ {
1288
+ return std::find(supported_features_.begin(), supported_features_.end(), feature) !=
1289
+ supported_features_.end();
1290
+ }
1291
+
1292
+ [[nodiscard]] auto supported_features() const -> std::vector<protocol::hello_feature>
1293
+ {
1294
+ return supported_features_;
1295
+ }
1296
+
1297
+ [[nodiscard]] auto supports_gcccp() const -> bool
1298
+ {
1299
+ return supports_gcccp_;
1300
+ }
1301
+
1302
+ auto config() const -> std::optional<topology::configuration>
1303
+ {
1304
+ return config_;
1305
+ }
1306
+
1307
+ [[nodiscard]] auto has_config() const -> bool
1308
+ {
1309
+ return configured_;
1310
+ }
1311
+
1312
+ [[nodiscard]] auto config() -> topology::configuration
1313
+ {
1314
+ std::scoped_lock lock(config_mutex_);
1315
+ return config_.value();
1316
+ }
1317
+
1318
+ [[nodiscard]] auto index() const -> std::size_t
1319
+ {
1320
+ std::scoped_lock lock(config_mutex_);
1321
+ Expects(config_.has_value());
1322
+ return config_->index_for_this_node();
1323
+ }
1324
+
1325
+ [[nodiscard]] auto bootstrap_address() const -> const std::string&
1326
+ {
1327
+ return bootstrap_address_;
1328
+ }
1329
+
1330
+ [[nodiscard]] auto bootstrap_hostname() const -> const std::string&
1331
+ {
1332
+ return bootstrap_hostname_;
1333
+ }
1334
+
1335
+ [[nodiscard]] auto bootstrap_port() const -> const std::string&
1336
+ {
1337
+ return bootstrap_port_;
1338
+ }
1339
+
1340
+ [[nodiscard]] auto bootstrap_port_number() const -> std::uint16_t
1341
+ {
1342
+ return bootstrap_port_number_;
1343
+ }
1344
+
1345
+ [[nodiscard]] auto next_opaque() -> std::uint32_t
1346
+ {
1347
+ return ++opaque_;
1348
+ }
1349
+
1350
+ auto decode_error_code(std::uint16_t code) -> std::optional<key_value_error_map_info>
1351
+ {
1352
+ if (error_map_) {
1353
+ auto info = error_map_->errors.find(code);
1354
+ if (info != error_map_->errors.end()) {
1355
+ return info->second;
1356
+ }
1362
1357
  }
1358
+ return {};
1359
+ }
1360
+
1361
+ void on_configuration_update(std::shared_ptr<config_listener> handler)
1362
+ {
1363
+ config_listeners_.emplace_back(std::move(handler));
1364
+ }
1365
+
1366
+ void update_configuration(topology::configuration&& config)
1367
+ {
1368
+ if (stopped_) {
1369
+ return;
1370
+ }
1371
+ std::scoped_lock lock(config_mutex_);
1372
+ // MB-60405 fixes this for 7.6.2, but for earlier versions we need to protect against using a
1373
+ // config that has an empty vbucket map. We should be okay to ignore at this point b/c we
1374
+ // should already have a config w/ a non-empty vbucket map (bootstrap will not complete
1375
+ // successfully unless we have a config w/ a non-empty vbucket map).
1376
+ if (config.vbmap && config.vbmap->size() == 0) {
1377
+ CB_LOG_DEBUG("{} received a configuration with an empty vbucket map, ignoring", log_prefix_);
1378
+ return;
1379
+ }
1380
+ if (config_) {
1381
+ if (config_->vbmap && config.vbmap && config_->vbmap->size() != config.vbmap->size()) {
1382
+ CB_LOG_DEBUG("{} received a configuration with a different number of vbuckets, ignoring",
1383
+ log_prefix_);
1384
+ return;
1385
+ }
1386
+ if (config == config_) {
1387
+ CB_LOG_TRACE(
1388
+ "{} received a configuration with identical revision (new={}, old={}), ignoring",
1389
+ log_prefix_,
1390
+ config.rev_str(),
1391
+ config_->rev_str());
1392
+ return;
1393
+ }
1394
+ if (config < config_) {
1395
+ CB_LOG_DEBUG("{} received a configuration with older revision (new={}, old={}), ignoring",
1396
+ log_prefix_,
1397
+ config.rev_str(),
1398
+ config_->rev_str());
1399
+ return;
1400
+ }
1401
+ }
1402
+ bool this_node_found = false;
1403
+ for (auto& node : config.nodes) {
1404
+ if (node.hostname.empty()) {
1405
+ node.hostname = bootstrap_hostname_;
1406
+ }
1407
+ if (node.this_node) {
1408
+ this_node_found = true;
1409
+ }
1410
+ }
1411
+ if (!this_node_found) {
1412
+ for (auto& node : config.nodes) {
1413
+ if (node.hostname == bootstrap_hostname_) {
1414
+ if ((node.services_plain.key_value &&
1415
+ std::to_string(node.services_plain.key_value.value()) == bootstrap_port_) ||
1416
+ (node.services_tls.key_value &&
1417
+ std::to_string(node.services_tls.key_value.value()) == bootstrap_port_)) {
1418
+ node.this_node = true;
1419
+ }
1420
+ }
1421
+ }
1422
+ }
1423
+ config_.reset();
1424
+ config_.emplace(std::move(config));
1425
+ configured_ = true;
1426
+ for (const auto& listener : config_listeners_) {
1427
+ asio::post(asio::bind_executor(ctx_, [listener, c = config_.value()]() mutable {
1428
+ return listener->update_config(std::move(c));
1429
+ }));
1430
+ }
1431
+ }
1363
1432
 
1364
- std::optional<std::uint32_t> get_collection_uid(const std::string& collection_path)
1365
- {
1366
- return collection_cache_.get(collection_path);
1433
+ void handle_not_my_vbucket(const io::mcbp_message& msg)
1434
+ {
1435
+ if (stopped_) {
1436
+ return;
1437
+ }
1438
+ Expects(msg.header.magic == static_cast<std::uint8_t>(protocol::magic::alt_client_response) ||
1439
+ msg.header.magic == static_cast<std::uint8_t>(protocol::magic::client_response));
1440
+ if (protocol::has_json_datatype(msg.header.datatype)) {
1441
+ auto magic = static_cast<protocol::magic>(msg.header.magic);
1442
+ std::uint8_t extras_size = msg.header.extlen;
1443
+ std::uint8_t framing_extras_size = 0;
1444
+ std::uint16_t key_size = utils::byte_swap(msg.header.keylen);
1445
+ if (magic == protocol::magic::alt_client_response) {
1446
+ framing_extras_size = static_cast<std::uint8_t>(msg.header.keylen >> 8U);
1447
+ key_size = msg.header.keylen & 0xffU;
1448
+ }
1449
+
1450
+ std::vector<std::uint8_t>::difference_type offset =
1451
+ framing_extras_size + key_size + extras_size;
1452
+ if (utils::byte_swap(msg.header.bodylen) - offset > 0) {
1453
+ std::string_view config_text{ reinterpret_cast<const char*>(msg.body.data()) + offset,
1454
+ msg.body.size() - static_cast<std::size_t>(offset) };
1455
+ if (origin_.options().dump_configuration) {
1456
+ CB_LOG_TRACE(
1457
+ "{} configuration from not_my_vbucket response (size={}, endpoint=\"{}:{}\"), {}",
1458
+ log_prefix_,
1459
+ config_text.size(),
1460
+ bootstrap_hostname_,
1461
+ bootstrap_port_number_,
1462
+ config_text);
1463
+ }
1464
+ auto config =
1465
+ protocol::parse_config(config_text, bootstrap_hostname_, bootstrap_port_number_);
1466
+ CB_LOG_DEBUG(
1467
+ "{} received not_my_vbucket status for {}, opaque={} with config rev={} in the payload",
1468
+ log_prefix_,
1469
+ protocol::client_opcode(msg.header.opcode),
1470
+ utils::byte_swap(msg.header.opaque),
1471
+ config.rev_str());
1472
+ update_configuration(std::move(config));
1473
+ }
1367
1474
  }
1475
+ }
1368
1476
 
1369
- void update_collection_uid(const std::string& path, std::uint32_t uid)
1370
- {
1371
- if (stopped_) {
1372
- return;
1373
- }
1374
- collection_cache_.update(path, uid);
1477
+ auto get_collection_uid(const std::string& collection_path) -> std::optional<std::uint32_t>
1478
+ {
1479
+ return collection_cache_.get(collection_path);
1480
+ }
1481
+
1482
+ void update_collection_uid(const std::string& path, std::uint32_t uid)
1483
+ {
1484
+ if (stopped_) {
1485
+ return;
1375
1486
  }
1487
+ collection_cache_.update(path, uid);
1488
+ }
1376
1489
 
1377
- private:
1378
- void invoke_bootstrap_handler(std::error_code ec)
1379
- {
1380
- retry_backoff_.cancel();
1490
+ private:
1491
+ void invoke_bootstrap_handler(std::error_code ec)
1492
+ {
1493
+ retry_backoff_.cancel();
1381
1494
 
1382
- if (ec && state_listener_) {
1383
- state_listener_->report_bootstrap_error(fmt::format("{}:{}", bootstrap_hostname_, bootstrap_port_), ec);
1384
- }
1385
- if (ec == errc::network::configuration_not_available) {
1386
- return initiate_bootstrap();
1387
- }
1388
- if (retry_bootstrap_on_bucket_not_found_ && ec == errc::common::bucket_not_found) {
1389
- CB_LOG_DEBUG(R"({} server returned {} ({}), it must be transient condition, retrying)", log_prefix_, ec.value(), ec.message());
1390
- return initiate_bootstrap();
1391
- }
1392
- if (!origin_.exhausted() && ec == errc::common::authentication_failure) {
1393
- CB_LOG_DEBUG(
1394
- R"({} server returned authentication_failure, but the bootstrap list is not exhausted yet. It must be transient condition, retrying)",
1395
- log_prefix_);
1396
- return initiate_bootstrap();
1397
- }
1495
+ if (ec && state_listener_) {
1496
+ state_listener_->report_bootstrap_error(
1497
+ fmt::format("{}:{}", bootstrap_hostname_, bootstrap_port_), ec);
1498
+ }
1499
+ if (ec == errc::network::configuration_not_available) {
1500
+ return initiate_bootstrap();
1501
+ }
1502
+ if (retry_bootstrap_on_bucket_not_found_ && ec == errc::common::bucket_not_found) {
1503
+ CB_LOG_DEBUG(R"({} server returned {} ({}), it must be transient condition, retrying)",
1504
+ log_prefix_,
1505
+ ec.value(),
1506
+ ec.message());
1507
+ return initiate_bootstrap();
1508
+ }
1509
+ if (!origin_.exhausted() && ec == errc::common::authentication_failure) {
1510
+ CB_LOG_DEBUG(
1511
+ R"({} server returned authentication_failure, but the bootstrap list is not exhausted yet. It must be transient condition, retrying)",
1512
+ log_prefix_);
1513
+ return initiate_bootstrap();
1514
+ }
1398
1515
 
1399
- if (!bootstrapped_ && bootstrap_callback_) {
1400
- bootstrap_deadline_.cancel();
1401
- if (config_ && state_listener_) {
1402
- std::vector<std::string> endpoints;
1403
- endpoints.reserve(config_.value().nodes.size());
1404
- for (const auto& node : config_.value().nodes) {
1405
- if (auto endpoint = node.endpoint(origin_.options().network, service_type::key_value, is_tls_); endpoint) {
1406
- endpoints.push_back(endpoint.value());
1407
- }
1408
- }
1409
- state_listener_->report_bootstrap_success(endpoints);
1410
- }
1411
- auto h = std::move(bootstrap_callback_);
1412
- h(ec, config_.value_or(topology::configuration{}));
1413
- }
1414
- if (ec) {
1415
- return stop(retry_reason::node_not_available);
1416
- }
1417
- state_ = diag::endpoint_state::connected;
1418
- std::scoped_lock lock(pending_buffer_mutex_);
1419
- bootstrapped_ = true;
1420
- bootstrap_handler_->stop();
1421
- handler_ = std::make_shared<message_handler>(shared_from_this());
1422
- handler_->start();
1423
- if (!pending_buffer_.empty()) {
1424
- for (auto& buf : pending_buffer_) {
1425
- write(std::move(buf));
1426
- }
1427
- pending_buffer_.clear();
1428
- flush();
1429
- }
1516
+ if (!bootstrapped_ && bootstrap_callback_) {
1517
+ bootstrap_deadline_.cancel();
1518
+ if (config_ && state_listener_) {
1519
+ std::vector<std::string> endpoints;
1520
+ endpoints.reserve(config_.value().nodes.size());
1521
+ for (const auto& node : config_.value().nodes) {
1522
+ if (auto endpoint =
1523
+ node.endpoint(origin_.options().network, service_type::key_value, is_tls_);
1524
+ endpoint) {
1525
+ endpoints.push_back(endpoint.value());
1526
+ }
1527
+ }
1528
+ state_listener_->report_bootstrap_success(endpoints);
1529
+ }
1530
+ auto h = std::move(bootstrap_callback_);
1531
+ h(ec, config_.value_or(topology::configuration{}));
1430
1532
  }
1533
+ if (ec) {
1534
+ return stop(retry_reason::node_not_available);
1535
+ }
1536
+ state_ = diag::endpoint_state::connected;
1537
+ std::scoped_lock lock(pending_buffer_mutex_);
1538
+ bootstrapped_ = true;
1539
+ bootstrap_handler_->stop();
1540
+ handler_ = std::make_shared<message_handler>(shared_from_this());
1541
+ handler_->start();
1542
+ if (!pending_buffer_.empty()) {
1543
+ for (auto& buf : pending_buffer_) {
1544
+ write(std::move(buf));
1545
+ }
1546
+ pending_buffer_.clear();
1547
+ flush();
1548
+ }
1549
+ }
1431
1550
 
1432
- void on_resolve(std::error_code ec, const asio::ip::tcp::resolver::results_type& endpoints)
1433
- {
1434
- if (ec == asio::error::operation_aborted || stopped_) {
1551
+ void on_resolve(std::error_code ec, const asio::ip::tcp::resolver::results_type& endpoints)
1552
+ {
1553
+ if (ec == asio::error::operation_aborted || stopped_) {
1554
+ return;
1555
+ }
1556
+ last_active_ = std::chrono::steady_clock::now();
1557
+ if (ec) {
1558
+ CB_LOG_ERROR("{} error on resolve: {} ({})", log_prefix_, ec.value(), ec.message());
1559
+ return initiate_bootstrap();
1560
+ }
1561
+ endpoints_ = endpoints;
1562
+ CB_LOG_TRACE("{} resolved \"{}:{}\" to {} endpoint(s)",
1563
+ log_prefix_,
1564
+ bootstrap_hostname_,
1565
+ bootstrap_port_,
1566
+ endpoints_.size());
1567
+ do_connect(endpoints_.begin());
1568
+ connection_deadline_.expires_after(origin_.options().resolve_timeout);
1569
+ connection_deadline_.async_wait([self = shared_from_this()](const auto timer_ec) {
1570
+ if (timer_ec == asio::error::operation_aborted || self->stopped_) {
1571
+ return;
1572
+ }
1573
+ return self->stream_->close([self](std::error_code) {
1574
+ self->initiate_bootstrap();
1575
+ });
1576
+ });
1577
+ }
1578
+
1579
+ void do_connect(asio::ip::tcp::resolver::results_type::iterator it)
1580
+ {
1581
+ if (stopped_) {
1582
+ return;
1583
+ }
1584
+ last_active_ = std::chrono::steady_clock::now();
1585
+ if (it != endpoints_.end()) {
1586
+ auto hostname = it->endpoint().address().to_string();
1587
+ auto port = it->endpoint().port();
1588
+ CB_LOG_DEBUG("{} connecting to {}:{} (\"{}:{}\"), timeout={}ms",
1589
+ log_prefix_,
1590
+ hostname,
1591
+ port,
1592
+ bootstrap_hostname_,
1593
+ bootstrap_port_,
1594
+ origin_.options().connect_timeout.count());
1595
+ connection_deadline_.expires_after(origin_.options().connect_timeout);
1596
+ connection_deadline_.async_wait(
1597
+ [self = shared_from_this(), hostname, port](const auto timer_ec) {
1598
+ if (timer_ec == asio::error::operation_aborted || self->stopped_) {
1435
1599
  return;
1436
- }
1437
- last_active_ = std::chrono::steady_clock::now();
1438
- if (ec) {
1439
- CB_LOG_ERROR("{} error on resolve: {} ({})", log_prefix_, ec.value(), ec.message());
1440
- return initiate_bootstrap();
1441
- }
1442
- endpoints_ = endpoints;
1443
- CB_LOG_TRACE("{} resolved \"{}:{}\" to {} endpoint(s)", log_prefix_, bootstrap_hostname_, bootstrap_port_, endpoints_.size());
1444
- do_connect(endpoints_.begin());
1445
- connection_deadline_.expires_after(origin_.options().resolve_timeout);
1446
- connection_deadline_.async_wait([self = shared_from_this()](const auto timer_ec) {
1447
- if (timer_ec == asio::error::operation_aborted || self->stopped_) {
1448
- return;
1449
- }
1450
- return self->stream_->close([self](std::error_code) { self->initiate_bootstrap(); });
1600
+ }
1601
+ CB_LOG_DEBUG("{} unable to connect to {}:{} (\"{}:{}\") in time, reconnecting",
1602
+ self->log_prefix_,
1603
+ hostname,
1604
+ port,
1605
+ self->bootstrap_hostname_,
1606
+ self->bootstrap_port_);
1607
+ return self->stream_->close([self](std::error_code) {
1608
+ self->initiate_bootstrap();
1609
+ });
1451
1610
  });
1611
+ stream_->async_connect(
1612
+ it->endpoint(),
1613
+ std::bind(&mcbp_session_impl::on_connect, shared_from_this(), std::placeholders::_1, it));
1614
+ } else {
1615
+ CB_LOG_ERROR("{} no more endpoints left to connect to \"{}:{}\", will try another address",
1616
+ log_prefix_,
1617
+ bootstrap_hostname_,
1618
+ bootstrap_port_);
1619
+ if (state_listener_) {
1620
+ state_listener_->report_bootstrap_error(
1621
+ fmt::format("{}:{}", bootstrap_hostname_, bootstrap_port_),
1622
+ errc::network::no_endpoints_left);
1623
+ }
1624
+ return initiate_bootstrap();
1452
1625
  }
1626
+ }
1453
1627
 
1454
- void do_connect(asio::ip::tcp::resolver::results_type::iterator it)
1455
- {
1456
- if (stopped_) {
1457
- return;
1458
- }
1459
- last_active_ = std::chrono::steady_clock::now();
1460
- if (it != endpoints_.end()) {
1461
- auto hostname = it->endpoint().address().to_string();
1462
- auto port = it->endpoint().port();
1463
- CB_LOG_DEBUG("{} connecting to {}:{} (\"{}:{}\"), timeout={}ms",
1464
- log_prefix_,
1465
- hostname,
1466
- port,
1467
- bootstrap_hostname_,
1468
- bootstrap_port_,
1469
- origin_.options().connect_timeout.count());
1470
- connection_deadline_.expires_after(origin_.options().connect_timeout);
1471
- connection_deadline_.async_wait([self = shared_from_this(), hostname, port](const auto timer_ec) {
1472
- if (timer_ec == asio::error::operation_aborted || self->stopped_) {
1473
- return;
1474
- }
1475
- CB_LOG_DEBUG("{} unable to connect to {}:{} (\"{}:{}\") in time, reconnecting",
1476
- self->log_prefix_,
1477
- hostname,
1478
- port,
1479
- self->bootstrap_hostname_,
1480
- self->bootstrap_port_);
1481
- return self->stream_->close([self](std::error_code) { self->initiate_bootstrap(); });
1482
- });
1483
- stream_->async_connect(it->endpoint(),
1484
- std::bind(&mcbp_session_impl::on_connect, shared_from_this(), std::placeholders::_1, it));
1485
- } else {
1486
- CB_LOG_ERROR("{} no more endpoints left to connect to \"{}:{}\", will try another address",
1487
- log_prefix_,
1488
- bootstrap_hostname_,
1489
- bootstrap_port_);
1490
- if (state_listener_) {
1491
- state_listener_->report_bootstrap_error(fmt::format("{}:{}", bootstrap_hostname_, bootstrap_port_),
1492
- errc::network::no_endpoints_left);
1493
- }
1494
- return initiate_bootstrap();
1495
- }
1628
+ void on_connect(const std::error_code& ec, asio::ip::tcp::resolver::results_type::iterator it)
1629
+ {
1630
+ if (ec == asio::error::operation_aborted || stopped_) {
1631
+ return;
1496
1632
  }
1497
-
1498
- void on_connect(const std::error_code& ec, asio::ip::tcp::resolver::results_type::iterator it)
1499
- {
1500
- if (ec == asio::error::operation_aborted || stopped_) {
1501
- return;
1502
- }
1503
- last_active_ = std::chrono::steady_clock::now();
1504
- if (!stream_->is_open() || ec) {
1633
+ last_active_ = std::chrono::steady_clock::now();
1634
+ if (!stream_->is_open() || ec) {
1505
1635
  #ifdef COUCHBASE_CXX_CLIENT_STATIC_BORINGSSL
1506
- auto error_message = (ec.category() == asio::error::ssl_category)
1507
- ? ERR_error_string(static_cast<std::uint32_t>(ec.value()), nullptr)
1508
- : ec.message();
1636
+ auto error_message = (ec.category() == asio::error::ssl_category)
1637
+ ? ERR_error_string(static_cast<std::uint32_t>(ec.value()), nullptr)
1638
+ : ec.message();
1509
1639
  #else
1510
- auto error_message = (ec.category() == asio::error::ssl_category)
1511
- ? ERR_error_string(static_cast<unsigned long>(ec.value()), nullptr)
1512
- : ec.message();
1640
+ auto error_message = (ec.category() == asio::error::ssl_category)
1641
+ ? ERR_error_string(static_cast<unsigned long>(ec.value()), nullptr)
1642
+ : ec.message();
1513
1643
  #endif
1514
- CB_LOG_WARNING("{} unable to connect to {}:{}: {} ({}){}. is_open={}",
1515
- log_prefix_,
1516
- it->endpoint().address().to_string(),
1517
- it->endpoint().port(),
1518
- ec.value(),
1519
- error_message,
1520
- (ec == asio::error::connection_refused) ? ", check server ports and cluster encryption setting" : "",
1521
- stream_->is_open());
1522
- if (stream_->is_open()) {
1523
- stream_->close(std::bind(&mcbp_session_impl::do_connect, shared_from_this(), ++it));
1524
- } else {
1525
- do_connect(++it);
1526
- }
1527
- } else {
1528
- stream_->set_options();
1529
- connection_endpoints_ = { it->endpoint(), stream_->local_endpoint() };
1530
- CB_LOG_DEBUG("{} connected to {}:{}", log_prefix_, connection_endpoints_.remote_address, connection_endpoints_.remote.port());
1531
- log_prefix_ = fmt::format("[{}/{}/{}/{}] <{}/{}:{}>",
1532
- client_id_,
1533
- id_,
1534
- stream_->log_prefix(),
1535
- bucket_name_.value_or("-"),
1536
- bootstrap_hostname_,
1537
- connection_endpoints_.remote_address,
1538
- connection_endpoints_.remote.port());
1539
- parser_.reset();
1540
- bootstrap_handler_ = std::make_shared<bootstrap_handler>(shared_from_this());
1541
- connection_deadline_.cancel();
1542
- }
1644
+ CB_LOG_WARNING("{} unable to connect to {}:{}: {} ({}){}. is_open={}",
1645
+ log_prefix_,
1646
+ it->endpoint().address().to_string(),
1647
+ it->endpoint().port(),
1648
+ ec.value(),
1649
+ error_message,
1650
+ (ec == asio::error::connection_refused)
1651
+ ? ", check server ports and cluster encryption setting"
1652
+ : "",
1653
+ stream_->is_open());
1654
+ if (stream_->is_open()) {
1655
+ stream_->close(std::bind(&mcbp_session_impl::do_connect, shared_from_this(), ++it));
1656
+ } else {
1657
+ do_connect(++it);
1658
+ }
1659
+ } else {
1660
+ stream_->set_options();
1661
+ connection_endpoints_ = { it->endpoint(), stream_->local_endpoint() };
1662
+ CB_LOG_DEBUG("{} connected to {}:{}",
1663
+ log_prefix_,
1664
+ connection_endpoints_.remote_address,
1665
+ connection_endpoints_.remote.port());
1666
+ log_prefix_ = fmt::format("[{}/{}/{}/{}] <{}/{}:{}>",
1667
+ client_id_,
1668
+ id_,
1669
+ stream_->log_prefix(),
1670
+ bucket_name_.value_or("-"),
1671
+ bootstrap_hostname_,
1672
+ connection_endpoints_.remote_address,
1673
+ connection_endpoints_.remote.port());
1674
+ parser_.reset();
1675
+ bootstrap_handler_ = std::make_shared<bootstrap_handler>(shared_from_this());
1676
+ connection_deadline_.cancel();
1543
1677
  }
1678
+ }
1544
1679
 
1545
- void check_deadline(std::error_code ec)
1546
- {
1547
- if (ec == asio::error::operation_aborted || stopped_) {
1548
- return;
1549
- }
1550
- if (connection_deadline_.expiry() <= asio::steady_timer::clock_type::now()) {
1551
- stream_->close([](std::error_code) {});
1552
- }
1553
- connection_deadline_.async_wait(std::bind(&mcbp_session_impl::check_deadline, shared_from_this(), std::placeholders::_1));
1680
+ void check_deadline(std::error_code ec)
1681
+ {
1682
+ if (ec == asio::error::operation_aborted || stopped_) {
1683
+ return;
1554
1684
  }
1555
-
1556
- void do_read()
1557
- {
1558
- if (stopped_ || reading_ || !stream_->is_open()) {
1685
+ if (connection_deadline_.expiry() <= asio::steady_timer::clock_type::now()) {
1686
+ stream_->close([](std::error_code) {
1687
+ });
1688
+ }
1689
+ connection_deadline_.async_wait(
1690
+ std::bind(&mcbp_session_impl::check_deadline, shared_from_this(), std::placeholders::_1));
1691
+ }
1692
+
1693
+ void do_read()
1694
+ {
1695
+ if (stopped_ || reading_ || !stream_->is_open()) {
1696
+ return;
1697
+ }
1698
+ reading_ = true;
1699
+ stream_->async_read_some(
1700
+ asio::buffer(input_buffer_),
1701
+ [self = shared_from_this(), stream_id = stream_->id()](std::error_code ec,
1702
+ std::size_t bytes_transferred) {
1703
+ if (ec == asio::error::operation_aborted || self->stopped_) {
1704
+ CB_LOG_PROTOCOL("[MCBP, IN] host=\"{}\", port={}, rc={}, bytes_received={}",
1705
+ self->connection_endpoints_.remote_address,
1706
+ self->connection_endpoints_.remote.port(),
1707
+ ec ? ec.message() : "ok",
1708
+ bytes_transferred);
1709
+ return;
1710
+ } else {
1711
+ CB_LOG_PROTOCOL("[MCBP, IN] host=\"{}\", port={}, rc={}, bytes_received={}{:a}",
1712
+ self->connection_endpoints_.remote_address,
1713
+ self->connection_endpoints_.remote.port(),
1714
+ ec ? ec.message() : "ok",
1715
+ bytes_transferred,
1716
+ spdlog::to_hex(self->input_buffer_.data(),
1717
+ self->input_buffer_.data() +
1718
+ static_cast<std::ptrdiff_t>(bytes_transferred)));
1719
+ }
1720
+ self->last_active_ = std::chrono::steady_clock::now();
1721
+ if (ec) {
1722
+ if (stream_id != self->stream_->id()) {
1723
+ CB_LOG_ERROR(
1724
+ R"({} ignore IO error while reading from the socket: {} ({}), old_id="{}", new_id="{}")",
1725
+ self->log_prefix_,
1726
+ ec.value(),
1727
+ ec.message(),
1728
+ stream_id,
1729
+ self->stream_->id());
1559
1730
  return;
1560
- }
1561
- reading_ = true;
1562
- stream_->async_read_some(
1563
- asio::buffer(input_buffer_),
1564
- [self = shared_from_this(), stream_id = stream_->id()](std::error_code ec, std::size_t bytes_transferred) {
1565
- if (ec == asio::error::operation_aborted || self->stopped_) {
1566
- CB_LOG_PROTOCOL("[MCBP, IN] host=\"{}\", port={}, rc={}, bytes_received={}",
1567
- self->connection_endpoints_.remote_address,
1568
- self->connection_endpoints_.remote.port(),
1569
- ec ? ec.message() : "ok",
1570
- bytes_transferred);
1571
- return;
1572
- } else {
1573
- CB_LOG_PROTOCOL("[MCBP, IN] host=\"{}\", port={}, rc={}, bytes_received={}{:a}",
1574
- self->connection_endpoints_.remote_address,
1575
- self->connection_endpoints_.remote.port(),
1576
- ec ? ec.message() : "ok",
1577
- bytes_transferred,
1578
- spdlog::to_hex(self->input_buffer_.data(),
1579
- self->input_buffer_.data() + static_cast<std::ptrdiff_t>(bytes_transferred)));
1580
- }
1581
- self->last_active_ = std::chrono::steady_clock::now();
1582
- if (ec) {
1583
- if (stream_id != self->stream_->id()) {
1584
- CB_LOG_ERROR(R"({} ignore IO error while reading from the socket: {} ({}), old_id="{}", new_id="{}")",
1585
- self->log_prefix_,
1586
- ec.value(),
1587
- ec.message(),
1588
- stream_id,
1589
- self->stream_->id());
1590
- return;
1591
- }
1592
- CB_LOG_ERROR(R"({} IO error while reading from the socket("{}"): {} ({}))",
1593
- self->log_prefix_,
1594
- self->stream_->id(),
1595
- ec.value(),
1596
- ec.message());
1597
- return self->stop(retry_reason::socket_closed_while_in_flight);
1731
+ }
1732
+ CB_LOG_ERROR(R"({} IO error while reading from the socket("{}"): {} ({}))",
1733
+ self->log_prefix_,
1734
+ self->stream_->id(),
1735
+ ec.value(),
1736
+ ec.message());
1737
+ return self->stop(retry_reason::socket_closed_while_in_flight);
1738
+ }
1739
+ self->parser_.feed(self->input_buffer_.data(),
1740
+ self->input_buffer_.data() +
1741
+ static_cast<std::ptrdiff_t>(bytes_transferred));
1742
+
1743
+ for (;;) {
1744
+ mcbp_message msg{};
1745
+ switch (self->parser_.next(msg)) {
1746
+ case mcbp_parser::result::ok: {
1747
+ if (self->stopped_) {
1748
+ return;
1598
1749
  }
1599
- self->parser_.feed(self->input_buffer_.data(), self->input_buffer_.data() + static_cast<std::ptrdiff_t>(bytes_transferred));
1600
-
1601
- for (;;) {
1602
- mcbp_message msg{};
1603
- switch (self->parser_.next(msg)) {
1604
- case mcbp_parser::result::ok: {
1605
- if (self->stopped_) {
1606
- return;
1607
- }
1608
- CB_LOG_TRACE("{} MCBP recv {}", self->log_prefix_, mcbp_header_view(msg.header_data()));
1609
- if (self->bootstrapped_) {
1610
- self->handler_->handle(std::move(msg));
1611
- } else if (self->bootstrap_handler_) {
1612
- self->bootstrap_handler_->handle(std::move(msg));
1613
- }
1614
- if (self->stopped_) {
1615
- return;
1616
- }
1617
- } break;
1618
- case mcbp_parser::result::need_data:
1619
- self->reading_ = false;
1620
- if (!self->stopped_ && self->stream_->is_open()) {
1621
- self->do_read();
1622
- }
1623
- return;
1624
- case mcbp_parser::result::failure:
1625
- return self->stop(retry_reason::key_value_temporary_failure);
1626
- }
1750
+ CB_LOG_TRACE(
1751
+ "{} MCBP recv {}", self->log_prefix_, mcbp_header_view(msg.header_data()));
1752
+ if (self->bootstrapped_) {
1753
+ self->handler_->handle(std::move(msg));
1754
+ } else if (self->bootstrap_handler_) {
1755
+ self->bootstrap_handler_->handle(std::move(msg));
1627
1756
  }
1628
- });
1629
- }
1630
-
1631
- void do_write()
1632
- {
1633
- if (stopped_ || !stream_->is_open()) {
1634
- return;
1635
- }
1636
- std::scoped_lock lock(writing_buffer_mutex_, output_buffer_mutex_);
1637
- if (!writing_buffer_.empty() || output_buffer_.empty()) {
1638
- return;
1639
- }
1640
- std::swap(writing_buffer_, output_buffer_);
1641
- std::vector<asio::const_buffer> buffers;
1642
- buffers.reserve(writing_buffer_.size());
1643
- for (auto& buf : writing_buffer_) {
1644
- CB_LOG_PROTOCOL("[MCBP, OUT] host=\"{}\", port={}, buffer_size={}{:a}",
1645
- connection_endpoints_.remote_address,
1646
- connection_endpoints_.remote.port(),
1647
- buf.size(),
1648
- spdlog::to_hex(buf));
1649
- buffers.emplace_back(asio::buffer(buf));
1650
- }
1651
- stream_->async_write(buffers, [self = shared_from_this()](std::error_code ec, std::size_t bytes_transferred) {
1652
- CB_LOG_PROTOCOL("[MCBP, OUT] host=\"{}\", port={}, rc={}, bytes_sent={}",
1653
- self->connection_endpoints_.remote_address,
1654
- self->connection_endpoints_.remote.port(),
1655
- ec ? ec.message() : "ok",
1656
- bytes_transferred);
1657
- if (ec == asio::error::operation_aborted || self->stopped_) {
1757
+ if (self->stopped_) {
1658
1758
  return;
1659
- }
1660
- self->last_active_ = std::chrono::steady_clock::now();
1661
-
1662
- if (ec) {
1663
- CB_LOG_ERROR(R"({} IO error while writing to the socket("{}"): {} ({}))",
1664
- self->log_prefix_,
1665
- self->stream_->id(),
1666
- ec.value(),
1667
- ec.message());
1668
- return self->stop(retry_reason::socket_closed_while_in_flight);
1669
- }
1670
- {
1671
- std::scoped_lock inner_lock(self->writing_buffer_mutex_);
1672
- self->writing_buffer_.clear();
1673
- }
1674
- asio::post(asio::bind_executor(self->ctx_, [self]() {
1675
- self->do_write();
1759
+ }
1760
+ } break;
1761
+ case mcbp_parser::result::need_data:
1762
+ self->reading_ = false;
1763
+ if (!self->stopped_ && self->stream_->is_open()) {
1676
1764
  self->do_read();
1677
- }));
1678
- });
1765
+ }
1766
+ return;
1767
+ case mcbp_parser::result::failure:
1768
+ return self->stop(retry_reason::key_value_temporary_failure);
1769
+ }
1770
+ }
1771
+ });
1772
+ }
1773
+
1774
+ void do_write()
1775
+ {
1776
+ if (stopped_ || !stream_->is_open()) {
1777
+ return;
1778
+ }
1779
+ std::scoped_lock lock(writing_buffer_mutex_, output_buffer_mutex_);
1780
+ if (!writing_buffer_.empty() || output_buffer_.empty()) {
1781
+ return;
1679
1782
  }
1783
+ std::swap(writing_buffer_, output_buffer_);
1784
+ std::vector<asio::const_buffer> buffers;
1785
+ buffers.reserve(writing_buffer_.size());
1786
+ for (auto& buf : writing_buffer_) {
1787
+ CB_LOG_PROTOCOL("[MCBP, OUT] host=\"{}\", port={}, buffer_size={}{:a}",
1788
+ connection_endpoints_.remote_address,
1789
+ connection_endpoints_.remote.port(),
1790
+ buf.size(),
1791
+ spdlog::to_hex(buf));
1792
+ buffers.emplace_back(asio::buffer(buf));
1793
+ }
1794
+ stream_->async_write(
1795
+ buffers, [self = shared_from_this()](std::error_code ec, std::size_t bytes_transferred) {
1796
+ CB_LOG_PROTOCOL("[MCBP, OUT] host=\"{}\", port={}, rc={}, bytes_sent={}",
1797
+ self->connection_endpoints_.remote_address,
1798
+ self->connection_endpoints_.remote.port(),
1799
+ ec ? ec.message() : "ok",
1800
+ bytes_transferred);
1801
+ if (ec == asio::error::operation_aborted || self->stopped_) {
1802
+ return;
1803
+ }
1804
+ self->last_active_ = std::chrono::steady_clock::now();
1680
1805
 
1681
- const std::string client_id_;
1682
- const std::string id_{ uuid::to_string(uuid::random()) };
1683
- asio::io_context& ctx_;
1684
- asio::ip::tcp::resolver resolver_;
1685
- std::unique_ptr<stream_impl> stream_;
1686
- asio::steady_timer bootstrap_deadline_;
1687
- asio::steady_timer connection_deadline_;
1688
- asio::steady_timer retry_backoff_;
1689
- asio::steady_timer ping_deadline_;
1690
- couchbase::core::origin origin_;
1691
- std::optional<std::string> bucket_name_;
1692
- mcbp_parser parser_;
1693
- std::shared_ptr<bootstrap_handler> bootstrap_handler_{ nullptr };
1694
- std::optional<std::string> last_bootstrap_error_message_;
1695
- std::shared_ptr<message_handler> handler_{ nullptr };
1696
- utils::movable_function<void(std::error_code, const topology::configuration&)> bootstrap_callback_{};
1697
- std::mutex command_handlers_mutex_{};
1698
- std::map<std::uint32_t, command_handler> command_handlers_{};
1699
- std::vector<std::shared_ptr<config_listener>> config_listeners_{};
1700
- utils::movable_function<void()> on_stop_handler_{};
1701
-
1702
- std::atomic_bool bootstrapped_{ false };
1703
- std::atomic_bool stopped_{ false };
1704
- bool authenticated_{ false };
1705
- bool bucket_selected_{ false };
1706
- bool supports_gcccp_{ true };
1707
- bool retry_bootstrap_on_bucket_not_found_{ false };
1708
-
1709
- std::atomic<std::uint32_t> opaque_{ 0 };
1710
-
1711
- std::array<std::byte, 16384> input_buffer_{};
1712
- std::vector<std::vector<std::byte>> output_buffer_{};
1713
- std::vector<std::vector<std::byte>> pending_buffer_{};
1714
- std::vector<std::vector<std::byte>> writing_buffer_{};
1715
- std::mutex output_buffer_mutex_{};
1716
- std::mutex pending_buffer_mutex_{};
1717
- std::mutex writing_buffer_mutex_{};
1718
- std::string bootstrap_hostname_{};
1719
- std::string bootstrap_port_{};
1720
- std::string bootstrap_address_{};
1721
- std::uint16_t bootstrap_port_number_{};
1722
- connection_endpoints connection_endpoints_{ {}, {} };
1723
- asio::ip::tcp::resolver::results_type endpoints_;
1724
- std::vector<protocol::hello_feature> supported_features_;
1725
- std::optional<topology::configuration> config_;
1726
- mutable std::mutex config_mutex_{};
1727
- std::atomic_bool configured_{ false };
1728
- std::optional<error_map> error_map_;
1729
- collection_cache collection_cache_;
1730
-
1731
- const bool is_tls_;
1732
- std::shared_ptr<impl::bootstrap_state_listener> state_listener_{ nullptr };
1733
-
1734
- mcbp::codec codec_;
1735
- std::recursive_mutex operations_mutex_{};
1736
- std::map<std::uint32_t, std::pair<std::shared_ptr<mcbp::queue_request>, std::shared_ptr<response_handler>>> operations_{};
1737
-
1738
- std::atomic_bool reading_{ false };
1739
-
1740
- std::string log_prefix_{};
1741
- std::chrono::time_point<std::chrono::steady_clock> last_active_{};
1742
- std::atomic<diag::endpoint_state> state_{ diag::endpoint_state::disconnected };
1806
+ if (ec) {
1807
+ CB_LOG_ERROR(R"({} IO error while writing to the socket("{}"): {} ({}))",
1808
+ self->log_prefix_,
1809
+ self->stream_->id(),
1810
+ ec.value(),
1811
+ ec.message());
1812
+ return self->stop(retry_reason::socket_closed_while_in_flight);
1813
+ }
1814
+ {
1815
+ std::scoped_lock inner_lock(self->writing_buffer_mutex_);
1816
+ self->writing_buffer_.clear();
1817
+ }
1818
+ asio::post(asio::bind_executor(self->ctx_, [self]() {
1819
+ self->do_write();
1820
+ self->do_read();
1821
+ }));
1822
+ });
1823
+ }
1824
+
1825
+ const std::string client_id_;
1826
+ const std::string id_{ uuid::to_string(uuid::random()) };
1827
+ asio::io_context& ctx_;
1828
+ asio::ip::tcp::resolver resolver_;
1829
+ std::unique_ptr<stream_impl> stream_;
1830
+ asio::steady_timer bootstrap_deadline_;
1831
+ asio::steady_timer connection_deadline_;
1832
+ asio::steady_timer retry_backoff_;
1833
+ asio::steady_timer ping_deadline_;
1834
+ couchbase::core::origin origin_;
1835
+ std::optional<std::string> bucket_name_;
1836
+ mcbp_parser parser_;
1837
+ std::shared_ptr<bootstrap_handler> bootstrap_handler_{ nullptr };
1838
+ std::optional<std::string> last_bootstrap_error_message_;
1839
+ std::shared_ptr<message_handler> handler_{ nullptr };
1840
+ utils::movable_function<void(std::error_code, const topology::configuration&)>
1841
+ bootstrap_callback_{};
1842
+ std::mutex command_handlers_mutex_{};
1843
+ std::map<std::uint32_t, command_handler> command_handlers_{};
1844
+ std::vector<std::shared_ptr<config_listener>> config_listeners_{};
1845
+ utils::movable_function<void()> on_stop_handler_{};
1846
+
1847
+ std::atomic_bool bootstrapped_{ false };
1848
+ std::atomic_bool stopped_{ false };
1849
+ bool authenticated_{ false };
1850
+ bool bucket_selected_{ false };
1851
+ bool supports_gcccp_{ true };
1852
+ bool retry_bootstrap_on_bucket_not_found_{ false };
1853
+
1854
+ std::atomic<std::uint32_t> opaque_{ 0 };
1855
+
1856
+ std::array<std::byte, 16384> input_buffer_{};
1857
+ std::vector<std::vector<std::byte>> output_buffer_{};
1858
+ std::vector<std::vector<std::byte>> pending_buffer_{};
1859
+ std::vector<std::vector<std::byte>> writing_buffer_{};
1860
+ std::mutex output_buffer_mutex_{};
1861
+ std::mutex pending_buffer_mutex_{};
1862
+ std::mutex writing_buffer_mutex_{};
1863
+ std::string bootstrap_hostname_{};
1864
+ std::string bootstrap_port_{};
1865
+ std::string bootstrap_address_{};
1866
+ std::uint16_t bootstrap_port_number_{};
1867
+ connection_endpoints connection_endpoints_{ {}, {} };
1868
+ asio::ip::tcp::resolver::results_type endpoints_;
1869
+ std::vector<protocol::hello_feature> supported_features_;
1870
+ std::optional<topology::configuration> config_;
1871
+ mutable std::mutex config_mutex_{};
1872
+ std::atomic_bool configured_{ false };
1873
+ std::optional<error_map> error_map_;
1874
+ collection_cache collection_cache_;
1875
+
1876
+ const bool is_tls_;
1877
+ std::shared_ptr<impl::bootstrap_state_listener> state_listener_{ nullptr };
1878
+
1879
+ mcbp::codec codec_;
1880
+ std::recursive_mutex operations_mutex_{};
1881
+ std::map<std::uint32_t,
1882
+ std::pair<std::shared_ptr<mcbp::queue_request>, std::shared_ptr<response_handler>>>
1883
+ operations_{};
1884
+
1885
+ std::atomic_bool reading_{ false };
1886
+
1887
+ std::string log_prefix_{};
1888
+ std::chrono::time_point<std::chrono::steady_clock> last_active_{};
1889
+ std::atomic<diag::endpoint_state> state_{ diag::endpoint_state::disconnected };
1743
1890
  };
1744
1891
 
1745
1892
  mcbp_session::mcbp_session(std::string client_id,
@@ -1774,196 +1921,202 @@ mcbp_session::mcbp_session(std::string client_id,
1774
1921
  {
1775
1922
  }
1776
1923
 
1777
- const std::string&
1778
- mcbp_session::log_prefix() const
1924
+ auto
1925
+ mcbp_session::log_prefix() const -> const std::string&
1779
1926
  {
1780
- return impl_->log_prefix();
1927
+ return impl_->log_prefix();
1781
1928
  }
1782
1929
 
1783
- bool
1784
- mcbp_session::cancel(std::uint32_t opaque, std::error_code ec, retry_reason reason)
1930
+ auto
1931
+ mcbp_session::cancel(std::uint32_t opaque, std::error_code ec, retry_reason reason) -> bool
1785
1932
  {
1786
- return impl_->cancel(opaque, ec, reason);
1933
+ return impl_->cancel(opaque, ec, reason);
1787
1934
  }
1788
1935
 
1789
- bool
1790
- mcbp_session::is_stopped() const
1936
+ auto
1937
+ mcbp_session::is_stopped() const -> bool
1791
1938
  {
1792
- return impl_->is_stopped();
1939
+ return impl_->is_stopped();
1793
1940
  }
1794
1941
 
1795
- bool
1796
- mcbp_session::is_bootstrapped() const
1942
+ auto
1943
+ mcbp_session::is_bootstrapped() const -> bool
1797
1944
  {
1798
- return impl_->is_bootstrapped();
1945
+ return impl_->is_bootstrapped();
1799
1946
  }
1800
1947
 
1801
- std::uint32_t
1802
- mcbp_session::next_opaque()
1948
+ auto
1949
+ mcbp_session::next_opaque() -> std::uint32_t
1803
1950
  {
1804
- return impl_->next_opaque();
1951
+ return impl_->next_opaque();
1805
1952
  }
1806
1953
 
1807
- std::optional<std::uint32_t>
1808
- mcbp_session::get_collection_uid(const std::string& collection_path)
1954
+ auto
1955
+ mcbp_session::get_collection_uid(const std::string& collection_path) -> std::optional<std::uint32_t>
1809
1956
  {
1810
- return impl_->get_collection_uid(collection_path);
1957
+ return impl_->get_collection_uid(collection_path);
1811
1958
  }
1812
1959
 
1813
- mcbp_context
1814
- mcbp_session::context() const
1960
+ auto
1961
+ mcbp_session::context() const -> mcbp_context
1815
1962
  {
1816
- return impl_->context();
1963
+ return impl_->context();
1817
1964
  }
1818
1965
 
1819
- bool
1820
- mcbp_session::supports_feature(protocol::hello_feature feature)
1966
+ auto
1967
+ mcbp_session::supports_feature(protocol::hello_feature feature) -> bool
1821
1968
  {
1822
- return impl_->supports_feature(feature);
1969
+ return impl_->supports_feature(feature);
1823
1970
  }
1824
1971
 
1825
- const std::string&
1826
- mcbp_session::id() const
1972
+ auto
1973
+ mcbp_session::id() const -> const std::string&
1827
1974
  {
1828
- return impl_->id();
1975
+ return impl_->id();
1829
1976
  }
1830
1977
 
1831
- const std::string&
1832
- mcbp_session::bootstrap_address() const
1978
+ auto
1979
+ mcbp_session::bootstrap_address() const -> const std::string&
1833
1980
  {
1834
- return impl_->bootstrap_address();
1981
+ return impl_->bootstrap_address();
1835
1982
  }
1836
1983
 
1837
- std::string
1838
- mcbp_session::remote_address() const
1984
+ auto
1985
+ mcbp_session::remote_address() const -> std::string
1839
1986
  {
1840
- return impl_->remote_address();
1987
+ return impl_->remote_address();
1841
1988
  }
1842
1989
 
1843
- std::string
1844
- mcbp_session::local_address() const
1990
+ auto
1991
+ mcbp_session::local_address() const -> std::string
1845
1992
  {
1846
- return impl_->local_address();
1993
+ return impl_->local_address();
1847
1994
  }
1848
1995
 
1849
- const std::string&
1850
- mcbp_session::bootstrap_hostname() const
1996
+ auto
1997
+ mcbp_session::bootstrap_hostname() const -> const std::string&
1851
1998
  {
1852
- return impl_->bootstrap_hostname();
1999
+ return impl_->bootstrap_hostname();
1853
2000
  }
1854
2001
 
1855
- const std::string&
1856
- mcbp_session::bootstrap_port() const
2002
+ auto
2003
+ mcbp_session::bootstrap_port() const -> const std::string&
1857
2004
  {
1858
- return impl_->bootstrap_port();
2005
+ return impl_->bootstrap_port();
1859
2006
  }
1860
2007
 
1861
- std::uint16_t
1862
- mcbp_session::bootstrap_port_number() const
2008
+ auto
2009
+ mcbp_session::bootstrap_port_number() const -> std::uint16_t
1863
2010
  {
1864
- return impl_->bootstrap_port_number();
2011
+ return impl_->bootstrap_port_number();
1865
2012
  }
1866
2013
 
1867
2014
  void
1868
- mcbp_session::write_and_subscribe(std::uint32_t opaque, std::vector<std::byte>&& data, command_handler&& handler)
2015
+ mcbp_session::write_and_subscribe(std::uint32_t opaque,
2016
+ std::vector<std::byte>&& data,
2017
+ command_handler&& handler)
1869
2018
  {
1870
- return impl_->write_and_subscribe(opaque, std::move(data), std::move(handler));
2019
+ return impl_->write_and_subscribe(opaque, std::move(data), std::move(handler));
1871
2020
  }
1872
2021
 
1873
2022
  void
1874
- mcbp_session::bootstrap(utils::movable_function<void(std::error_code, topology::configuration)>&& handler, bool retry_on_bucket_not_found)
2023
+ mcbp_session::bootstrap(
2024
+ utils::movable_function<void(std::error_code, topology::configuration)>&& handler,
2025
+ bool retry_on_bucket_not_found)
1875
2026
  {
1876
- return impl_->bootstrap(std::move(handler), retry_on_bucket_not_found);
2027
+ return impl_->bootstrap(std::move(handler), retry_on_bucket_not_found);
1877
2028
  }
1878
2029
 
1879
2030
  void
1880
2031
  mcbp_session::on_stop(utils::movable_function<void()> handler)
1881
2032
  {
1882
- return impl_->on_stop(std::move(handler));
2033
+ return impl_->on_stop(std::move(handler));
1883
2034
  }
1884
2035
 
1885
2036
  void
1886
2037
  mcbp_session::stop(retry_reason reason)
1887
2038
  {
1888
- return impl_->stop(reason);
2039
+ return impl_->stop(reason);
1889
2040
  }
1890
2041
 
1891
- std::size_t
1892
- mcbp_session::index() const
2042
+ auto
2043
+ mcbp_session::index() const -> std::size_t
1893
2044
  {
1894
- return impl_->index();
2045
+ return impl_->index();
1895
2046
  }
1896
2047
 
1897
- std::optional<topology::configuration>
1898
- mcbp_session::config() const
2048
+ auto
2049
+ mcbp_session::config() const -> std::optional<topology::configuration>
1899
2050
  {
1900
- return impl_->config();
2051
+ return impl_->config();
1901
2052
  }
1902
2053
 
1903
- bool
1904
- mcbp_session::has_config() const
2054
+ auto
2055
+ mcbp_session::has_config() const -> bool
1905
2056
  {
1906
- return impl_->has_config();
2057
+ return impl_->has_config();
1907
2058
  }
1908
2059
 
1909
- diag::endpoint_diag_info
1910
- mcbp_session::diag_info() const
2060
+ auto
2061
+ mcbp_session::diag_info() const -> diag::endpoint_diag_info
1911
2062
  {
1912
- return impl_->diag_info();
2063
+ return impl_->diag_info();
1913
2064
  }
1914
2065
 
1915
2066
  void
1916
2067
  mcbp_session::on_configuration_update(std::shared_ptr<config_listener> handler)
1917
2068
  {
1918
- return impl_->on_configuration_update(std::move(handler));
2069
+ return impl_->on_configuration_update(std::move(handler));
1919
2070
  }
1920
2071
 
1921
- std::vector<protocol::hello_feature>
1922
- mcbp_session::supported_features() const
2072
+ auto
2073
+ mcbp_session::supported_features() const -> std::vector<protocol::hello_feature>
1923
2074
  {
1924
- return impl_->supported_features();
2075
+ return impl_->supported_features();
1925
2076
  }
1926
2077
 
1927
2078
  void
1928
- mcbp_session::ping(std::shared_ptr<diag::ping_reporter> handler, std::optional<std::chrono::milliseconds> timeout) const
2079
+ mcbp_session::ping(std::shared_ptr<diag::ping_reporter> handler,
2080
+ std::optional<std::chrono::milliseconds> timeout) const
1929
2081
  {
1930
- return impl_->ping(std::move(handler), std::move(timeout));
2082
+ return impl_->ping(std::move(handler), std::move(timeout));
1931
2083
  }
1932
2084
 
1933
- bool
1934
- mcbp_session::supports_gcccp() const
2085
+ auto
2086
+ mcbp_session::supports_gcccp() const -> bool
1935
2087
  {
1936
- return impl_->supports_gcccp();
2088
+ return impl_->supports_gcccp();
1937
2089
  }
1938
2090
 
1939
- std::optional<key_value_error_map_info>
1940
- mcbp_session::decode_error_code(std::uint16_t code)
2091
+ auto
2092
+ mcbp_session::decode_error_code(std::uint16_t code) -> std::optional<key_value_error_map_info>
1941
2093
  {
1942
- return impl_->decode_error_code(code);
2094
+ return impl_->decode_error_code(code);
1943
2095
  }
1944
2096
 
1945
2097
  void
1946
2098
  mcbp_session::handle_not_my_vbucket(const mcbp_message& msg) const
1947
2099
  {
1948
- return impl_->handle_not_my_vbucket(msg);
2100
+ return impl_->handle_not_my_vbucket(msg);
1949
2101
  }
1950
2102
 
1951
2103
  void
1952
2104
  mcbp_session::update_collection_uid(const std::string& path, std::uint32_t uid)
1953
2105
  {
1954
- return impl_->update_collection_uid(path, uid);
2106
+ return impl_->update_collection_uid(path, uid);
1955
2107
  }
1956
2108
 
1957
2109
  void
1958
- mcbp_session::write_and_subscribe(std::shared_ptr<mcbp::queue_request> request, std::shared_ptr<response_handler> handler)
2110
+ mcbp_session::write_and_subscribe(std::shared_ptr<mcbp::queue_request> request,
2111
+ std::shared_ptr<response_handler> handler)
1959
2112
  {
1960
- return impl_->write_and_subscribe(std::move(request), std::move(handler));
2113
+ return impl_->write_and_subscribe(std::move(request), std::move(handler));
1961
2114
  }
1962
2115
 
1963
2116
  void
1964
2117
  mcbp_session::write_and_flush(std::vector<std::byte>&& buffer)
1965
2118
  {
1966
- return impl_->write_and_flush(std::move(buffer));
2119
+ return impl_->write_and_flush(std::move(buffer));
1967
2120
  }
1968
2121
 
1969
2122
  } // namespace couchbase::core::io