couchbase 3.5.1 → 3.5.2

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 (1166) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +40 -0
  4. data/ext/CMakeLists.txt +22 -2
  5. data/ext/cache/extconf_include.rb +3 -3
  6. data/ext/cache/mozilla-ca-bundle.crt +19 -32
  7. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  8. data/ext/couchbase/CMakeLists.txt +16 -9
  9. data/ext/couchbase/cmake/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +3 -4
  10. data/ext/couchbase/cmake/CompilerWarnings.cmake +2 -1
  11. data/ext/couchbase/cmake/Packaging.cmake +41 -0
  12. data/ext/couchbase/cmake/Sanitizers.cmake +1 -0
  13. data/ext/couchbase/cmake/VersionInfo.cmake +5 -5
  14. data/ext/couchbase/cmake/build_version.hxx.in +1 -0
  15. data/ext/couchbase/cmake/couchbase-cxx-client.pc.in +10 -0
  16. data/ext/couchbase/cmake/test_boringssl.cxx +1 -1
  17. data/ext/couchbase/cmake/test_openssl.cxx +1 -1
  18. data/ext/couchbase/core/agent.cxx +353 -304
  19. data/ext/couchbase/core/agent.hxx +94 -76
  20. data/ext/couchbase/core/agent_config.cxx +9 -8
  21. data/ext/couchbase/core/agent_config.hxx +7 -7
  22. data/ext/couchbase/core/agent_group.cxx +132 -120
  23. data/ext/couchbase/core/agent_group.hxx +26 -22
  24. data/ext/couchbase/core/agent_group_config.cxx +8 -7
  25. data/ext/couchbase/core/agent_group_config.hxx +6 -6
  26. data/ext/couchbase/core/agent_unit_test_api.hxx +6 -6
  27. data/ext/couchbase/core/analytics_query_options.cxx +21 -21
  28. data/ext/couchbase/core/analytics_query_options.hxx +19 -18
  29. data/ext/couchbase/core/analytics_scan_consistency.hxx +2 -2
  30. data/ext/couchbase/core/bucket.cxx +848 -776
  31. data/ext/couchbase/core/bucket.hxx +151 -139
  32. data/ext/couchbase/core/capella_ca.hxx +20 -19
  33. data/ext/couchbase/core/cluster.cxx +1240 -927
  34. data/ext/couchbase/core/cluster.hxx +254 -167
  35. data/ext/couchbase/core/cluster_agent.cxx +7 -7
  36. data/ext/couchbase/core/cluster_agent.hxx +4 -4
  37. data/ext/couchbase/core/cluster_agent_config.cxx +8 -7
  38. data/ext/couchbase/core/cluster_agent_config.hxx +6 -6
  39. data/ext/couchbase/core/cluster_options.cxx +17 -17
  40. data/ext/couchbase/core/cluster_options.hxx +50 -47
  41. data/ext/couchbase/core/cluster_state.hxx +3 -3
  42. data/ext/couchbase/core/collection_id_cache_entry.hxx +5 -4
  43. data/ext/couchbase/core/collections_component.cxx +372 -329
  44. data/ext/couchbase/core/collections_component.hxx +17 -13
  45. data/ext/couchbase/core/collections_component_unit_test_api.hxx +6 -6
  46. data/ext/couchbase/core/collections_options.hxx +29 -27
  47. data/ext/couchbase/core/config_listener.hxx +3 -3
  48. data/ext/couchbase/core/config_profile.hxx +3 -3
  49. data/ext/couchbase/core/config_profiles.cxx +31 -31
  50. data/ext/couchbase/core/config_profiles.hxx +19 -19
  51. data/ext/couchbase/core/core_sdk_shim.cxx +2 -1
  52. data/ext/couchbase/core/core_sdk_shim.hxx +2 -2
  53. data/ext/couchbase/core/crud_component.cxx +310 -276
  54. data/ext/couchbase/core/crud_component.hxx +21 -15
  55. data/ext/couchbase/core/crud_options.hxx +361 -354
  56. data/ext/couchbase/core/crypto/cbcrypto.cc +732 -627
  57. data/ext/couchbase/core/crypto/cbcrypto.h +12 -3
  58. data/ext/couchbase/core/design_document_namespace.hxx +2 -2
  59. data/ext/couchbase/core/design_document_namespace_fmt.hxx +18 -18
  60. data/ext/couchbase/core/diagnostics.hxx +44 -44
  61. data/ext/couchbase/core/diagnostics_fmt.hxx +76 -76
  62. data/ext/couchbase/core/diagnostics_json.hxx +61 -60
  63. data/ext/couchbase/core/diagntostics_options.hxx +14 -14
  64. data/ext/couchbase/core/dispatcher.cxx +4 -3
  65. data/ext/couchbase/core/dispatcher.hxx +8 -7
  66. data/ext/couchbase/core/document_id.cxx +37 -34
  67. data/ext/couchbase/core/document_id.hxx +87 -86
  68. data/ext/couchbase/core/document_id_fmt.hxx +10 -10
  69. data/ext/couchbase/core/durability_options.hxx +50 -49
  70. data/ext/couchbase/core/error_context/analytics.hxx +18 -18
  71. data/ext/couchbase/core/error_context/analytics_json.hxx +115 -0
  72. data/ext/couchbase/core/error_context/base_error_context.hxx +184 -0
  73. data/ext/couchbase/core/error_context/http.hxx +14 -14
  74. data/ext/couchbase/core/error_context/http_json.hxx +90 -0
  75. data/ext/couchbase/core/error_context/internal_tof_metadata_json.hxx +36 -0
  76. data/ext/couchbase/core/error_context/key_value.cxx +27 -27
  77. data/ext/couchbase/core/error_context/key_value.hxx +41 -38
  78. data/ext/couchbase/core/error_context/key_value_error_context.hxx +235 -0
  79. data/ext/couchbase/core/error_context/key_value_error_map_attribute.hxx +142 -0
  80. data/ext/couchbase/core/error_context/key_value_error_map_info.hxx +139 -0
  81. data/ext/couchbase/core/error_context/key_value_extended_error_info.hxx +86 -0
  82. data/ext/couchbase/core/error_context/key_value_json.hxx +83 -0
  83. data/ext/couchbase/core/error_context/key_value_status_code.hxx +109 -0
  84. data/ext/couchbase/core/error_context/query.hxx +18 -18
  85. data/ext/couchbase/core/error_context/query_error_context.hxx +150 -0
  86. data/ext/couchbase/core/error_context/query_json.hxx +114 -0
  87. data/ext/couchbase/core/error_context/query_public_json.hxx +84 -0
  88. data/ext/couchbase/core/error_context/search.hxx +17 -17
  89. data/ext/couchbase/core/error_context/search_json.hxx +101 -0
  90. data/ext/couchbase/core/error_context/subdocument_error_context.hxx +147 -0
  91. data/ext/couchbase/core/error_context/subdocument_json.hxx +48 -0
  92. data/ext/couchbase/{couchbase → core/error_context}/transaction_error_context.hxx +22 -22
  93. data/ext/couchbase/core/error_context/transaction_op_error_context.hxx +79 -0
  94. data/ext/couchbase/core/error_context/view.hxx +17 -17
  95. data/ext/couchbase/core/fmt/key_value_error_map_attribute.hxx +100 -0
  96. data/ext/couchbase/{couchbase → core}/fmt/key_value_extended_error_info.hxx +20 -20
  97. data/ext/couchbase/core/fmt/key_value_status_code.hxx +269 -0
  98. data/ext/couchbase/core/free_form_http_request.cxx +26 -26
  99. data/ext/couchbase/core/free_form_http_request.hxx +34 -33
  100. data/ext/couchbase/core/impl/analytics.cxx +111 -131
  101. data/ext/couchbase/core/impl/analytics.hxx +5 -7
  102. data/ext/couchbase/core/impl/analytics_error_category.cxx +29 -28
  103. data/ext/couchbase/core/impl/analytics_index_manager.cxx +615 -516
  104. data/ext/couchbase/core/impl/best_effort_retry_strategy.cxx +53 -50
  105. data/ext/couchbase/core/impl/binary_collection.cxx +346 -285
  106. data/ext/couchbase/core/impl/boolean_field_query.cxx +10 -10
  107. data/ext/couchbase/core/impl/boolean_query.cxx +27 -27
  108. data/ext/couchbase/core/impl/bootstrap_state_listener.hxx +6 -6
  109. data/ext/couchbase/core/impl/bucket.cxx +39 -34
  110. data/ext/couchbase/core/impl/bucket_manager.cxx +354 -313
  111. data/ext/couchbase/core/impl/cluster.cxx +430 -325
  112. data/ext/couchbase/core/impl/collection.cxx +1033 -1187
  113. data/ext/couchbase/core/impl/collection_manager.cxx +201 -170
  114. data/ext/couchbase/core/impl/common_error_category.cxx +58 -55
  115. data/ext/couchbase/core/impl/configuration_profiles_registry.cxx +46 -32
  116. data/ext/couchbase/core/impl/conjunction_query.cxx +17 -17
  117. data/ext/couchbase/core/impl/date_range.cxx +24 -20
  118. data/ext/couchbase/core/impl/date_range_facet.cxx +22 -22
  119. data/ext/couchbase/core/impl/date_range_facet_result.cxx +6 -6
  120. data/ext/couchbase/core/impl/date_range_query.cxx +50 -48
  121. data/ext/couchbase/core/impl/diagnostics.cxx +211 -198
  122. data/ext/couchbase/core/impl/diagnostics.hxx +7 -6
  123. data/ext/couchbase/core/impl/disjunction_query.cxx +18 -17
  124. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +92 -75
  125. data/ext/couchbase/core/impl/dns_srv_tracker.hxx +24 -20
  126. data/ext/couchbase/core/impl/doc_id_query.cxx +9 -9
  127. data/ext/couchbase/core/impl/encoded_search_facet.hxx +2 -2
  128. data/ext/couchbase/core/impl/encoded_search_query.hxx +2 -2
  129. data/ext/couchbase/core/impl/encoded_search_sort.hxx +2 -2
  130. data/ext/couchbase/core/impl/error.cxx +171 -0
  131. data/ext/couchbase/core/impl/error.hxx +64 -0
  132. data/ext/couchbase/core/impl/error_context.cxx +56 -0
  133. data/ext/couchbase/core/impl/expiry.cxx +66 -53
  134. data/ext/couchbase/core/impl/fail_fast_retry_strategy.cxx +5 -4
  135. data/ext/couchbase/core/impl/field_level_encryption_error_category.cxx +30 -28
  136. data/ext/couchbase/core/impl/geo_bounding_box_query.cxx +17 -17
  137. data/ext/couchbase/core/impl/geo_distance_query.cxx +14 -14
  138. data/ext/couchbase/core/impl/geo_polygon_query.cxx +17 -17
  139. data/ext/couchbase/core/impl/get_all_replicas.hxx +26 -22
  140. data/ext/couchbase/core/impl/get_any_replica.hxx +25 -23
  141. data/ext/couchbase/core/impl/get_replica.cxx +18 -15
  142. data/ext/couchbase/core/impl/get_replica.hxx +23 -18
  143. data/ext/couchbase/core/impl/internal_date_range_facet_result.cxx +16 -14
  144. data/ext/couchbase/core/impl/internal_date_range_facet_result.hxx +16 -15
  145. data/ext/couchbase/core/impl/internal_error_context.cxx +79 -0
  146. data/ext/couchbase/core/impl/internal_error_context.hxx +52 -0
  147. data/ext/couchbase/core/impl/internal_numeric_range_facet_result.cxx +18 -15
  148. data/ext/couchbase/core/impl/internal_numeric_range_facet_result.hxx +16 -15
  149. data/ext/couchbase/core/impl/internal_scan_result.hxx +7 -7
  150. data/ext/couchbase/core/impl/internal_search_error_context.cxx +25 -22
  151. data/ext/couchbase/core/impl/internal_search_error_context.hxx +32 -31
  152. data/ext/couchbase/core/impl/internal_search_meta_data.cxx +15 -13
  153. data/ext/couchbase/core/impl/internal_search_meta_data.hxx +10 -9
  154. data/ext/couchbase/core/impl/internal_search_result.cxx +30 -22
  155. data/ext/couchbase/core/impl/internal_search_result.hxx +10 -9
  156. data/ext/couchbase/core/impl/internal_search_row.cxx +10 -10
  157. data/ext/couchbase/core/impl/internal_search_row.hxx +16 -16
  158. data/ext/couchbase/core/impl/internal_search_row_location.hxx +2 -2
  159. data/ext/couchbase/core/impl/internal_search_row_locations.cxx +68 -65
  160. data/ext/couchbase/core/impl/internal_search_row_locations.hxx +16 -13
  161. data/ext/couchbase/core/impl/internal_term_facet_result.cxx +16 -14
  162. data/ext/couchbase/core/impl/internal_term_facet_result.hxx +15 -15
  163. data/ext/couchbase/core/impl/key_value_error_category.cxx +73 -72
  164. data/ext/couchbase/core/impl/key_value_error_context.cxx +65 -65
  165. data/ext/couchbase/core/impl/logger.cxx +91 -0
  166. data/ext/couchbase/core/impl/lookup_in_all_replicas.hxx +32 -29
  167. data/ext/couchbase/core/impl/lookup_in_any_replica.hxx +33 -29
  168. data/ext/couchbase/core/impl/lookup_in_replica.cxx +75 -68
  169. data/ext/couchbase/core/impl/lookup_in_replica.hxx +30 -26
  170. data/ext/couchbase/core/impl/management_error_category.cxx +41 -40
  171. data/ext/couchbase/core/impl/match_all_query.cxx +6 -6
  172. data/ext/couchbase/core/impl/match_none_query.cxx +6 -6
  173. data/ext/couchbase/core/impl/match_phrase_query.cxx +13 -13
  174. data/ext/couchbase/core/impl/match_query.cxx +28 -28
  175. data/ext/couchbase/core/impl/network_error_category.cxx +39 -38
  176. data/ext/couchbase/core/impl/numeric_range.cxx +6 -6
  177. data/ext/couchbase/core/impl/numeric_range_facet.cxx +22 -22
  178. data/ext/couchbase/core/impl/numeric_range_facet_result.cxx +6 -6
  179. data/ext/couchbase/core/impl/numeric_range_query.cxx +22 -22
  180. data/ext/couchbase/core/impl/observe_poll.cxx +294 -277
  181. data/ext/couchbase/core/impl/observe_poll.hxx +1 -1
  182. data/ext/couchbase/core/impl/observe_seqno.cxx +21 -18
  183. data/ext/couchbase/core/impl/observe_seqno.hxx +31 -26
  184. data/ext/couchbase/core/impl/phrase_query.cxx +10 -10
  185. data/ext/couchbase/core/impl/prefix_query.cxx +10 -10
  186. data/ext/couchbase/core/impl/query.cxx +163 -154
  187. data/ext/couchbase/core/impl/query.hxx +6 -7
  188. data/ext/couchbase/core/impl/query_error_category.cxx +22 -21
  189. data/ext/couchbase/core/impl/query_error_context.cxx +45 -45
  190. data/ext/couchbase/core/impl/query_index_manager.cxx +488 -408
  191. data/ext/couchbase/core/impl/query_string_query.cxx +7 -7
  192. data/ext/couchbase/core/impl/regexp_query.cxx +10 -10
  193. data/ext/couchbase/core/impl/replica_utils.cxx +66 -0
  194. data/ext/couchbase/core/impl/replica_utils.hxx +48 -0
  195. data/ext/couchbase/core/impl/retry_action.cxx +3 -3
  196. data/ext/couchbase/core/impl/retry_reason.cxx +129 -56
  197. data/ext/couchbase/core/impl/retry_reason.hxx +28 -0
  198. data/ext/couchbase/core/impl/scan_result.cxx +53 -49
  199. data/ext/couchbase/core/impl/scope.cxx +103 -94
  200. data/ext/couchbase/core/impl/search.cxx +139 -130
  201. data/ext/couchbase/core/impl/search.hxx +4 -4
  202. data/ext/couchbase/core/impl/search_error_category.cxx +18 -17
  203. data/ext/couchbase/core/impl/search_index_manager.cxx +492 -390
  204. data/ext/couchbase/core/impl/search_meta_data.cxx +3 -3
  205. data/ext/couchbase/core/impl/search_request.cxx +78 -78
  206. data/ext/couchbase/core/impl/search_result.cxx +5 -5
  207. data/ext/couchbase/core/impl/search_row.cxx +7 -7
  208. data/ext/couchbase/core/impl/search_row_location.cxx +9 -8
  209. data/ext/couchbase/core/impl/search_row_locations.cxx +8 -7
  210. data/ext/couchbase/core/impl/search_sort_field.cxx +53 -53
  211. data/ext/couchbase/core/impl/search_sort_geo_distance.cxx +49 -48
  212. data/ext/couchbase/core/impl/search_sort_id.cxx +10 -10
  213. data/ext/couchbase/core/impl/search_sort_score.cxx +10 -10
  214. data/ext/couchbase/core/impl/streaming_json_lexer_error_category.cxx +70 -68
  215. data/ext/couchbase/core/impl/subdoc/array_add_unique.cxx +6 -6
  216. data/ext/couchbase/core/impl/subdoc/array_append.cxx +6 -6
  217. data/ext/couchbase/core/impl/subdoc/array_insert.cxx +6 -6
  218. data/ext/couchbase/core/impl/subdoc/array_prepend.cxx +6 -6
  219. data/ext/couchbase/core/impl/subdoc/command.hxx +5 -5
  220. data/ext/couchbase/core/impl/subdoc/command_bundle.hxx +11 -11
  221. data/ext/couchbase/core/impl/subdoc/count.cxx +6 -6
  222. data/ext/couchbase/core/impl/subdoc/counter.cxx +6 -6
  223. data/ext/couchbase/core/impl/subdoc/exists.cxx +6 -6
  224. data/ext/couchbase/core/impl/subdoc/get.cxx +6 -6
  225. data/ext/couchbase/core/impl/subdoc/insert.cxx +6 -6
  226. data/ext/couchbase/core/impl/subdoc/join_values.cxx +25 -25
  227. data/ext/couchbase/core/impl/subdoc/lookup_in_macro.cxx +61 -60
  228. data/ext/couchbase/core/impl/subdoc/lookup_in_specs.cxx +9 -9
  229. data/ext/couchbase/core/impl/subdoc/mutate_in_macro.cxx +48 -39
  230. data/ext/couchbase/core/impl/subdoc/mutate_in_specs.cxx +9 -9
  231. data/ext/couchbase/core/impl/subdoc/opcode.hxx +16 -16
  232. data/ext/couchbase/core/impl/subdoc/path_flags.hxx +40 -17
  233. data/ext/couchbase/core/impl/subdoc/remove.cxx +6 -6
  234. data/ext/couchbase/core/impl/subdoc/replace.cxx +6 -6
  235. data/ext/couchbase/core/impl/subdoc/upsert.cxx +6 -6
  236. data/ext/couchbase/core/impl/term_facet.cxx +8 -8
  237. data/ext/couchbase/core/impl/term_facet_result.cxx +6 -6
  238. data/ext/couchbase/core/impl/term_query.cxx +25 -25
  239. data/ext/couchbase/core/impl/term_range_query.cxx +22 -22
  240. data/ext/couchbase/core/impl/transaction_error_category.cxx +21 -20
  241. data/ext/couchbase/core/impl/transaction_get_result.cxx +41 -30
  242. data/ext/couchbase/core/impl/transaction_op_error_category.cxx +55 -56
  243. data/ext/couchbase/core/impl/vector_query.cxx +15 -10
  244. data/ext/couchbase/core/impl/vector_search.cxx +9 -9
  245. data/ext/couchbase/core/impl/view_error_category.cxx +17 -16
  246. data/ext/couchbase/core/impl/wildcard_query.cxx +10 -10
  247. data/ext/couchbase/core/impl/with_legacy_durability.hxx +30 -29
  248. data/ext/couchbase/core/io/dns_client.cxx +257 -232
  249. data/ext/couchbase/core/io/dns_client.hxx +19 -18
  250. data/ext/couchbase/core/io/dns_codec.hxx +156 -154
  251. data/ext/couchbase/core/io/dns_config.cxx +114 -109
  252. data/ext/couchbase/core/io/dns_config.hxx +15 -13
  253. data/ext/couchbase/core/io/dns_message.hxx +365 -342
  254. data/ext/couchbase/core/io/http_command.hxx +155 -134
  255. data/ext/couchbase/core/io/http_context.hxx +5 -5
  256. data/ext/couchbase/core/io/http_message.hxx +75 -71
  257. data/ext/couchbase/core/io/http_parser.cxx +70 -67
  258. data/ext/couchbase/core/io/http_parser.hxx +18 -18
  259. data/ext/couchbase/core/io/http_session.hxx +620 -520
  260. data/ext/couchbase/core/io/http_session_manager.hxx +406 -315
  261. data/ext/couchbase/core/io/http_traits.hxx +7 -0
  262. data/ext/couchbase/core/io/ip_protocol.hxx +3 -3
  263. data/ext/couchbase/core/io/mcbp_command.hxx +298 -278
  264. data/ext/couchbase/core/io/mcbp_context.hxx +7 -6
  265. data/ext/couchbase/core/io/mcbp_message.cxx +8 -8
  266. data/ext/couchbase/core/io/mcbp_message.hxx +19 -19
  267. data/ext/couchbase/core/io/mcbp_parser.cxx +60 -51
  268. data/ext/couchbase/core/io/mcbp_parser.hxx +21 -17
  269. data/ext/couchbase/core/io/mcbp_session.cxx +1769 -1616
  270. data/ext/couchbase/core/io/mcbp_session.hxx +63 -57
  271. data/ext/couchbase/core/io/query_cache.hxx +34 -34
  272. data/ext/couchbase/core/io/retry_context.hxx +45 -45
  273. data/ext/couchbase/core/io/retry_orchestrator.hxx +52 -42
  274. data/ext/couchbase/core/io/streams.hxx +210 -193
  275. data/ext/couchbase/core/json_string.hxx +47 -47
  276. data/ext/couchbase/core/key_value_config.cxx +8 -8
  277. data/ext/couchbase/core/key_value_config.hxx +12 -11
  278. data/ext/couchbase/core/logger/configuration.hxx +35 -35
  279. data/ext/couchbase/core/logger/custom_rotating_file_sink.cxx +73 -72
  280. data/ext/couchbase/core/logger/custom_rotating_file_sink.hxx +20 -18
  281. data/ext/couchbase/core/logger/level.hxx +9 -1
  282. data/ext/couchbase/core/logger/logger.cxx +279 -252
  283. data/ext/couchbase/core/logger/logger.hxx +110 -58
  284. data/ext/couchbase/core/management/analytics_dataset.hxx +4 -4
  285. data/ext/couchbase/core/management/analytics_index.hxx +4 -4
  286. data/ext/couchbase/core/management/analytics_link_azure_blob_external.cxx +35 -33
  287. data/ext/couchbase/core/management/analytics_link_azure_blob_external.hxx +36 -35
  288. data/ext/couchbase/core/management/analytics_link_azure_blob_external_json.hxx +24 -20
  289. data/ext/couchbase/core/management/analytics_link_couchbase_remote.cxx +66 -65
  290. data/ext/couchbase/core/management/analytics_link_couchbase_remote.hxx +77 -70
  291. data/ext/couchbase/core/management/analytics_link_couchbase_remote_json.hxx +38 -32
  292. data/ext/couchbase/core/management/analytics_link_s3_external.cxx +26 -25
  293. data/ext/couchbase/core/management/analytics_link_s3_external.hxx +30 -30
  294. data/ext/couchbase/core/management/analytics_link_s3_external_json.hxx +18 -16
  295. data/ext/couchbase/core/management/bucket_settings.hxx +109 -91
  296. data/ext/couchbase/core/management/bucket_settings_json.hxx +112 -94
  297. data/ext/couchbase/core/management/design_document.hxx +9 -9
  298. data/ext/couchbase/core/management/eventing_function.hxx +124 -121
  299. data/ext/couchbase/core/management/eventing_function_json.hxx +228 -184
  300. data/ext/couchbase/core/management/eventing_status.hxx +41 -41
  301. data/ext/couchbase/core/management/eventing_status_json.hxx +53 -45
  302. data/ext/couchbase/core/management/rbac.hxx +33 -28
  303. data/ext/couchbase/core/management/rbac_fmt.hxx +21 -21
  304. data/ext/couchbase/core/management/rbac_json.hxx +132 -125
  305. data/ext/couchbase/core/management/search_index.cxx +79 -0
  306. data/ext/couchbase/core/management/search_index.hxx +11 -10
  307. data/ext/couchbase/core/management/search_index_json.hxx +27 -26
  308. data/ext/couchbase/core/mcbp/barrier_frame.hxx +4 -3
  309. data/ext/couchbase/core/mcbp/big_endian.cxx +22 -22
  310. data/ext/couchbase/core/mcbp/buffer_writer.cxx +22 -19
  311. data/ext/couchbase/core/mcbp/buffer_writer.hxx +9 -9
  312. data/ext/couchbase/core/mcbp/codec.cxx +419 -397
  313. data/ext/couchbase/core/mcbp/codec.hxx +14 -12
  314. data/ext/couchbase/core/mcbp/command_code.cxx +48 -48
  315. data/ext/couchbase/core/mcbp/completion_token.hxx +33 -33
  316. data/ext/couchbase/core/mcbp/datatype.hxx +3 -3
  317. data/ext/couchbase/core/mcbp/durability_level.hxx +8 -7
  318. data/ext/couchbase/core/mcbp/durability_level_frame.hxx +3 -2
  319. data/ext/couchbase/core/mcbp/durability_timeout_frame.hxx +4 -3
  320. data/ext/couchbase/core/mcbp/open_tracing_frame.hxx +3 -2
  321. data/ext/couchbase/core/mcbp/operation_consumer.cxx +3 -3
  322. data/ext/couchbase/core/mcbp/operation_consumer.hxx +9 -9
  323. data/ext/couchbase/core/mcbp/operation_queue.cxx +76 -70
  324. data/ext/couchbase/core/mcbp/operation_queue.hxx +18 -17
  325. data/ext/couchbase/core/mcbp/packet.cxx +65 -51
  326. data/ext/couchbase/core/mcbp/packet.hxx +25 -25
  327. data/ext/couchbase/core/mcbp/preserve_expiry_frame.hxx +4 -2
  328. data/ext/couchbase/core/mcbp/queue_callback.hxx +3 -2
  329. data/ext/couchbase/core/mcbp/queue_request.cxx +65 -62
  330. data/ext/couchbase/core/mcbp/queue_request.hxx +54 -52
  331. data/ext/couchbase/core/mcbp/queue_request_connection_info.hxx +3 -3
  332. data/ext/couchbase/core/mcbp/queue_response.hxx +7 -7
  333. data/ext/couchbase/core/mcbp/read_units_frame.hxx +3 -2
  334. data/ext/couchbase/core/mcbp/server_duration.cxx +7 -7
  335. data/ext/couchbase/core/mcbp/server_duration_frame.hxx +3 -2
  336. data/ext/couchbase/core/mcbp/stream_id_frame.hxx +3 -2
  337. data/ext/couchbase/core/mcbp/unsupported_frame.hxx +4 -3
  338. data/ext/couchbase/core/mcbp/user_impersonation_frame.hxx +1 -1
  339. data/ext/couchbase/core/mcbp/write_units_frame.hxx +3 -2
  340. data/ext/couchbase/core/meta/features.hxx +58 -0
  341. data/ext/couchbase/core/meta/version.cxx +255 -204
  342. data/ext/couchbase/core/meta/version.hxx +31 -20
  343. data/ext/couchbase/core/metrics/logging_meter.cxx +160 -154
  344. data/ext/couchbase/core/metrics/logging_meter.hxx +16 -15
  345. data/ext/couchbase/core/metrics/logging_meter_options.hxx +1 -1
  346. data/ext/couchbase/core/metrics/noop_meter.hxx +14 -13
  347. data/ext/couchbase/core/mozilla_ca_bundle.hxx +2 -2
  348. data/ext/couchbase/core/n1ql_query_options.cxx +31 -31
  349. data/ext/couchbase/core/n1ql_query_options.hxx +22 -21
  350. data/ext/couchbase/core/operation_map.hxx +3 -3
  351. data/ext/couchbase/core/operations/document_analytics.cxx +187 -176
  352. data/ext/couchbase/core/operations/document_analytics.hxx +79 -71
  353. data/ext/couchbase/core/operations/document_append.cxx +18 -15
  354. data/ext/couchbase/core/operations/document_append.hxx +18 -16
  355. data/ext/couchbase/core/operations/document_decrement.cxx +26 -23
  356. data/ext/couchbase/core/operations/document_decrement.hxx +24 -20
  357. data/ext/couchbase/core/operations/document_exists.cxx +23 -21
  358. data/ext/couchbase/core/operations/document_exists.hxx +25 -23
  359. data/ext/couchbase/core/operations/document_get.cxx +17 -15
  360. data/ext/couchbase/core/operations/document_get.hxx +17 -15
  361. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +121 -92
  362. data/ext/couchbase/core/operations/document_get_and_lock.cxx +19 -16
  363. data/ext/couchbase/core/operations/document_get_and_lock.hxx +21 -17
  364. data/ext/couchbase/core/operations/document_get_and_touch.cxx +19 -16
  365. data/ext/couchbase/core/operations/document_get_and_touch.hxx +22 -18
  366. data/ext/couchbase/core/operations/document_get_any_replica.hxx +111 -82
  367. data/ext/couchbase/core/operations/document_get_projected.cxx +193 -184
  368. data/ext/couchbase/core/operations/document_get_projected.hxx +25 -21
  369. data/ext/couchbase/core/operations/document_increment.cxx +26 -23
  370. data/ext/couchbase/core/operations/document_increment.hxx +24 -20
  371. data/ext/couchbase/core/operations/document_insert.cxx +23 -20
  372. data/ext/couchbase/core/operations/document_insert.hxx +20 -18
  373. data/ext/couchbase/core/operations/document_lookup_in.cxx +80 -67
  374. data/ext/couchbase/core/operations/document_lookup_in.hxx +31 -27
  375. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +187 -149
  376. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +190 -145
  377. data/ext/couchbase/core/operations/document_mutate_in.cxx +98 -80
  378. data/ext/couchbase/core/operations/document_mutate_in.hxx +38 -33
  379. data/ext/couchbase/core/operations/document_prepend.cxx +18 -15
  380. data/ext/couchbase/core/operations/document_prepend.hxx +18 -16
  381. data/ext/couchbase/core/operations/document_query.cxx +367 -356
  382. data/ext/couchbase/core/operations/document_query.hxx +83 -79
  383. data/ext/couchbase/core/operations/document_remove.cxx +18 -15
  384. data/ext/couchbase/core/operations/document_remove.hxx +18 -16
  385. data/ext/couchbase/core/operations/document_replace.cxx +27 -24
  386. data/ext/couchbase/core/operations/document_replace.hxx +22 -20
  387. data/ext/couchbase/core/operations/document_search.cxx +322 -308
  388. data/ext/couchbase/core/operations/document_search.hxx +125 -121
  389. data/ext/couchbase/core/operations/document_touch.cxx +16 -14
  390. data/ext/couchbase/core/operations/document_touch.hxx +19 -17
  391. data/ext/couchbase/core/operations/document_unlock.cxx +16 -14
  392. data/ext/couchbase/core/operations/document_unlock.hxx +19 -17
  393. data/ext/couchbase/core/operations/document_upsert.cxx +26 -23
  394. data/ext/couchbase/core/operations/document_upsert.hxx +21 -19
  395. data/ext/couchbase/core/operations/document_view.cxx +169 -159
  396. data/ext/couchbase/core/operations/document_view.hxx +68 -65
  397. data/ext/couchbase/core/operations/http_noop.cxx +38 -35
  398. data/ext/couchbase/core/operations/http_noop.hxx +12 -10
  399. data/ext/couchbase/core/operations/management/analytics_dataset_create.cxx +58 -56
  400. data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +20 -17
  401. data/ext/couchbase/core/operations/management/analytics_dataset_drop.cxx +49 -44
  402. data/ext/couchbase/core/operations/management/analytics_dataset_drop.hxx +18 -15
  403. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.cxx +46 -43
  404. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.hxx +16 -13
  405. data/ext/couchbase/core/operations/management/analytics_dataverse_create.cxx +48 -43
  406. data/ext/couchbase/core/operations/management/analytics_dataverse_create.hxx +17 -14
  407. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.cxx +48 -43
  408. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.hxx +17 -14
  409. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.cxx +38 -35
  410. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.hxx +16 -14
  411. data/ext/couchbase/core/operations/management/analytics_index_create.cxx +68 -66
  412. data/ext/couchbase/core/operations/management/analytics_index_create.hxx +20 -17
  413. data/ext/couchbase/core/operations/management/analytics_index_drop.cxx +56 -51
  414. data/ext/couchbase/core/operations/management/analytics_index_drop.hxx +19 -16
  415. data/ext/couchbase/core/operations/management/analytics_index_get_all.cxx +44 -42
  416. data/ext/couchbase/core/operations/management/analytics_index_get_all.hxx +16 -13
  417. data/ext/couchbase/core/operations/management/analytics_link_connect.cxx +49 -43
  418. data/ext/couchbase/core/operations/management/analytics_link_connect.hxx +23 -20
  419. data/ext/couchbase/core/operations/management/analytics_link_create.cxx +52 -51
  420. data/ext/couchbase/core/operations/management/analytics_link_create.hxx +33 -30
  421. data/ext/couchbase/core/operations/management/analytics_link_disconnect.cxx +46 -42
  422. data/ext/couchbase/core/operations/management/analytics_link_disconnect.hxx +22 -19
  423. data/ext/couchbase/core/operations/management/analytics_link_drop.cxx +70 -67
  424. data/ext/couchbase/core/operations/management/analytics_link_drop.hxx +22 -19
  425. data/ext/couchbase/core/operations/management/analytics_link_get_all.cxx +92 -85
  426. data/ext/couchbase/core/operations/management/analytics_link_get_all.hxx +27 -24
  427. data/ext/couchbase/core/operations/management/analytics_link_replace.cxx +52 -51
  428. data/ext/couchbase/core/operations/management/analytics_link_replace.hxx +33 -30
  429. data/ext/couchbase/core/operations/management/analytics_link_utils.hxx +6 -4
  430. data/ext/couchbase/core/operations/management/analytics_problem.hxx +2 -2
  431. data/ext/couchbase/core/operations/management/bucket_create.cxx +158 -149
  432. data/ext/couchbase/core/operations/management/bucket_create.hxx +14 -12
  433. data/ext/couchbase/core/operations/management/bucket_describe.cxx +118 -42
  434. data/ext/couchbase/core/operations/management/bucket_describe.hxx +47 -22
  435. data/ext/couchbase/core/operations/management/bucket_drop.cxx +19 -18
  436. data/ext/couchbase/core/operations/management/bucket_drop.hxx +13 -11
  437. data/ext/couchbase/core/operations/management/bucket_flush.cxx +25 -24
  438. data/ext/couchbase/core/operations/management/bucket_flush.hxx +13 -11
  439. data/ext/couchbase/core/operations/management/bucket_get.cxx +24 -22
  440. data/ext/couchbase/core/operations/management/bucket_get.hxx +14 -12
  441. data/ext/couchbase/core/operations/management/bucket_get_all.cxx +25 -23
  442. data/ext/couchbase/core/operations/management/bucket_get_all.hxx +13 -11
  443. data/ext/couchbase/core/operations/management/bucket_update.cxx +112 -107
  444. data/ext/couchbase/core/operations/management/bucket_update.hxx +15 -13
  445. data/ext/couchbase/core/operations/management/change_password.cxx +22 -20
  446. data/ext/couchbase/core/operations/management/change_password.hxx +13 -11
  447. data/ext/couchbase/core/operations/management/cluster_describe.cxx +52 -50
  448. data/ext/couchbase/core/operations/management/cluster_describe.hxx +31 -29
  449. data/ext/couchbase/core/operations/management/cluster_developer_preview_enable.cxx +14 -12
  450. data/ext/couchbase/core/operations/management/cluster_developer_preview_enable.hxx +13 -11
  451. data/ext/couchbase/core/operations/management/collection_create.cxx +48 -46
  452. data/ext/couchbase/core/operations/management/collection_create.hxx +19 -16
  453. data/ext/couchbase/core/operations/management/collection_drop.cxx +37 -35
  454. data/ext/couchbase/core/operations/management/collection_drop.hxx +16 -14
  455. data/ext/couchbase/core/operations/management/collection_update.cxx +49 -47
  456. data/ext/couchbase/core/operations/management/collection_update.hxx +19 -16
  457. data/ext/couchbase/core/operations/management/collections_manifest_get.cxx +11 -9
  458. data/ext/couchbase/core/operations/management/collections_manifest_get.hxx +17 -13
  459. data/ext/couchbase/core/operations/management/error_utils.cxx +210 -198
  460. data/ext/couchbase/core/operations/management/error_utils.hxx +3 -1
  461. data/ext/couchbase/core/operations/management/eventing_deploy_function.cxx +30 -28
  462. data/ext/couchbase/core/operations/management/eventing_deploy_function.hxx +17 -14
  463. data/ext/couchbase/core/operations/management/eventing_drop_function.cxx +31 -29
  464. data/ext/couchbase/core/operations/management/eventing_drop_function.hxx +17 -14
  465. data/ext/couchbase/core/operations/management/eventing_get_all_functions.cxx +49 -43
  466. data/ext/couchbase/core/operations/management/eventing_get_all_functions.hxx +17 -14
  467. data/ext/couchbase/core/operations/management/eventing_get_function.cxx +29 -27
  468. data/ext/couchbase/core/operations/management/eventing_get_function.hxx +18 -15
  469. data/ext/couchbase/core/operations/management/eventing_get_status.cxx +45 -39
  470. data/ext/couchbase/core/operations/management/eventing_get_status.hxx +17 -14
  471. data/ext/couchbase/core/operations/management/eventing_pause_function.cxx +30 -28
  472. data/ext/couchbase/core/operations/management/eventing_pause_function.hxx +17 -14
  473. data/ext/couchbase/core/operations/management/eventing_problem.hxx +3 -3
  474. data/ext/couchbase/core/operations/management/eventing_resume_function.cxx +30 -28
  475. data/ext/couchbase/core/operations/management/eventing_resume_function.hxx +17 -14
  476. data/ext/couchbase/core/operations/management/eventing_undeploy_function.cxx +30 -28
  477. data/ext/couchbase/core/operations/management/eventing_undeploy_function.hxx +17 -14
  478. data/ext/couchbase/core/operations/management/eventing_upsert_function.cxx +328 -318
  479. data/ext/couchbase/core/operations/management/eventing_upsert_function.hxx +17 -14
  480. data/ext/couchbase/core/operations/management/freeform.cxx +23 -22
  481. data/ext/couchbase/core/operations/management/freeform.hxx +19 -17
  482. data/ext/couchbase/core/operations/management/group_drop.cxx +18 -17
  483. data/ext/couchbase/core/operations/management/group_drop.hxx +13 -11
  484. data/ext/couchbase/core/operations/management/group_get.cxx +25 -23
  485. data/ext/couchbase/core/operations/management/group_get.hxx +14 -12
  486. data/ext/couchbase/core/operations/management/group_get_all.cxx +23 -22
  487. data/ext/couchbase/core/operations/management/group_get_all.hxx +13 -11
  488. data/ext/couchbase/core/operations/management/group_upsert.cxx +58 -55
  489. data/ext/couchbase/core/operations/management/group_upsert.hxx +14 -12
  490. data/ext/couchbase/core/operations/management/query_index_build.cxx +53 -48
  491. data/ext/couchbase/core/operations/management/query_index_build.hxx +25 -22
  492. data/ext/couchbase/core/operations/management/query_index_build_deferred.hxx +75 -67
  493. data/ext/couchbase/core/operations/management/query_index_create.cxx +128 -122
  494. data/ext/couchbase/core/operations/management/query_index_create.hxx +31 -28
  495. data/ext/couchbase/core/operations/management/query_index_drop.cxx +95 -93
  496. data/ext/couchbase/core/operations/management/query_index_drop.hxx +26 -24
  497. data/ext/couchbase/core/operations/management/query_index_get_all.cxx +97 -93
  498. data/ext/couchbase/core/operations/management/query_index_get_all.hxx +24 -21
  499. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.cxx +66 -62
  500. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.hxx +24 -22
  501. data/ext/couchbase/core/operations/management/role_get_all.cxx +24 -22
  502. data/ext/couchbase/core/operations/management/role_get_all.hxx +13 -11
  503. data/ext/couchbase/core/operations/management/scope_create.cxx +38 -36
  504. data/ext/couchbase/core/operations/management/scope_create.hxx +15 -13
  505. data/ext/couchbase/core/operations/management/scope_drop.cxx +33 -32
  506. data/ext/couchbase/core/operations/management/scope_drop.hxx +15 -13
  507. data/ext/couchbase/core/operations/management/scope_get_all.cxx +27 -25
  508. data/ext/couchbase/core/operations/management/scope_get_all.hxx +14 -12
  509. data/ext/couchbase/core/operations/management/search_get_stats.cxx +12 -10
  510. data/ext/couchbase/core/operations/management/search_get_stats.hxx +13 -11
  511. data/ext/couchbase/core/operations/management/search_index_analyze_document.cxx +72 -67
  512. data/ext/couchbase/core/operations/management/search_index_analyze_document.hxx +20 -18
  513. data/ext/couchbase/core/operations/management/search_index_control_ingest.cxx +62 -59
  514. data/ext/couchbase/core/operations/management/search_index_control_ingest.hxx +19 -16
  515. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.cxx +62 -59
  516. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.hxx +19 -17
  517. data/ext/couchbase/core/operations/management/search_index_control_query.cxx +62 -59
  518. data/ext/couchbase/core/operations/management/search_index_control_query.hxx +19 -16
  519. data/ext/couchbase/core/operations/management/search_index_drop.cxx +58 -55
  520. data/ext/couchbase/core/operations/management/search_index_drop.hxx +18 -15
  521. data/ext/couchbase/core/operations/management/search_index_get.cxx +59 -56
  522. data/ext/couchbase/core/operations/management/search_index_get.hxx +18 -16
  523. data/ext/couchbase/core/operations/management/search_index_get_all.cxx +51 -46
  524. data/ext/couchbase/core/operations/management/search_index_get_all.hxx +18 -15
  525. data/ext/couchbase/core/operations/management/search_index_get_documents_count.cxx +66 -61
  526. data/ext/couchbase/core/operations/management/search_index_get_documents_count.hxx +19 -17
  527. data/ext/couchbase/core/operations/management/search_index_get_stats.cxx +38 -36
  528. data/ext/couchbase/core/operations/management/search_index_get_stats.hxx +17 -14
  529. data/ext/couchbase/core/operations/management/search_index_upsert.cxx +98 -95
  530. data/ext/couchbase/core/operations/management/search_index_upsert.hxx +20 -17
  531. data/ext/couchbase/core/operations/management/user_drop.cxx +18 -17
  532. data/ext/couchbase/core/operations/management/user_drop.hxx +16 -12
  533. data/ext/couchbase/core/operations/management/user_get.cxx +25 -23
  534. data/ext/couchbase/core/operations/management/user_get.hxx +17 -13
  535. data/ext/couchbase/core/operations/management/user_get_all.cxx +24 -22
  536. data/ext/couchbase/core/operations/management/user_get_all.hxx +16 -12
  537. data/ext/couchbase/core/operations/management/user_upsert.cxx +63 -60
  538. data/ext/couchbase/core/operations/management/user_upsert.hxx +17 -13
  539. data/ext/couchbase/core/operations/management/view_index_drop.cxx +16 -12
  540. data/ext/couchbase/core/operations/management/view_index_drop.hxx +15 -13
  541. data/ext/couchbase/core/operations/management/view_index_get.cxx +40 -35
  542. data/ext/couchbase/core/operations/management/view_index_get.hxx +16 -14
  543. data/ext/couchbase/core/operations/management/view_index_get_all.cxx +73 -69
  544. data/ext/couchbase/core/operations/management/view_index_get_all.hxx +16 -13
  545. data/ext/couchbase/core/operations/management/view_index_upsert.cxx +39 -35
  546. data/ext/couchbase/core/operations/management/view_index_upsert.hxx +15 -12
  547. data/ext/couchbase/core/origin.cxx +259 -249
  548. data/ext/couchbase/core/origin.hxx +55 -49
  549. data/ext/couchbase/core/pending_operation.hxx +3 -3
  550. data/ext/couchbase/core/ping_collector.hxx +3 -3
  551. data/ext/couchbase/core/ping_options.hxx +30 -30
  552. data/ext/couchbase/core/ping_reporter.hxx +3 -3
  553. data/ext/couchbase/core/platform/backtrace.c +100 -91
  554. data/ext/couchbase/core/platform/base64.cc +135 -134
  555. data/ext/couchbase/core/platform/dirutils.cc +66 -63
  556. data/ext/couchbase/core/platform/random.cc +43 -42
  557. data/ext/couchbase/core/platform/random.h +4 -4
  558. data/ext/couchbase/core/platform/string_hex.cc +42 -40
  559. data/ext/couchbase/core/platform/terminate_handler.cc +54 -52
  560. data/ext/couchbase/core/platform/uuid.cc +47 -47
  561. data/ext/couchbase/core/protocol/client_opcode.hxx +336 -327
  562. data/ext/couchbase/core/protocol/client_opcode_fmt.hxx +291 -291
  563. data/ext/couchbase/core/protocol/client_request.cxx +13 -10
  564. data/ext/couchbase/core/protocol/client_request.hxx +133 -130
  565. data/ext/couchbase/core/protocol/client_response.cxx +40 -40
  566. data/ext/couchbase/core/protocol/client_response.hxx +153 -150
  567. data/ext/couchbase/core/protocol/cmd_append.cxx +24 -23
  568. data/ext/couchbase/core/protocol/cmd_append.hxx +65 -65
  569. data/ext/couchbase/core/protocol/cmd_cluster_map_change_notification.cxx +25 -21
  570. data/ext/couchbase/core/protocol/cmd_cluster_map_change_notification.hxx +33 -25
  571. data/ext/couchbase/core/protocol/cmd_decrement.cxx +38 -38
  572. data/ext/couchbase/core/protocol/cmd_decrement.hxx +87 -87
  573. data/ext/couchbase/core/protocol/cmd_get.cxx +17 -17
  574. data/ext/couchbase/core/protocol/cmd_get.hxx +59 -59
  575. data/ext/couchbase/core/protocol/cmd_get_and_lock.cxx +20 -20
  576. data/ext/couchbase/core/protocol/cmd_get_and_lock.hxx +72 -72
  577. data/ext/couchbase/core/protocol/cmd_get_and_touch.cxx +20 -20
  578. data/ext/couchbase/core/protocol/cmd_get_and_touch.hxx +72 -72
  579. data/ext/couchbase/core/protocol/cmd_get_cluster_config.cxx +46 -39
  580. data/ext/couchbase/core/protocol/cmd_get_cluster_config.hxx +57 -49
  581. data/ext/couchbase/core/protocol/cmd_get_collection_id.cxx +17 -17
  582. data/ext/couchbase/core/protocol/cmd_get_collection_id.hxx +59 -59
  583. data/ext/couchbase/core/protocol/cmd_get_collections_manifest.cxx +16 -14
  584. data/ext/couchbase/core/protocol/cmd_get_collections_manifest.hxx +39 -39
  585. data/ext/couchbase/core/protocol/cmd_get_error_map.cxx +18 -17
  586. data/ext/couchbase/core/protocol/cmd_get_error_map.hxx +62 -62
  587. data/ext/couchbase/core/protocol/cmd_get_meta.cxx +24 -23
  588. data/ext/couchbase/core/protocol/cmd_get_meta.hxx +81 -79
  589. data/ext/couchbase/core/protocol/cmd_get_replica.cxx +23 -23
  590. data/ext/couchbase/core/protocol/cmd_get_replica.hxx +44 -44
  591. data/ext/couchbase/core/protocol/cmd_hello.cxx +28 -27
  592. data/ext/couchbase/core/protocol/cmd_hello.hxx +106 -105
  593. data/ext/couchbase/core/protocol/cmd_increment.cxx +38 -38
  594. data/ext/couchbase/core/protocol/cmd_increment.hxx +87 -87
  595. data/ext/couchbase/core/protocol/cmd_info.hxx +3 -3
  596. data/ext/couchbase/core/protocol/cmd_insert.cxx +27 -27
  597. data/ext/couchbase/core/protocol/cmd_insert.hxx +81 -81
  598. data/ext/couchbase/core/protocol/cmd_lookup_in.cxx +54 -51
  599. data/ext/couchbase/core/protocol/cmd_lookup_in.hxx +90 -90
  600. data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +54 -51
  601. data/ext/couchbase/core/protocol/cmd_lookup_in_replica.hxx +88 -88
  602. data/ext/couchbase/core/protocol/cmd_mutate_in.cxx +105 -97
  603. data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +161 -153
  604. data/ext/couchbase/core/protocol/cmd_noop.cxx +4 -4
  605. data/ext/couchbase/core/protocol/cmd_noop.hxx +32 -32
  606. data/ext/couchbase/core/protocol/cmd_observe_seqno.cxx +36 -34
  607. data/ext/couchbase/core/protocol/cmd_observe_seqno.hxx +89 -89
  608. data/ext/couchbase/core/protocol/cmd_prepend.cxx +22 -22
  609. data/ext/couchbase/core/protocol/cmd_prepend.hxx +63 -63
  610. data/ext/couchbase/core/protocol/cmd_remove.cxx +23 -23
  611. data/ext/couchbase/core/protocol/cmd_remove.hxx +54 -54
  612. data/ext/couchbase/core/protocol/cmd_replace.cxx +28 -28
  613. data/ext/couchbase/core/protocol/cmd_replace.hxx +88 -88
  614. data/ext/couchbase/core/protocol/cmd_sasl_auth.cxx +17 -15
  615. data/ext/couchbase/core/protocol/cmd_sasl_auth.hxx +56 -56
  616. data/ext/couchbase/core/protocol/cmd_sasl_list_mechs.cxx +24 -19
  617. data/ext/couchbase/core/protocol/cmd_sasl_list_mechs.hxx +39 -39
  618. data/ext/couchbase/core/protocol/cmd_sasl_step.cxx +17 -15
  619. data/ext/couchbase/core/protocol/cmd_sasl_step.hxx +56 -56
  620. data/ext/couchbase/core/protocol/cmd_select_bucket.cxx +6 -6
  621. data/ext/couchbase/core/protocol/cmd_select_bucket.hxx +36 -36
  622. data/ext/couchbase/core/protocol/cmd_touch.cxx +8 -8
  623. data/ext/couchbase/core/protocol/cmd_touch.hxx +38 -38
  624. data/ext/couchbase/core/protocol/cmd_unlock.cxx +5 -5
  625. data/ext/couchbase/core/protocol/cmd_unlock.hxx +36 -36
  626. data/ext/couchbase/core/protocol/cmd_upsert.cxx +28 -28
  627. data/ext/couchbase/core/protocol/cmd_upsert.hxx +83 -83
  628. data/ext/couchbase/core/protocol/datatype.hxx +19 -18
  629. data/ext/couchbase/core/protocol/frame_info_id.hxx +108 -103
  630. data/ext/couchbase/core/protocol/frame_info_id_fmt.hxx +45 -45
  631. data/ext/couchbase/core/protocol/frame_info_utils.cxx +24 -21
  632. data/ext/couchbase/core/protocol/frame_info_utils.hxx +3 -1
  633. data/ext/couchbase/core/protocol/hello_feature.hxx +211 -175
  634. data/ext/couchbase/core/protocol/hello_feature_fmt.hxx +93 -90
  635. data/ext/couchbase/core/protocol/magic.hxx +24 -24
  636. data/ext/couchbase/core/protocol/magic_fmt.hxx +30 -30
  637. data/ext/couchbase/core/protocol/server_opcode.hxx +11 -11
  638. data/ext/couchbase/core/protocol/server_opcode_fmt.hxx +18 -18
  639. data/ext/couchbase/core/protocol/server_request.hxx +90 -86
  640. data/ext/couchbase/core/protocol/status.cxx +138 -138
  641. data/ext/couchbase/core/protocol/status.hxx +86 -86
  642. data/ext/couchbase/core/query_context.hxx +44 -43
  643. data/ext/couchbase/core/range_scan_load_balancer.cxx +51 -50
  644. data/ext/couchbase/core/range_scan_load_balancer.hxx +26 -25
  645. data/ext/couchbase/core/range_scan_options.cxx +2 -2
  646. data/ext/couchbase/core/range_scan_options.hxx +62 -59
  647. data/ext/couchbase/core/range_scan_orchestrator.cxx +515 -470
  648. data/ext/couchbase/core/range_scan_orchestrator.hxx +23 -18
  649. data/ext/couchbase/core/range_scan_orchestrator_options.hxx +10 -10
  650. data/ext/couchbase/core/resource_units.hxx +2 -2
  651. data/ext/couchbase/core/response_handler.hxx +8 -8
  652. data/ext/couchbase/core/retry_orchestrator.cxx +27 -19
  653. data/ext/couchbase/core/retry_orchestrator.hxx +3 -2
  654. data/ext/couchbase/core/sasl/client.cc +22 -18
  655. data/ext/couchbase/core/sasl/client.h +66 -62
  656. data/ext/couchbase/core/sasl/context.cc +4 -4
  657. data/ext/couchbase/core/sasl/context.h +19 -19
  658. data/ext/couchbase/core/sasl/error.h +12 -1
  659. data/ext/couchbase/core/sasl/error_fmt.h +42 -42
  660. data/ext/couchbase/core/sasl/mechanism.cc +13 -10
  661. data/ext/couchbase/core/sasl/mechanism.h +8 -3
  662. data/ext/couchbase/core/sasl/plain/plain.cc +8 -8
  663. data/ext/couchbase/core/sasl/plain/plain.h +25 -24
  664. data/ext/couchbase/core/sasl/scram-sha/scram-sha.cc +225 -218
  665. data/ext/couchbase/core/sasl/scram-sha/scram-sha.h +133 -115
  666. data/ext/couchbase/core/sasl/scram-sha/stringutils.cc +20 -20
  667. data/ext/couchbase/core/scan_result.cxx +38 -38
  668. data/ext/couchbase/core/scan_result.hxx +16 -16
  669. data/ext/couchbase/core/search_highlight_style.hxx +4 -1
  670. data/ext/couchbase/core/search_query_options.cxx +21 -21
  671. data/ext/couchbase/core/search_query_options.hxx +19 -18
  672. data/ext/couchbase/core/search_scan_consistency.hxx +3 -1
  673. data/ext/couchbase/core/seed_config.cxx +10 -7
  674. data/ext/couchbase/core/seed_config.hxx +8 -8
  675. data/ext/couchbase/core/service_type.hxx +7 -7
  676. data/ext/couchbase/core/service_type_fmt.hxx +33 -33
  677. data/ext/couchbase/core/stats_options.hxx +13 -13
  678. data/ext/couchbase/core/subdoc_options.hxx +60 -58
  679. data/ext/couchbase/core/tls_verify_mode.hxx +2 -2
  680. data/ext/couchbase/core/topology/capabilities.hxx +83 -83
  681. data/ext/couchbase/core/topology/capabilities_fmt.hxx +111 -111
  682. data/ext/couchbase/core/topology/collections_manifest.hxx +14 -14
  683. data/ext/couchbase/core/topology/collections_manifest_fmt.hxx +23 -21
  684. data/ext/couchbase/core/topology/collections_manifest_json.hxx +26 -25
  685. data/ext/couchbase/core/topology/configuration.cxx +213 -192
  686. data/ext/couchbase/core/topology/configuration.hxx +104 -91
  687. data/ext/couchbase/core/topology/configuration_fmt.hxx +131 -128
  688. data/ext/couchbase/core/topology/configuration_json.hxx +276 -242
  689. data/ext/couchbase/core/topology/error_map.hxx +5 -5
  690. data/ext/couchbase/core/topology/error_map_json.hxx +65 -60
  691. data/ext/couchbase/core/tracing/constants.hxx +153 -153
  692. data/ext/couchbase/core/tracing/noop_tracer.hxx +29 -28
  693. data/ext/couchbase/core/tracing/threshold_logging_options.hxx +30 -30
  694. data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +354 -344
  695. data/ext/couchbase/core/tracing/threshold_logging_tracer.hxx +12 -12
  696. data/ext/couchbase/core/transactions/active_transaction_record.cxx +153 -33
  697. data/ext/couchbase/core/transactions/active_transaction_record.hxx +30 -118
  698. data/ext/couchbase/core/transactions/async_attempt_context.cxx +8 -2
  699. data/ext/couchbase/core/transactions/async_attempt_context.hxx +163 -127
  700. data/ext/couchbase/core/transactions/atr_cleanup_entry.cxx +358 -334
  701. data/ext/couchbase/core/transactions/atr_ids.cxx +270 -185
  702. data/ext/couchbase/core/transactions/atr_ids.hxx +4 -4
  703. data/ext/couchbase/core/transactions/attempt_context.cxx +9 -5
  704. data/ext/couchbase/core/transactions/attempt_context.hxx +194 -154
  705. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +3278 -2159
  706. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +446 -573
  707. data/ext/couchbase/core/transactions/attempt_context_testing_hooks.cxx +15 -10
  708. data/ext/couchbase/core/transactions/attempt_context_testing_hooks.hxx +58 -49
  709. data/ext/couchbase/core/transactions/attempt_state.hxx +72 -72
  710. data/ext/couchbase/core/transactions/binary.cxx +3 -3
  711. data/ext/couchbase/core/transactions/cleanup_testing_hooks.cxx +2 -2
  712. data/ext/couchbase/core/transactions/cleanup_testing_hooks.hxx +28 -24
  713. data/ext/couchbase/core/transactions/document_metadata.hxx +68 -68
  714. data/ext/couchbase/core/transactions/durability_level.hxx +53 -53
  715. data/ext/couchbase/core/transactions/error_class.hxx +12 -12
  716. data/ext/couchbase/core/transactions/error_list.hxx +22 -22
  717. data/ext/couchbase/core/transactions/exceptions.cxx +167 -114
  718. data/ext/couchbase/core/transactions/exceptions.hxx +170 -139
  719. data/ext/couchbase/core/transactions/exceptions_fmt.hxx +105 -0
  720. data/ext/couchbase/core/transactions/forward_compat.cxx +220 -0
  721. data/ext/couchbase/core/transactions/forward_compat.hxx +63 -207
  722. data/ext/couchbase/core/transactions/internal/atr_cleanup_entry.hxx +110 -102
  723. data/ext/couchbase/core/transactions/internal/atr_entry.hxx +144 -144
  724. data/ext/couchbase/core/transactions/internal/client_record.hxx +53 -50
  725. data/ext/couchbase/core/transactions/internal/doc_record.cxx +5 -5
  726. data/ext/couchbase/core/transactions/internal/doc_record.hxx +38 -35
  727. data/ext/couchbase/core/transactions/internal/doc_record_fmt.hxx +17 -16
  728. data/ext/couchbase/core/transactions/internal/exceptions_internal.hxx +238 -281
  729. data/ext/couchbase/core/transactions/internal/exceptions_internal_fmt.hxx +103 -0
  730. data/ext/couchbase/core/transactions/internal/logging.hxx +52 -29
  731. data/ext/couchbase/core/transactions/internal/transaction_attempt.hxx +3 -3
  732. data/ext/couchbase/core/transactions/internal/transaction_context.hxx +136 -120
  733. data/ext/couchbase/core/transactions/internal/transaction_fields.hxx +2 -1
  734. data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +127 -122
  735. data/ext/couchbase/core/transactions/internal/utils.hxx +244 -219
  736. data/ext/couchbase/core/transactions/result.cxx +41 -40
  737. data/ext/couchbase/core/transactions/result.hxx +143 -141
  738. data/ext/couchbase/core/transactions/result_fmt.hxx +21 -20
  739. data/ext/couchbase/core/transactions/staged_mutation.cxx +759 -627
  740. data/ext/couchbase/core/transactions/staged_mutation.hxx +175 -156
  741. data/ext/couchbase/core/transactions/transaction_context.cxx +231 -179
  742. data/ext/couchbase/core/transactions/transaction_get_result.cxx +185 -198
  743. data/ext/couchbase/core/transactions/transaction_get_result.hxx +207 -222
  744. data/ext/couchbase/core/transactions/transaction_keyspace.cxx +15 -11
  745. data/ext/couchbase/core/transactions/transaction_links.cxx +11 -7
  746. data/ext/couchbase/core/transactions/transaction_links.hxx +222 -201
  747. data/ext/couchbase/core/transactions/transaction_options.cxx +44 -41
  748. data/ext/couchbase/core/transactions/transactions.cxx +167 -125
  749. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +491 -424
  750. data/ext/couchbase/core/transactions/transactions_config.cxx +25 -19
  751. data/ext/couchbase/core/transactions/uid_generator.cxx +3 -3
  752. data/ext/couchbase/core/transactions/uid_generator.hxx +2 -2
  753. data/ext/couchbase/core/transactions/utils.cxx +82 -69
  754. data/ext/couchbase/core/transactions/waitable_op_list.hxx +154 -140
  755. data/ext/couchbase/core/transactions.hxx +184 -180
  756. data/ext/couchbase/core/utils/binary.cxx +3 -3
  757. data/ext/couchbase/core/utils/binary.hxx +19 -15
  758. data/ext/couchbase/core/utils/byteswap.hxx +17 -17
  759. data/ext/couchbase/core/utils/connection_string.cxx +395 -328
  760. data/ext/couchbase/core/utils/connection_string.hxx +37 -36
  761. data/ext/couchbase/core/utils/crc32.hxx +42 -34
  762. data/ext/couchbase/core/utils/duration_parser.cxx +142 -133
  763. data/ext/couchbase/core/utils/duration_parser.hxx +9 -9
  764. data/ext/couchbase/core/utils/join_strings.hxx +24 -24
  765. data/ext/couchbase/core/utils/json.cxx +234 -228
  766. data/ext/couchbase/core/utils/json.hxx +12 -12
  767. data/ext/couchbase/core/utils/json_stream_control.hxx +8 -8
  768. data/ext/couchbase/core/utils/json_streaming_lexer.cxx +288 -263
  769. data/ext/couchbase/core/utils/json_streaming_lexer.hxx +20 -17
  770. data/ext/couchbase/core/utils/keyspace.hxx +22 -21
  771. data/ext/couchbase/core/utils/movable_function.hxx +78 -76
  772. data/ext/couchbase/core/utils/mutation_token.cxx +7 -3
  773. data/ext/couchbase/core/utils/mutation_token.hxx +3 -1
  774. data/ext/couchbase/core/utils/name_codec.hxx +13 -13
  775. data/ext/couchbase/core/utils/split_string.cxx +9 -9
  776. data/ext/couchbase/core/utils/split_string.hxx +2 -2
  777. data/ext/couchbase/core/utils/unsigned_leb128.hxx +92 -88
  778. data/ext/couchbase/core/utils/url_codec.cxx +301 -297
  779. data/ext/couchbase/core/utils/url_codec.hxx +35 -35
  780. data/ext/couchbase/core/vector_query_combination.hxx +4 -1
  781. data/ext/couchbase/core/view_on_error.hxx +4 -3
  782. data/ext/couchbase/core/view_query_options.cxx +21 -21
  783. data/ext/couchbase/core/view_query_options.hxx +23 -22
  784. data/ext/couchbase/core/view_scan_consistency.hxx +3 -3
  785. data/ext/couchbase/core/view_sort_order.hxx +4 -1
  786. data/ext/couchbase/core/wait_until_ready_options.hxx +11 -10
  787. data/ext/couchbase/couchbase/allow_querying_search_index_options.hxx +11 -11
  788. data/ext/couchbase/couchbase/analytics_index_manager.hxx +423 -405
  789. data/ext/couchbase/couchbase/analytics_meta_data.hxx +105 -105
  790. data/ext/couchbase/couchbase/analytics_metrics.hxx +120 -118
  791. data/ext/couchbase/couchbase/analytics_options.hxx +318 -292
  792. data/ext/couchbase/couchbase/analytics_result.hxx +56 -55
  793. data/ext/couchbase/couchbase/analytics_scan_consistency.hxx +24 -21
  794. data/ext/couchbase/couchbase/analytics_status.hxx +10 -10
  795. data/ext/couchbase/couchbase/analytics_warning.hxx +44 -43
  796. data/ext/couchbase/couchbase/analyze_document_options.hxx +9 -9
  797. data/ext/couchbase/couchbase/append_options.hxx +51 -47
  798. data/ext/couchbase/couchbase/behavior_options.hxx +75 -69
  799. data/ext/couchbase/couchbase/best_effort_retry_strategy.hxx +12 -10
  800. data/ext/couchbase/couchbase/binary_collection.hxx +213 -183
  801. data/ext/couchbase/couchbase/boolean_field_query.hxx +38 -38
  802. data/ext/couchbase/couchbase/boolean_query.hxx +166 -157
  803. data/ext/couchbase/couchbase/bucket.hxx +69 -68
  804. data/ext/couchbase/couchbase/bucket_manager.hxx +97 -88
  805. data/ext/couchbase/couchbase/build_query_index_options.hxx +22 -21
  806. data/ext/couchbase/couchbase/cas.hxx +74 -73
  807. data/ext/couchbase/couchbase/certificate_authenticator.hxx +10 -10
  808. data/ext/couchbase/couchbase/cluster.hxx +266 -310
  809. data/ext/couchbase/couchbase/cluster_options.hxx +235 -241
  810. data/ext/couchbase/couchbase/codec/binary_noop_serializer.hxx +11 -11
  811. data/ext/couchbase/couchbase/codec/codec_flags.hxx +39 -35
  812. data/ext/couchbase/couchbase/codec/encoded_value.hxx +15 -2
  813. data/ext/couchbase/couchbase/codec/json_transcoder.hxx +17 -15
  814. data/ext/couchbase/couchbase/codec/raw_binary_transcoder.hxx +19 -17
  815. data/ext/couchbase/couchbase/codec/raw_json_transcoder.hxx +31 -24
  816. data/ext/couchbase/couchbase/codec/raw_string_transcoder.hxx +20 -18
  817. data/ext/couchbase/couchbase/codec/tao_json_serializer.hxx +38 -30
  818. data/ext/couchbase/couchbase/collection.hxx +1007 -902
  819. data/ext/couchbase/couchbase/collection_manager.hxx +115 -107
  820. data/ext/couchbase/couchbase/collection_query_index_manager.hxx +200 -188
  821. data/ext/couchbase/couchbase/common_durability_options.hxx +68 -62
  822. data/ext/couchbase/couchbase/common_options.hxx +67 -67
  823. data/ext/couchbase/couchbase/compression_options.hxx +33 -33
  824. data/ext/couchbase/couchbase/configuration_profile.hxx +12 -11
  825. data/ext/couchbase/couchbase/configuration_profiles_registry.hxx +24 -22
  826. data/ext/couchbase/couchbase/conjunction_query.hxx +47 -45
  827. data/ext/couchbase/couchbase/connect_link_analytics_options.hxx +74 -72
  828. data/ext/couchbase/couchbase/counter_result.hxx +32 -32
  829. data/ext/couchbase/couchbase/create_bucket_options.hxx +9 -10
  830. data/ext/couchbase/couchbase/create_collection_options.hxx +35 -34
  831. data/ext/couchbase/couchbase/create_dataset_analytics_options.hxx +76 -76
  832. data/ext/couchbase/couchbase/create_dataverse_analytics_options.hxx +44 -44
  833. data/ext/couchbase/couchbase/create_index_analytics_options.hxx +60 -60
  834. data/ext/couchbase/couchbase/create_link_analytics_options.hxx +25 -25
  835. data/ext/couchbase/couchbase/create_primary_query_index_options.hxx +95 -94
  836. data/ext/couchbase/couchbase/create_query_index_options.hxx +97 -96
  837. data/ext/couchbase/couchbase/create_scope_options.hxx +9 -9
  838. data/ext/couchbase/couchbase/date_range.hxx +29 -27
  839. data/ext/couchbase/couchbase/date_range_facet.hxx +20 -20
  840. data/ext/couchbase/couchbase/date_range_facet_result.hxx +14 -14
  841. data/ext/couchbase/couchbase/date_range_query.hxx +219 -205
  842. data/ext/couchbase/couchbase/decrement_options.hxx +93 -91
  843. data/ext/couchbase/couchbase/diagnostics_options.hxx +42 -41
  844. data/ext/couchbase/couchbase/diagnostics_result.hxx +82 -83
  845. data/ext/couchbase/couchbase/disallow_querying_search_index_options.hxx +11 -10
  846. data/ext/couchbase/couchbase/disconnect_link_analytics_options.hxx +62 -62
  847. data/ext/couchbase/couchbase/disjunction_query.hxx +61 -60
  848. data/ext/couchbase/couchbase/dns_options.hxx +30 -30
  849. data/ext/couchbase/couchbase/doc_id_query.hxx +69 -69
  850. data/ext/couchbase/couchbase/drop_bucket_options.hxx +9 -9
  851. data/ext/couchbase/couchbase/drop_collection_options.hxx +9 -9
  852. data/ext/couchbase/couchbase/drop_dataset_analytics_options.hxx +60 -60
  853. data/ext/couchbase/couchbase/drop_dataverse_analytics_options.hxx +44 -44
  854. data/ext/couchbase/couchbase/drop_index_analytics_options.hxx +60 -60
  855. data/ext/couchbase/couchbase/drop_link_analytics_options.hxx +25 -25
  856. data/ext/couchbase/couchbase/drop_primary_query_index_options.hxx +58 -58
  857. data/ext/couchbase/couchbase/drop_query_index_options.hxx +44 -44
  858. data/ext/couchbase/couchbase/drop_scope_options.hxx +9 -9
  859. data/ext/couchbase/couchbase/drop_search_index_options.hxx +9 -9
  860. data/ext/couchbase/couchbase/durability_level.hxx +32 -29
  861. data/ext/couchbase/couchbase/endpoint_diagnostics.hxx +171 -171
  862. data/ext/couchbase/couchbase/endpoint_ping_report.hxx +166 -169
  863. data/ext/couchbase/couchbase/error.hxx +51 -0
  864. data/ext/couchbase/couchbase/error_codes.hxx +975 -940
  865. data/ext/couchbase/couchbase/error_context.hxx +19 -152
  866. data/ext/couchbase/couchbase/exists_options.hxx +25 -24
  867. data/ext/couchbase/couchbase/exists_result.hxx +32 -32
  868. data/ext/couchbase/couchbase/fail_fast_retry_strategy.hxx +4 -4
  869. data/ext/couchbase/couchbase/flush_bucket_options.hxx +9 -9
  870. data/ext/couchbase/couchbase/fmt/analytics_scan_consistency.hxx +18 -18
  871. data/ext/couchbase/couchbase/fmt/analytics_status.hxx +42 -42
  872. data/ext/couchbase/couchbase/fmt/cas.hxx +10 -10
  873. data/ext/couchbase/couchbase/fmt/durability_level.hxx +24 -24
  874. data/ext/couchbase/couchbase/fmt/error.hxx +53 -0
  875. data/ext/couchbase/couchbase/fmt/error_context.hxx +43 -0
  876. data/ext/couchbase/couchbase/fmt/mutation_token.hxx +15 -11
  877. data/ext/couchbase/couchbase/fmt/query_profile.hxx +21 -21
  878. data/ext/couchbase/couchbase/fmt/query_scan_consistency.hxx +18 -18
  879. data/ext/couchbase/couchbase/fmt/query_status.hxx +42 -42
  880. data/ext/couchbase/couchbase/fmt/retry_reason.hxx +75 -75
  881. data/ext/couchbase/couchbase/fmt/search_scan_consistency.hxx +15 -15
  882. data/ext/couchbase/couchbase/fmt/tls_verify_mode.hxx +18 -18
  883. data/ext/couchbase/couchbase/fmt/transaction_keyspace.hxx +15 -11
  884. data/ext/couchbase/couchbase/fork_event.hxx +12 -12
  885. data/ext/couchbase/couchbase/freeze_plan_search_index_options.hxx +9 -9
  886. data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +71 -64
  887. data/ext/couchbase/couchbase/geo_distance_query.hxx +73 -66
  888. data/ext/couchbase/couchbase/geo_point.hxx +2 -2
  889. data/ext/couchbase/couchbase/geo_polygon_query.hxx +40 -39
  890. data/ext/couchbase/couchbase/get_all_buckets_options.hxx +9 -9
  891. data/ext/couchbase/couchbase/get_all_datasets_analytics_options.hxx +25 -25
  892. data/ext/couchbase/couchbase/get_all_indexes_analytics_options.hxx +26 -25
  893. data/ext/couchbase/couchbase/get_all_query_indexes_options.hxx +27 -25
  894. data/ext/couchbase/couchbase/get_all_replicas_options.hxx +49 -26
  895. data/ext/couchbase/couchbase/get_all_scopes_options.hxx +9 -9
  896. data/ext/couchbase/couchbase/get_all_search_indexes_options.hxx +9 -9
  897. data/ext/couchbase/couchbase/get_and_lock_options.hxx +25 -24
  898. data/ext/couchbase/couchbase/get_and_touch_options.hxx +25 -24
  899. data/ext/couchbase/couchbase/get_any_replica_options.hxx +49 -26
  900. data/ext/couchbase/couchbase/get_bucket_options.hxx +9 -9
  901. data/ext/couchbase/couchbase/get_indexed_search_index_options.hxx +9 -9
  902. data/ext/couchbase/couchbase/get_links_analytics_options.hxx +74 -74
  903. data/ext/couchbase/couchbase/get_options.hxx +63 -60
  904. data/ext/couchbase/couchbase/get_pending_mutations_analytics_options.hxx +30 -28
  905. data/ext/couchbase/couchbase/get_replica_result.hxx +79 -75
  906. data/ext/couchbase/couchbase/get_result.hxx +86 -80
  907. data/ext/couchbase/couchbase/get_search_index_options.hxx +9 -9
  908. data/ext/couchbase/couchbase/highlight_style.hxx +14 -14
  909. data/ext/couchbase/couchbase/increment_options.hxx +94 -91
  910. data/ext/couchbase/couchbase/insert_options.hxx +62 -59
  911. data/ext/couchbase/couchbase/ip_protocol.hxx +3 -3
  912. data/ext/couchbase/couchbase/logger.hxx +51 -0
  913. data/ext/couchbase/couchbase/lookup_in_all_replicas_options.hxx +54 -43
  914. data/ext/couchbase/couchbase/lookup_in_any_replica_options.hxx +54 -44
  915. data/ext/couchbase/couchbase/lookup_in_options.hxx +40 -40
  916. data/ext/couchbase/couchbase/lookup_in_replica_result.hxx +38 -35
  917. data/ext/couchbase/couchbase/lookup_in_result.hxx +222 -216
  918. data/ext/couchbase/couchbase/lookup_in_specs.hxx +101 -101
  919. data/ext/couchbase/couchbase/management/analytics_dataset.hxx +16 -16
  920. data/ext/couchbase/couchbase/management/analytics_index.hxx +16 -16
  921. data/ext/couchbase/couchbase/management/analytics_link.hxx +193 -189
  922. data/ext/couchbase/couchbase/management/bucket_settings.hxx +91 -75
  923. data/ext/couchbase/couchbase/management/collection_spec.hxx +4 -4
  924. data/ext/couchbase/couchbase/management/query_index.hxx +10 -10
  925. data/ext/couchbase/couchbase/management/scope_spec.hxx +2 -2
  926. data/ext/couchbase/couchbase/management/search_index.hxx +9 -9
  927. data/ext/couchbase/couchbase/match_all_query.hxx +10 -9
  928. data/ext/couchbase/couchbase/match_none_query.hxx +10 -9
  929. data/ext/couchbase/couchbase/match_operator.hxx +15 -14
  930. data/ext/couchbase/couchbase/match_phrase_query.hxx +70 -65
  931. data/ext/couchbase/couchbase/match_query.hxx +115 -114
  932. data/ext/couchbase/couchbase/metrics/meter.hxx +33 -30
  933. data/ext/couchbase/couchbase/metrics/otel_meter.hxx +86 -74
  934. data/ext/couchbase/couchbase/metrics_options.hxx +34 -34
  935. data/ext/couchbase/couchbase/mutate_in_options.hxx +160 -149
  936. data/ext/couchbase/couchbase/mutate_in_result.hxx +130 -123
  937. data/ext/couchbase/couchbase/mutate_in_specs.hxx +473 -454
  938. data/ext/couchbase/couchbase/mutation_result.hxx +32 -32
  939. data/ext/couchbase/couchbase/mutation_state.hxx +35 -34
  940. data/ext/couchbase/couchbase/mutation_token.hxx +78 -78
  941. data/ext/couchbase/couchbase/network_options.hxx +101 -72
  942. data/ext/couchbase/couchbase/numeric_range.hxx +26 -26
  943. data/ext/couchbase/couchbase/numeric_range_facet.hxx +20 -20
  944. data/ext/couchbase/couchbase/numeric_range_facet_result.hxx +14 -14
  945. data/ext/couchbase/couchbase/numeric_range_query.hxx +97 -95
  946. data/ext/couchbase/couchbase/password_authenticator.hxx +17 -17
  947. data/ext/couchbase/couchbase/pause_ingest_search_index_options.hxx +11 -10
  948. data/ext/couchbase/couchbase/persist_to.hxx +45 -44
  949. data/ext/couchbase/couchbase/phrase_query.hxx +69 -65
  950. data/ext/couchbase/couchbase/ping_options.hxx +55 -54
  951. data/ext/couchbase/couchbase/ping_result.hxx +79 -77
  952. data/ext/couchbase/couchbase/prefix_query.hxx +43 -40
  953. data/ext/couchbase/couchbase/prepend_options.hxx +51 -47
  954. data/ext/couchbase/couchbase/query_index_manager.hxx +207 -199
  955. data/ext/couchbase/couchbase/query_meta_data.hxx +120 -120
  956. data/ext/couchbase/couchbase/query_metrics.hxx +135 -133
  957. data/ext/couchbase/couchbase/query_options.hxx +518 -493
  958. data/ext/couchbase/couchbase/query_profile.hxx +29 -26
  959. data/ext/couchbase/couchbase/query_result.hxx +56 -55
  960. data/ext/couchbase/couchbase/query_scan_consistency.hxx +24 -21
  961. data/ext/couchbase/couchbase/query_status.hxx +10 -10
  962. data/ext/couchbase/couchbase/query_string_query.hxx +34 -29
  963. data/ext/couchbase/couchbase/query_warning.hxx +75 -71
  964. data/ext/couchbase/couchbase/read_preference.hxx +58 -0
  965. data/ext/couchbase/couchbase/regexp_query.hxx +40 -39
  966. data/ext/couchbase/couchbase/remove_options.hxx +51 -47
  967. data/ext/couchbase/couchbase/replace_link_analytics_options.hxx +25 -25
  968. data/ext/couchbase/couchbase/replace_options.hxx +112 -104
  969. data/ext/couchbase/couchbase/replicate_to.hxx +28 -28
  970. data/ext/couchbase/couchbase/result.hxx +28 -28
  971. data/ext/couchbase/couchbase/resume_ingest_search_index_options.hxx +11 -10
  972. data/ext/couchbase/couchbase/retry_action.hxx +10 -10
  973. data/ext/couchbase/couchbase/retry_reason.hxx +53 -51
  974. data/ext/couchbase/couchbase/retry_request.hxx +7 -7
  975. data/ext/couchbase/couchbase/retry_strategy.hxx +4 -4
  976. data/ext/couchbase/couchbase/scan_options.hxx +114 -108
  977. data/ext/couchbase/couchbase/scan_result.hxx +97 -96
  978. data/ext/couchbase/couchbase/scan_result_item.hxx +120 -118
  979. data/ext/couchbase/couchbase/scan_type.hxx +237 -232
  980. data/ext/couchbase/couchbase/scope.hxx +164 -157
  981. data/ext/couchbase/couchbase/scope_search_index_manager.hxx +263 -238
  982. data/ext/couchbase/couchbase/search_date_range.hxx +32 -29
  983. data/ext/couchbase/couchbase/search_facet.hxx +25 -25
  984. data/ext/couchbase/couchbase/search_facet_result.hxx +11 -11
  985. data/ext/couchbase/couchbase/search_geo_distance_units.hxx +11 -1
  986. data/ext/couchbase/couchbase/search_index_manager.hxx +261 -238
  987. data/ext/couchbase/couchbase/search_meta_data.hxx +37 -37
  988. data/ext/couchbase/couchbase/search_metrics.hxx +84 -83
  989. data/ext/couchbase/couchbase/search_numeric_range.hxx +32 -32
  990. data/ext/couchbase/couchbase/search_options.hxx +449 -435
  991. data/ext/couchbase/couchbase/search_query.hxx +32 -30
  992. data/ext/couchbase/couchbase/search_request.hxx +69 -68
  993. data/ext/couchbase/couchbase/search_result.hxx +29 -26
  994. data/ext/couchbase/couchbase/search_row.hxx +52 -52
  995. data/ext/couchbase/couchbase/search_row_location.hxx +20 -20
  996. data/ext/couchbase/couchbase/search_row_locations.hxx +39 -38
  997. data/ext/couchbase/couchbase/search_scan_consistency.hxx +11 -10
  998. data/ext/couchbase/couchbase/search_sort.hxx +20 -20
  999. data/ext/couchbase/couchbase/search_sort_field.hxx +77 -71
  1000. data/ext/couchbase/couchbase/search_sort_field_missing.hxx +2 -2
  1001. data/ext/couchbase/couchbase/search_sort_field_mode.hxx +3 -3
  1002. data/ext/couchbase/couchbase/search_sort_field_type.hxx +4 -4
  1003. data/ext/couchbase/couchbase/search_sort_geo_distance.hxx +41 -41
  1004. data/ext/couchbase/couchbase/search_sort_id.hxx +23 -23
  1005. data/ext/couchbase/couchbase/search_sort_score.hxx +23 -23
  1006. data/ext/couchbase/couchbase/search_term_range.hxx +17 -17
  1007. data/ext/couchbase/couchbase/security_options.hxx +50 -50
  1008. data/ext/couchbase/couchbase/service_type.hxx +34 -34
  1009. data/ext/couchbase/couchbase/store_semantics.hxx +28 -28
  1010. data/ext/couchbase/couchbase/subdoc/array_add_unique.hxx +54 -54
  1011. data/ext/couchbase/couchbase/subdoc/array_append.hxx +40 -40
  1012. data/ext/couchbase/couchbase/subdoc/array_insert.hxx +41 -41
  1013. data/ext/couchbase/couchbase/subdoc/array_prepend.hxx +41 -41
  1014. data/ext/couchbase/couchbase/subdoc/count.hxx +24 -24
  1015. data/ext/couchbase/couchbase/subdoc/counter.hxx +41 -41
  1016. data/ext/couchbase/couchbase/subdoc/exists.hxx +24 -24
  1017. data/ext/couchbase/couchbase/subdoc/get.hxx +45 -29
  1018. data/ext/couchbase/couchbase/subdoc/insert.hxx +70 -54
  1019. data/ext/couchbase/couchbase/subdoc/lookup_in_macro.hxx +13 -12
  1020. data/ext/couchbase/couchbase/subdoc/mutate_in_macro.hxx +7 -2
  1021. data/ext/couchbase/couchbase/subdoc/remove.hxx +24 -24
  1022. data/ext/couchbase/couchbase/subdoc/replace.hxx +55 -39
  1023. data/ext/couchbase/couchbase/subdoc/upsert.hxx +70 -54
  1024. data/ext/couchbase/couchbase/term_facet.hxx +16 -16
  1025. data/ext/couchbase/couchbase/term_facet_result.hxx +14 -14
  1026. data/ext/couchbase/couchbase/term_query.hxx +107 -104
  1027. data/ext/couchbase/couchbase/term_range_query.hxx +99 -96
  1028. data/ext/couchbase/couchbase/timeout_options.hxx +118 -112
  1029. data/ext/couchbase/couchbase/tls_verify_mode.hxx +2 -2
  1030. data/ext/couchbase/couchbase/touch_options.hxx +25 -24
  1031. data/ext/couchbase/couchbase/tracing/otel_tracer.hxx +45 -44
  1032. data/ext/couchbase/couchbase/tracing/request_span.hxx +34 -34
  1033. data/ext/couchbase/couchbase/tracing/request_tracer.hxx +27 -25
  1034. data/ext/couchbase/couchbase/tracing_options.hxx +147 -142
  1035. data/ext/couchbase/couchbase/transactions/async_attempt_context.hxx +149 -115
  1036. data/ext/couchbase/couchbase/transactions/attempt_context.hxx +146 -95
  1037. data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +52 -80
  1038. data/ext/couchbase/couchbase/transactions/transaction_keyspace.hxx +33 -29
  1039. data/ext/couchbase/couchbase/transactions/transaction_options.hxx +101 -96
  1040. data/ext/couchbase/couchbase/transactions/transaction_query_options.hxx +228 -223
  1041. data/ext/couchbase/couchbase/transactions/transaction_query_result.hxx +11 -12
  1042. data/ext/couchbase/couchbase/transactions/transaction_result.hxx +2 -3
  1043. data/ext/couchbase/couchbase/transactions/transactions_cleanup_config.hxx +105 -104
  1044. data/ext/couchbase/couchbase/transactions/transactions_config.hxx +191 -187
  1045. data/ext/couchbase/couchbase/transactions/transactions_query_config.hxx +32 -32
  1046. data/ext/couchbase/couchbase/transactions.hxx +56 -37
  1047. data/ext/couchbase/couchbase/unfreeze_plan_search_index_options.hxx +11 -10
  1048. data/ext/couchbase/couchbase/unlock_options.hxx +25 -24
  1049. data/ext/couchbase/couchbase/update_bucket_options.hxx +9 -9
  1050. data/ext/couchbase/couchbase/update_collection_options.hxx +35 -34
  1051. data/ext/couchbase/couchbase/upsert_options.hxx +85 -80
  1052. data/ext/couchbase/couchbase/upsert_search_index_options.hxx +9 -9
  1053. data/ext/couchbase/couchbase/vector_query.hxx +82 -62
  1054. data/ext/couchbase/couchbase/vector_search.hxx +51 -47
  1055. data/ext/couchbase/couchbase/vector_search_options.hxx +45 -41
  1056. data/ext/couchbase/couchbase/wan_development_configuration_profile.hxx +13 -13
  1057. data/ext/couchbase/couchbase/watch_query_indexes_options.hxx +41 -41
  1058. data/ext/couchbase/couchbase/wildcard_query.hxx +42 -41
  1059. data/ext/couchbase/third_party/expected/include/tl/expected.hpp +1746 -1584
  1060. data/ext/couchbase/third_party/jsonsl/jsonsl.c +2664 -2638
  1061. data/ext/couchbase/third_party/jsonsl/jsonsl.h +359 -342
  1062. data/ext/couchbase.cxx +43 -9568
  1063. data/ext/extconf.rb +5 -0
  1064. data/ext/rcb_analytics.cxx +1195 -0
  1065. data/ext/rcb_analytics.hxx +29 -0
  1066. data/ext/rcb_backend.cxx +530 -0
  1067. data/ext/rcb_backend.hxx +46 -0
  1068. data/ext/rcb_buckets.cxx +624 -0
  1069. data/ext/rcb_buckets.hxx +29 -0
  1070. data/ext/rcb_collections.cxx +377 -0
  1071. data/ext/rcb_collections.hxx +29 -0
  1072. data/ext/rcb_crud.cxx +1544 -0
  1073. data/ext/rcb_crud.hxx +29 -0
  1074. data/ext/rcb_diagnostics.cxx +264 -0
  1075. data/ext/rcb_diagnostics.hxx +29 -0
  1076. data/ext/rcb_exceptions.cxx +963 -0
  1077. data/ext/rcb_exceptions.hxx +111 -0
  1078. data/ext/rcb_extras.cxx +394 -0
  1079. data/ext/rcb_extras.hxx +29 -0
  1080. data/ext/rcb_logger.cxx +319 -0
  1081. data/ext/rcb_logger.hxx +36 -0
  1082. data/ext/rcb_multi.cxx +343 -0
  1083. data/ext/rcb_multi.hxx +29 -0
  1084. data/ext/rcb_query.cxx +1316 -0
  1085. data/ext/rcb_query.hxx +29 -0
  1086. data/ext/rcb_range_scan.cxx +358 -0
  1087. data/ext/rcb_range_scan.hxx +29 -0
  1088. data/ext/rcb_search.cxx +1216 -0
  1089. data/ext/rcb_search.hxx +29 -0
  1090. data/ext/rcb_users.cxx +636 -0
  1091. data/ext/rcb_users.hxx +29 -0
  1092. data/ext/rcb_utils.cxx +590 -0
  1093. data/ext/rcb_utils.hxx +564 -0
  1094. data/ext/rcb_version.cxx +137 -0
  1095. data/ext/rcb_version.hxx +34 -0
  1096. data/ext/rcb_views.cxx +485 -0
  1097. data/ext/rcb_views.hxx +29 -0
  1098. data/lib/active_support/cache/couchbase_store.rb +4 -1
  1099. data/lib/couchbase/analytics_options.rb +2 -0
  1100. data/lib/couchbase/authenticator.rb +2 -0
  1101. data/lib/couchbase/binary_collection.rb +2 -0
  1102. data/lib/couchbase/binary_collection_options.rb +2 -0
  1103. data/lib/couchbase/bucket.rb +2 -0
  1104. data/lib/couchbase/cluster.rb +2 -0
  1105. data/lib/couchbase/collection.rb +3 -1
  1106. data/lib/couchbase/collection_options.rb +2 -0
  1107. data/lib/couchbase/config_profiles.rb +2 -0
  1108. data/lib/couchbase/configuration.rb +2 -0
  1109. data/lib/couchbase/datastructures/couchbase_list.rb +4 -4
  1110. data/lib/couchbase/datastructures/couchbase_map.rb +4 -4
  1111. data/lib/couchbase/datastructures/couchbase_queue.rb +4 -4
  1112. data/lib/couchbase/datastructures/couchbase_set.rb +4 -4
  1113. data/lib/couchbase/datastructures.rb +2 -0
  1114. data/lib/couchbase/diagnostics.rb +2 -0
  1115. data/lib/couchbase/errors.rb +46 -8
  1116. data/lib/couchbase/json_transcoder.rb +2 -0
  1117. data/lib/couchbase/key_value_scan.rb +2 -0
  1118. data/lib/couchbase/logger.rb +2 -0
  1119. data/lib/couchbase/management/analytics_index_manager.rb +2 -0
  1120. data/lib/couchbase/management/bucket_manager.rb +2 -0
  1121. data/lib/couchbase/management/collection_manager.rb +2 -0
  1122. data/lib/couchbase/management/collection_query_index_manager.rb +2 -0
  1123. data/lib/couchbase/management/query_index_manager.rb +2 -0
  1124. data/lib/couchbase/management/scope_search_index_manager.rb +2 -0
  1125. data/lib/couchbase/management/search_index_manager.rb +2 -0
  1126. data/lib/couchbase/management/user_manager.rb +2 -0
  1127. data/lib/couchbase/management/view_index_manager.rb +2 -0
  1128. data/lib/couchbase/management.rb +2 -0
  1129. data/lib/couchbase/mutation_state.rb +2 -0
  1130. data/lib/couchbase/options.rb +2 -0
  1131. data/lib/couchbase/protostellar/request_generator/kv.rb +1 -1
  1132. data/lib/couchbase/query_options.rb +2 -0
  1133. data/lib/couchbase/railtie.rb +2 -0
  1134. data/lib/couchbase/raw_binary_transcoder.rb +2 -0
  1135. data/lib/couchbase/raw_json_transcoder.rb +2 -0
  1136. data/lib/couchbase/raw_string_transcoder.rb +2 -0
  1137. data/lib/couchbase/scope.rb +2 -0
  1138. data/lib/couchbase/search_options.rb +91 -63
  1139. data/lib/couchbase/subdoc.rb +5 -3
  1140. data/lib/couchbase/transcoder_flags.rb +2 -0
  1141. data/lib/couchbase/utils/generic_logger_adapter.rb +3 -1
  1142. data/lib/couchbase/utils/stdlib_logger_adapter.rb +2 -0
  1143. data/lib/couchbase/utils/time.rb +3 -1
  1144. data/lib/couchbase/utils.rb +2 -0
  1145. data/lib/couchbase/version.rb +3 -1
  1146. data/lib/couchbase/view_options.rb +2 -0
  1147. data/lib/couchbase.rb +2 -0
  1148. data/lib/rails/generators/couchbase/config/config_generator.rb +2 -0
  1149. metadata +83 -26
  1150. data/ext/couchbase/core/impl/internal_manager_error_context.cxx +0 -113
  1151. data/ext/couchbase/core/impl/internal_manager_error_context.hxx +0 -60
  1152. data/ext/couchbase/core/impl/manager_error_context.cxx +0 -100
  1153. data/ext/couchbase/core/impl/search_error_context.cxx +0 -147
  1154. data/ext/couchbase/couchbase/analytics_error_context.hxx +0 -143
  1155. data/ext/couchbase/couchbase/fmt/key_value_error_map_attribute.hxx +0 -100
  1156. data/ext/couchbase/couchbase/fmt/key_value_status_code.hxx +0 -269
  1157. data/ext/couchbase/couchbase/key_value_error_context.hxx +0 -229
  1158. data/ext/couchbase/couchbase/key_value_error_map_attribute.hxx +0 -136
  1159. data/ext/couchbase/couchbase/key_value_error_map_info.hxx +0 -138
  1160. data/ext/couchbase/couchbase/key_value_extended_error_info.hxx +0 -86
  1161. data/ext/couchbase/couchbase/key_value_status_code.hxx +0 -109
  1162. data/ext/couchbase/couchbase/manager_error_context.hxx +0 -111
  1163. data/ext/couchbase/couchbase/query_error_context.hxx +0 -145
  1164. data/ext/couchbase/couchbase/search_error_context.hxx +0 -138
  1165. data/ext/couchbase/couchbase/subdocument_error_context.hxx +0 -147
  1166. data/ext/couchbase/couchbase/transaction_op_error_context.hxx +0 -76
@@ -47,824 +47,894 @@ class bucket_impl
47
47
  , public config_listener
48
48
  , public response_handler
49
49
  {
50
- public:
51
- bucket_impl(std::string client_id,
52
- std::string name,
53
- couchbase::core::origin origin,
54
- std::shared_ptr<couchbase::tracing::request_tracer> tracer,
55
- std::shared_ptr<couchbase::metrics::meter> meter,
56
- std::vector<protocol::hello_feature> known_features,
57
- std::shared_ptr<impl::bootstrap_state_listener> state_listener,
58
- asio::io_context& ctx,
59
- asio::ssl::context& tls)
60
- : client_id_{ std::move(client_id) }
61
- , name_{ std::move(name) }
62
- , log_prefix_{ fmt::format("[{}/{}]", client_id_, name_) }
63
- , origin_{ std::move(origin) }
64
- , tracer_{ std::move(tracer) }
65
- , meter_{ std::move(meter) }
66
- , known_features_{ std::move(known_features) }
67
- , state_listener_{ std::move(state_listener) }
68
- , codec_{ { known_features_.begin(), known_features_.end() } }
69
- , ctx_{ ctx }
70
- , tls_{ tls }
71
- , heartbeat_timer_(ctx_)
72
- , heartbeat_interval_{ origin_.options().config_poll_floor > origin_.options().config_poll_interval
73
- ? origin_.options().config_poll_floor
74
- : origin_.options().config_poll_interval }
75
- {
50
+ public:
51
+ bucket_impl(std::string client_id,
52
+ std::string name,
53
+ couchbase::core::origin origin,
54
+ std::shared_ptr<couchbase::tracing::request_tracer> tracer,
55
+ std::shared_ptr<couchbase::metrics::meter> meter,
56
+ std::vector<protocol::hello_feature> known_features,
57
+ std::shared_ptr<impl::bootstrap_state_listener> state_listener,
58
+ asio::io_context& ctx,
59
+ asio::ssl::context& tls)
60
+ : client_id_{ std::move(client_id) }
61
+ , name_{ std::move(name) }
62
+ , log_prefix_{ fmt::format("[{}/{}]", client_id_, name_) }
63
+ , origin_{ std::move(origin) }
64
+ , tracer_{ std::move(tracer) }
65
+ , meter_{ std::move(meter) }
66
+ , known_features_{ std::move(known_features) }
67
+ , state_listener_{ std::move(state_listener) }
68
+ , codec_{ { known_features_.begin(), known_features_.end() } }
69
+ , ctx_{ ctx }
70
+ , tls_{ tls }
71
+ , heartbeat_timer_(ctx_)
72
+ , heartbeat_interval_{ origin_.options().config_poll_floor >
73
+ origin_.options().config_poll_interval
74
+ ? origin_.options().config_poll_floor
75
+ : origin_.options().config_poll_interval }
76
+ {
77
+ }
78
+
79
+ auto resolve_response(std::shared_ptr<mcbp::queue_request> req,
80
+ std::shared_ptr<mcbp::queue_response> resp,
81
+ std::error_code ec,
82
+ retry_reason reason,
83
+ std::optional<key_value_error_map_info> error_info)
84
+ {
85
+ // TODO: copy from mcbp_command, subject to refactor later
86
+ static std::string meter_name = "db.couchbase.operations";
87
+ static std::map<std::string, std::string> tags = {
88
+ { "db.couchbase.service", "kv" },
89
+ { "db.operation", fmt::format("{}", req->command_) },
90
+ };
91
+ meter_->get_value_recorder(meter_name, tags)
92
+ ->record_value(std::chrono::duration_cast<std::chrono::microseconds>(
93
+ std::chrono::steady_clock::now() - req->dispatched_time_)
94
+ .count());
95
+
96
+ if (ec == asio::error::operation_aborted) {
97
+ // TODO: fix tracing
98
+ // self->span_->add_tag(tracing::attributes::orphan, "aborted");
99
+ return req->try_callback(resp,
100
+ req->idempotent() ? errc::common::unambiguous_timeout
101
+ : errc::common::ambiguous_timeout);
76
102
  }
77
-
78
- auto resolve_response(std::shared_ptr<mcbp::queue_request> req,
79
- std::shared_ptr<mcbp::queue_response> resp,
80
- std::error_code ec,
81
- retry_reason reason,
82
- std::optional<key_value_error_map_info> error_info)
83
- {
84
- // TODO: copy from mcbp_command, subject to refactor later
85
- static std::string meter_name = "db.couchbase.operations";
86
- static std::map<std::string, std::string> tags = {
87
- { "db.couchbase.service", "kv" },
88
- { "db.operation", fmt::format("{}", req->command_) },
89
- };
90
- meter_->get_value_recorder(meter_name, tags)
91
- ->record_value(
92
- std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - req->dispatched_time_).count());
93
-
94
- if (ec == asio::error::operation_aborted) {
95
- // TODO: fix tracing
96
- // self->span_->add_tag(tracing::attributes::orphan, "aborted");
97
- return req->try_callback(resp, req->idempotent() ? errc::common::unambiguous_timeout : errc::common::ambiguous_timeout);
98
- }
99
- if (ec == errc::common::request_canceled) {
100
- if (!req->idempotent() && !allows_non_idempotent_retry(reason)) {
101
- // TODO: fix tracing
102
- // self->span_->add_tag(tracing::attributes::orphan, "canceled");
103
- return req->try_callback(resp, ec);
104
- }
105
- backoff_and_retry(req, reason == retry_reason::do_not_retry ? retry_reason::node_not_available : reason);
106
- return;
107
- }
108
- key_value_status_code status{ key_value_status_code::unknown };
109
- if (resp) {
110
- status = resp->status_code_;
111
- }
112
- if (status == key_value_status_code::not_my_vbucket) {
113
- reason = retry_reason::key_value_not_my_vbucket;
114
- }
115
- if (status == key_value_status_code::unknown && error_info && error_info.value().has_retry_attribute()) {
116
- reason = retry_reason::key_value_error_map_retry_indicated;
117
- } else {
118
- switch (status) {
119
- case key_value_status_code::locked:
120
- if (req->command_ != protocol::client_opcode::unlock) {
121
- /**
122
- * special case for unlock command, when it should not be retried, because it does not make sense
123
- * (someone else unlocked the document)
124
- */
125
- reason = retry_reason::key_value_locked;
126
- }
127
- break;
128
- case key_value_status_code::temporary_failure:
129
- reason = retry_reason::key_value_temporary_failure;
130
- break;
131
- case key_value_status_code::sync_write_in_progress:
132
- reason = retry_reason::key_value_sync_write_in_progress;
133
- break;
134
- case key_value_status_code::sync_write_re_commit_in_progress:
135
- reason = retry_reason::key_value_sync_write_re_commit_in_progress;
136
- break;
137
- default:
138
- break;
139
- }
140
- }
141
- if (reason == retry_reason::do_not_retry || !backoff_and_retry(req, reason)) {
142
- return req->try_callback(resp, ec);
143
- }
103
+ if (ec == errc::common::request_canceled) {
104
+ if (!req->idempotent() && !allows_non_idempotent_retry(reason)) {
105
+ // TODO: fix tracing
106
+ // self->span_->add_tag(tracing::attributes::orphan, "canceled");
107
+ return req->try_callback(resp, ec);
108
+ }
109
+ backoff_and_retry(std::move(req),
110
+ reason == retry_reason::do_not_retry ? retry_reason::node_not_available
111
+ : reason);
112
+ return;
144
113
  }
145
-
146
- void handle_response(std::shared_ptr<mcbp::queue_request> req,
147
- std::error_code error,
148
- retry_reason reason,
149
- io::mcbp_message msg,
150
- std::optional<key_value_error_map_info> error_info) override
151
- {
152
- std::shared_ptr<mcbp::queue_response> resp{};
153
- auto header = msg.header_data();
154
- auto [packet, size, err] = codec_.decode_packet(gsl::span(header.data(), header.size()), msg.body);
155
- if (err) {
156
- error = errc::network::protocol_error;
157
- } else {
158
- resp = std::make_shared<mcbp::queue_response>(std::move(packet));
159
- }
160
- resolve_response(req, resp, error, reason, std::move(error_info));
114
+ key_value_status_code status{ key_value_status_code::unknown };
115
+ if (resp) {
116
+ status = resp->status_code_;
161
117
  }
162
-
163
- auto direct_dispatch(std::shared_ptr<mcbp::queue_request> req) -> std::error_code
164
- {
165
- if (closed_) {
166
- req->cancel(errc::network::bucket_closed);
167
- return errc::network::bucket_closed;
168
- }
169
- if (!configured_) {
170
- return defer_command([self = shared_from_this(), req]() { self->direct_dispatch(req); });
171
- }
172
-
173
- req->dispatched_time_ = std::chrono::steady_clock::now();
174
-
175
- auto session = route_request(req);
176
- if (!session || !session->has_config()) {
177
- return defer_command([self = shared_from_this(), req]() mutable { self->direct_dispatch(std::move(req)); });
178
- }
179
- if (session->is_stopped()) {
180
- if (backoff_and_retry(req, retry_reason::node_not_available)) {
181
- return {};
182
- }
183
- return errc::common::service_not_available;
184
- }
185
- req->opaque_ = session->next_opaque();
186
- session->write_and_subscribe(req, shared_from_this());
187
- return {};
118
+ if (status == key_value_status_code::not_my_vbucket) {
119
+ reason = retry_reason::key_value_not_my_vbucket;
120
+ }
121
+ if (status == key_value_status_code::unknown && error_info &&
122
+ error_info.value().has_retry_attribute()) {
123
+ reason = retry_reason::key_value_error_map_retry_indicated;
124
+ } else {
125
+ switch (status) {
126
+ case key_value_status_code::locked:
127
+ if (req->command_ != protocol::client_opcode::unlock) {
128
+ /**
129
+ * special case for unlock command, when it should not be retried, because it does not
130
+ * make sense (someone else unlocked the document)
131
+ */
132
+ reason = retry_reason::key_value_locked;
133
+ }
134
+ break;
135
+ case key_value_status_code::temporary_failure:
136
+ reason = retry_reason::key_value_temporary_failure;
137
+ break;
138
+ case key_value_status_code::sync_write_in_progress:
139
+ reason = retry_reason::key_value_sync_write_in_progress;
140
+ break;
141
+ case key_value_status_code::sync_write_re_commit_in_progress:
142
+ reason = retry_reason::key_value_sync_write_re_commit_in_progress;
143
+ break;
144
+ default:
145
+ break;
146
+ }
147
+ }
148
+ if (reason == retry_reason::do_not_retry || !backoff_and_retry(req, reason)) {
149
+ return req->try_callback(resp, ec);
150
+ }
151
+ }
152
+
153
+ void handle_response(std::shared_ptr<mcbp::queue_request> req,
154
+ std::error_code error,
155
+ retry_reason reason,
156
+ io::mcbp_message msg,
157
+ std::optional<key_value_error_map_info> error_info) override
158
+ {
159
+ std::shared_ptr<mcbp::queue_response> resp{};
160
+ auto header = msg.header_data();
161
+ auto [packet, size, err] =
162
+ codec_.decode_packet(gsl::span(header.data(), header.size()), msg.body);
163
+ if (err) {
164
+ error = errc::network::protocol_error;
165
+ } else {
166
+ resp = std::make_shared<mcbp::queue_response>(std::move(packet));
167
+ }
168
+ resolve_response(std::move(req), std::move(resp), error, reason, std::move(error_info));
169
+ }
170
+
171
+ auto direct_dispatch(std::shared_ptr<mcbp::queue_request> req) -> std::error_code
172
+ {
173
+ if (closed_) {
174
+ req->cancel(errc::network::bucket_closed);
175
+ return errc::network::bucket_closed;
176
+ }
177
+ if (!configured_) {
178
+ return defer_command([self = shared_from_this(), req]() {
179
+ self->direct_dispatch(req);
180
+ });
188
181
  }
189
182
 
190
- auto direct_re_queue(std::shared_ptr<mcbp::queue_request> req, bool is_retry) -> std::error_code
191
- {
192
- auto handle_error = [is_retry, req](std::error_code ec) {
193
- // We only want to log an error on retries if the error isn't cancelled.
194
- if (!is_retry || (is_retry && ec != errc::common::request_canceled)) {
195
- CB_LOG_ERROR("reschedule failed, failing request ({})", ec.message());
196
- }
197
-
198
- req->try_callback({}, ec);
199
- };
200
-
201
- CB_LOG_DEBUG("request being re-queued. opaque={}, opcode={}", req->opaque_, req->command_);
183
+ req->dispatched_time_ = std::chrono::steady_clock::now();
202
184
 
203
- auto session = route_request(req);
204
- if (!session || !session->has_config()) {
205
- return defer_command([self = shared_from_this(), req]() { self->direct_dispatch(req); });
206
- }
207
- if (session->is_stopped()) {
208
- if (backoff_and_retry(req, retry_reason::node_not_available)) {
209
- return {};
210
- }
211
- handle_error(errc::common::service_not_available);
212
- return errc::common::service_not_available;
213
- }
214
- req->opaque_ = session->next_opaque();
215
- auto data = codec_.encode_packet(*req);
216
- if (!data) {
217
- CB_LOG_DEBUG("unable to encode packet. ec={}", data.error().message());
218
- handle_error(data.error());
219
- return data.error();
220
- }
221
- session->write_and_subscribe(
222
- req->opaque_,
223
- std::move(data.value()),
224
- [self = shared_from_this(), req, session](
225
- std::error_code error, retry_reason reason, io::mcbp_message msg, std::optional<key_value_error_map_info> error_info) {
226
- std::shared_ptr<mcbp::queue_response> resp{};
227
- auto header = msg.header_data();
228
- auto [packet, size, err] = self->codec_.decode_packet(gsl::span(header.data(), header.size()), msg.body);
229
- if (err) {
230
- error = errc::network::protocol_error;
231
- } else {
232
- resp = std::make_shared<mcbp::queue_response>(std::move(packet));
233
- }
234
- return self->resolve_response(req, resp, error, reason, std::move(error_info));
235
- });
185
+ auto session = route_request(req);
186
+ if (!session || !session->has_config()) {
187
+ return defer_command([self = shared_from_this(), req]() mutable {
188
+ self->direct_dispatch(std::move(req));
189
+ });
190
+ }
191
+ if (session->is_stopped()) {
192
+ if (backoff_and_retry(req, retry_reason::node_not_available)) {
236
193
  return {};
194
+ }
195
+ return errc::common::service_not_available;
237
196
  }
238
-
239
- auto backoff_and_retry(std::shared_ptr<mcbp::queue_request> request, retry_reason reason) -> bool
240
- {
241
- auto action = retry_orchestrator::should_retry(request, reason);
242
- auto retried = action.need_to_retry();
243
- if (retried) {
244
- auto timer = std::make_shared<asio::steady_timer>(ctx_);
245
- timer->expires_after(action.duration());
246
- timer->async_wait([self = shared_from_this(), request](auto error) {
247
- if (error == asio::error::operation_aborted) {
248
- return;
249
- }
250
- self->direct_re_queue(request, true);
251
- });
252
- request->set_retry_backoff(timer);
253
- }
254
- return retried;
197
+ req->opaque_ = session->next_opaque();
198
+ session->write_and_subscribe(req, shared_from_this());
199
+ return {};
200
+ }
201
+
202
+ auto direct_re_queue(std::shared_ptr<mcbp::queue_request> req, bool is_retry) -> std::error_code
203
+ {
204
+ auto handle_error = [is_retry, req](std::error_code ec) {
205
+ // We only want to log an error on retries if the error isn't cancelled.
206
+ if (!is_retry || (is_retry && ec != errc::common::request_canceled)) {
207
+ CB_LOG_ERROR("reschedule failed, failing request ({})", ec.message());
208
+ }
209
+
210
+ req->try_callback({}, ec);
211
+ };
212
+
213
+ CB_LOG_DEBUG("request being re-queued. opaque={}, opcode={}", req->opaque_, req->command_);
214
+
215
+ auto session = route_request(req);
216
+ if (!session || !session->has_config()) {
217
+ return defer_command([self = shared_from_this(), req]() {
218
+ self->direct_dispatch(req);
219
+ });
255
220
  }
256
-
257
- auto route_request(std::shared_ptr<mcbp::queue_request> req) -> std::optional<io::mcbp_session>
258
- {
259
- if (req->key_.empty()) {
260
- if (auto server = server_by_vbucket(req->vbucket_, req->replica_index_); server) {
261
- return find_session_by_index(server.value());
262
- }
263
- } else if (auto [partition, server] = map_id(req->key_, req->replica_index_); server) {
264
- req->vbucket_ = partition;
265
- return find_session_by_index(server.value());
266
- }
221
+ if (session->is_stopped()) {
222
+ if (backoff_and_retry(req, retry_reason::node_not_available)) {
267
223
  return {};
224
+ }
225
+ handle_error(errc::common::service_not_available);
226
+ return errc::common::service_not_available;
268
227
  }
269
-
270
- [[nodiscard]] auto server_by_vbucket(std::uint16_t vbucket, std::size_t node_index) -> std::optional<std::size_t>
271
- {
272
- std::scoped_lock lock(config_mutex_);
273
- return config_->server_by_vbucket(vbucket, node_index);
274
- }
275
-
276
- [[nodiscard]] auto map_id(const document_id& id) -> std::pair<std::uint16_t, std::optional<std::size_t>>
277
- {
278
- std::scoped_lock lock(config_mutex_);
279
- return config_->map_key(id.key(), id.node_index());
228
+ req->opaque_ = session->next_opaque();
229
+ auto data = codec_.encode_packet(*req);
230
+ if (!data) {
231
+ CB_LOG_DEBUG("unable to encode packet. ec={}", data.error().message());
232
+ handle_error(data.error());
233
+ return data.error();
280
234
  }
281
-
282
- auto config_rev() const -> std::string
283
- {
284
- std::scoped_lock lock(config_mutex_);
285
- if (config_) {
286
- return config_->rev_str();
235
+ session->write_and_subscribe(
236
+ req->opaque_,
237
+ std::move(data.value()),
238
+ [self = shared_from_this(), req, session](
239
+ std::error_code error,
240
+ retry_reason reason,
241
+ io::mcbp_message msg,
242
+ std::optional<key_value_error_map_info> error_info) {
243
+ std::shared_ptr<mcbp::queue_response> resp{};
244
+ auto header = msg.header_data();
245
+ auto [packet, size, err] =
246
+ self->codec_.decode_packet(gsl::span(header.data(), header.size()), msg.body);
247
+ if (err) {
248
+ error = errc::network::protocol_error;
249
+ } else {
250
+ resp = std::make_shared<mcbp::queue_response>(std::move(packet));
251
+ }
252
+ return self->resolve_response(req, resp, error, reason, std::move(error_info));
253
+ });
254
+ return {};
255
+ }
256
+
257
+ auto backoff_and_retry(std::shared_ptr<mcbp::queue_request> request, retry_reason reason) -> bool
258
+ {
259
+ auto action = retry_orchestrator::should_retry(request, reason);
260
+ auto retried = action.need_to_retry();
261
+ if (retried) {
262
+ auto timer = std::make_shared<asio::steady_timer>(ctx_);
263
+ timer->expires_after(action.duration());
264
+ timer->async_wait([self = shared_from_this(), request](auto error) {
265
+ if (error == asio::error::operation_aborted) {
266
+ return;
287
267
  }
288
- return "<no-config>";
268
+ self->direct_re_queue(request, true);
269
+ });
270
+ request->set_retry_backoff(timer);
289
271
  }
290
-
291
- [[nodiscard]] auto map_id(const std::vector<std::byte>& key, std::size_t node_index)
292
- -> std::pair<std::uint16_t, std::optional<std::size_t>>
293
- {
294
- std::scoped_lock lock(config_mutex_);
295
- return config_->map_key(key, node_index);
272
+ return retried;
273
+ }
274
+
275
+ auto route_request(std::shared_ptr<mcbp::queue_request> req) -> std::optional<io::mcbp_session>
276
+ {
277
+ if (req->key_.empty()) {
278
+ if (auto server = server_by_vbucket(req->vbucket_, req->replica_index_); server) {
279
+ return find_session_by_index(server.value());
280
+ }
281
+ } else if (auto [partition, server] = map_id(req->key_, req->replica_index_); server) {
282
+ req->vbucket_ = partition;
283
+ return find_session_by_index(server.value());
296
284
  }
297
-
298
- void restart_sessions()
299
- {
300
- const std::scoped_lock lock(config_mutex_, sessions_mutex_);
301
- if (!config_.has_value()) {
302
- return;
303
- }
304
-
305
- std::size_t kv_node_index{ 0 };
306
- for (std::size_t index = 0; index < config_->nodes.size(); ++index) {
307
- const auto& node = config_->nodes[index];
308
-
309
- const auto& hostname = node.hostname_for(origin_.options().network);
310
- auto port = node.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
311
- if (port == 0) {
312
- continue;
313
- }
314
-
315
- auto ptr = std::find_if(sessions_.begin(), sessions_.end(), [&hostname, &port](const auto& session) {
316
- return session.second.bootstrap_hostname() == hostname && session.second.bootstrap_port_number() == port;
317
- });
318
- if (ptr != sessions_.end()) {
319
-
320
- if (auto found_kv_node_index = ptr->first; found_kv_node_index != kv_node_index) {
321
- if (auto current = sessions_.find(kv_node_index); current == sessions_.end()) {
322
- CB_LOG_WARNING(R"({} KV node index mismatch: config rev={} states that address="{}:{}" should be at idx={}, )"
323
- R"(but it is at idx={} ("{}"). Moving session to idx={}.)",
324
- log_prefix_,
325
- config_->rev_str(),
326
- hostname,
327
- port,
328
- kv_node_index,
329
- found_kv_node_index,
330
- ptr->second.id(),
331
- kv_node_index);
332
- sessions_.insert_or_assign(kv_node_index, std::move(ptr->second));
333
- sessions_.erase(ptr);
334
- } else {
335
- CB_LOG_WARNING(
336
- R"({} KV node index mismatch: config rev={} states that address="{}:{}" should be at idx={}, )"
337
- R"(but it is at idx={} ("{}"). Slot with idx={} is holds session with address="{}" ("{}"), swapping them.)",
338
- log_prefix_,
339
- config_->rev_str(),
340
- hostname,
341
- port,
342
- kv_node_index,
343
- found_kv_node_index,
344
- ptr->second.id(),
345
- kv_node_index,
346
- current->second.bootstrap_address(),
347
- current->second.id());
348
- std::swap(current->second, ptr->second);
349
- }
350
- }
351
- ++kv_node_index;
352
- continue;
353
- }
354
- couchbase::core::origin origin(origin_.credentials(), hostname, port, origin_.options());
355
- io::mcbp_session session = origin_.options().enable_tls
356
- ? io::mcbp_session(client_id_, ctx_, tls_, origin, state_listener_, name_, known_features_)
357
- : io::mcbp_session(client_id_, ctx_, origin, state_listener_, name_, known_features_);
358
- CB_LOG_DEBUG(R"({} rev={}, restart idx={}, session="{}", address="{}:{}")",
359
- log_prefix_,
360
- config_->rev_str(),
361
- node.index,
362
- session.id(),
363
- hostname,
364
- port);
365
- session.bootstrap(
366
- [self = shared_from_this(), session](std::error_code err, topology::configuration cfg) mutable {
367
- if (err) {
368
- return self->remove_session(session.id());
369
- }
370
- self->update_config(std::move(cfg));
371
- session.on_configuration_update(self);
372
- session.on_stop([id = session.id(), self]() { self->remove_session(id); });
373
- self->drain_deferred_queue();
374
- },
375
- true);
376
- sessions_.insert_or_assign(index, std::move(session));
377
- ++kv_node_index;
378
- }
285
+ return {};
286
+ }
287
+
288
+ [[nodiscard]] auto server_by_vbucket(std::uint16_t vbucket,
289
+ std::size_t node_index) -> std::optional<std::size_t>
290
+ {
291
+ std::scoped_lock lock(config_mutex_);
292
+ return config_->server_by_vbucket(vbucket, node_index);
293
+ }
294
+
295
+ [[nodiscard]] auto map_id(const document_id& id)
296
+ -> std::pair<std::uint16_t, std::optional<std::size_t>>
297
+ {
298
+ std::scoped_lock lock(config_mutex_);
299
+ return config_->map_key(id.key(), id.node_index());
300
+ }
301
+
302
+ auto config_rev() const -> std::string
303
+ {
304
+ std::scoped_lock lock(config_mutex_);
305
+ if (config_) {
306
+ return config_->rev_str();
379
307
  }
380
-
381
- void remove_session(const std::string& id)
382
- {
383
- bool found{ false };
384
- const std::scoped_lock lock(sessions_mutex_);
385
- for (auto ptr = sessions_.cbegin(); ptr != sessions_.cend();) {
386
- if (ptr->second.id() == id) {
387
- CB_LOG_DEBUG(R"({} removed session id="{}", address="{}", bootstrap_address="{}:{}")",
388
- log_prefix_,
389
- ptr->second.id(),
390
- ptr->second.remote_address(),
391
- ptr->second.bootstrap_hostname(),
392
- ptr->second.bootstrap_port());
393
- ptr = sessions_.erase(ptr);
394
- found = true;
395
- } else {
396
- ptr = std::next(ptr);
397
- }
398
- }
399
-
400
- if (found) {
401
- asio::post(asio::bind_executor(ctx_, [self = shared_from_this()]() { return self->restart_sessions(); }));
402
- }
308
+ return "<no-config>";
309
+ }
310
+
311
+ [[nodiscard]] auto map_id(const std::vector<std::byte>& key, std::size_t node_index)
312
+ -> std::pair<std::uint16_t, std::optional<std::size_t>>
313
+ {
314
+ std::scoped_lock lock(config_mutex_);
315
+ return config_->map_key(key, node_index);
316
+ }
317
+
318
+ void restart_sessions()
319
+ {
320
+ const std::scoped_lock lock(config_mutex_, sessions_mutex_);
321
+ if (!config_.has_value()) {
322
+ return;
403
323
  }
404
324
 
405
- void bootstrap(utils::movable_function<void(std::error_code, topology::configuration)>&& handler)
406
- {
407
- if (state_listener_) {
408
- state_listener_->register_config_listener(shared_from_this());
409
- }
410
- io::mcbp_session new_session = origin_.options().enable_tls
411
- ? io::mcbp_session(client_id_, ctx_, tls_, origin_, state_listener_, name_, known_features_)
412
- : io::mcbp_session(client_id_, ctx_, origin_, state_listener_, name_, known_features_);
413
- new_session.bootstrap([self = shared_from_this(), new_session, h = std::move(handler)](std::error_code ec,
414
- topology::configuration cfg) mutable {
415
- if (ec) {
416
- CB_LOG_WARNING(R"({} failed to bootstrap session ec={}, bucket="{}")", new_session.log_prefix(), ec.message(), self->name_);
417
- self->remove_session(new_session.id());
418
- } else {
419
- const std::size_t this_index = new_session.index();
420
- new_session.on_configuration_update(self);
421
- new_session.on_stop([id = new_session.id(), self]() { self->remove_session(id); });
422
-
423
- {
424
- std::scoped_lock lock(self->sessions_mutex_);
425
- self->sessions_.insert_or_assign(this_index, std::move(new_session));
426
- }
427
- self->update_config(cfg);
428
- self->drain_deferred_queue();
429
- self->poll_config({});
430
- }
431
- asio::post(asio::bind_executor(self->ctx_, [h = std::move(h), ec, cfg = std::move(cfg)]() mutable { h(ec, cfg); }));
325
+ std::size_t kv_node_index{ 0 };
326
+ for (std::size_t index = 0; index < config_->nodes.size(); ++index) {
327
+ const auto& node = config_->nodes[index];
328
+
329
+ const auto& hostname = node.hostname_for(origin_.options().network);
330
+ auto port = node.port_or(
331
+ origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
332
+ if (port == 0) {
333
+ continue;
334
+ }
335
+
336
+ auto ptr =
337
+ std::find_if(sessions_.begin(), sessions_.end(), [&hostname, &port](const auto& session) {
338
+ return session.second.bootstrap_hostname() == hostname &&
339
+ session.second.bootstrap_port_number() == port;
432
340
  });
433
- }
434
-
435
- void with_configuration(utils::movable_function<void(std::error_code, topology::configuration)>&& handler)
436
- {
437
- if (closed_) {
438
- return handler(errc::network::configuration_not_available, topology::configuration{});
439
- }
440
- if (configured_) {
441
- std::optional<topology::configuration> config{};
442
- {
443
- std::scoped_lock config_lock(config_mutex_);
444
- config = config_;
445
- }
446
- if (config) {
447
- return handler({}, config.value());
448
- }
449
- return handler(errc::network::configuration_not_available, topology::configuration{});
341
+ if (ptr != sessions_.end()) {
342
+
343
+ if (auto found_kv_node_index = ptr->first; found_kv_node_index != kv_node_index) {
344
+ if (auto current = sessions_.find(kv_node_index); current == sessions_.end()) {
345
+ CB_LOG_WARNING(
346
+ R"({} KV node index mismatch: config rev={} states that address="{}:{}" should be at idx={}, )"
347
+ R"(but it is at idx={} ("{}"). Moving session to idx={}.)",
348
+ log_prefix_,
349
+ config_->rev_str(),
350
+ hostname,
351
+ port,
352
+ kv_node_index,
353
+ found_kv_node_index,
354
+ ptr->second.id(),
355
+ kv_node_index);
356
+ sessions_.insert_or_assign(kv_node_index, std::move(ptr->second));
357
+ sessions_.erase(ptr);
358
+ } else {
359
+ CB_LOG_WARNING(
360
+ R"({} KV node index mismatch: config rev={} states that address="{}:{}" should be at idx={}, )"
361
+ R"(but it is at idx={} ("{}"). Slot with idx={} is holds session with address="{}" ("{}"), swapping them.)",
362
+ log_prefix_,
363
+ config_->rev_str(),
364
+ hostname,
365
+ port,
366
+ kv_node_index,
367
+ found_kv_node_index,
368
+ ptr->second.id(),
369
+ kv_node_index,
370
+ current->second.bootstrap_address(),
371
+ current->second.id());
372
+ std::swap(current->second, ptr->second);
373
+ }
450
374
  }
451
- std::scoped_lock lock(deferred_commands_mutex_);
452
- deferred_commands_.emplace([self = shared_from_this(), handler = std::move(handler)]() mutable {
453
- if (self->closed_ || !self->configured_) {
454
- return handler(errc::network::configuration_not_available, topology::configuration{});
455
- }
456
-
457
- std::optional<topology::configuration> config{};
458
- {
459
- std::scoped_lock config_lock(self->config_mutex_);
460
- config = self->config_;
461
- }
462
- if (config) {
463
- return handler({}, config.value());
464
- }
465
- return handler(errc::network::configuration_not_available, topology::configuration{});
466
- });
375
+ ++kv_node_index;
376
+ continue;
377
+ }
378
+ couchbase::core::origin origin(origin_.credentials(), hostname, port, origin_.options());
379
+ io::mcbp_session session =
380
+ origin_.options().enable_tls
381
+ ? io::mcbp_session(
382
+ client_id_, ctx_, tls_, origin, state_listener_, name_, known_features_)
383
+ : io::mcbp_session(client_id_, ctx_, origin, state_listener_, name_, known_features_);
384
+ CB_LOG_DEBUG(R"({} rev={}, restart idx={}, session="{}", address="{}:{}")",
385
+ log_prefix_,
386
+ config_->rev_str(),
387
+ node.index,
388
+ session.id(),
389
+ hostname,
390
+ port);
391
+ session.bootstrap(
392
+ [self = shared_from_this(), session](std::error_code err,
393
+ topology::configuration cfg) mutable {
394
+ if (err) {
395
+ return self->remove_session(session.id());
396
+ }
397
+ self->update_config(std::move(cfg));
398
+ session.on_configuration_update(self);
399
+ session.on_stop([id = session.id(), self]() {
400
+ self->remove_session(id);
401
+ });
402
+ self->drain_deferred_queue();
403
+ },
404
+ true);
405
+ sessions_.insert_or_assign(index, std::move(session));
406
+ ++kv_node_index;
467
407
  }
468
-
469
- void drain_deferred_queue()
470
- {
471
- std::queue<utils::movable_function<void()>> commands{};
472
- {
473
- std::scoped_lock lock(deferred_commands_mutex_);
474
- std::swap(deferred_commands_, commands);
475
- }
476
- if (!commands.empty()) {
477
- CB_LOG_TRACE(R"({} draining deferred operation queue, size={})", log_prefix_, commands.size());
478
- }
479
- while (!commands.empty()) {
480
- commands.front()();
481
- commands.pop();
482
- }
408
+ }
409
+
410
+ void remove_session(const std::string& id)
411
+ {
412
+ bool found{ false };
413
+ const std::scoped_lock lock(sessions_mutex_);
414
+ for (auto ptr = sessions_.cbegin(); ptr != sessions_.cend();) {
415
+ if (ptr->second.id() == id) {
416
+ CB_LOG_DEBUG(R"({} removed session id="{}", address="{}", bootstrap_address="{}:{}")",
417
+ log_prefix_,
418
+ ptr->second.id(),
419
+ ptr->second.remote_address(),
420
+ ptr->second.bootstrap_hostname(),
421
+ ptr->second.bootstrap_port());
422
+ ptr = sessions_.erase(ptr);
423
+ found = true;
424
+ } else {
425
+ ptr = std::next(ptr);
426
+ }
483
427
  }
484
428
 
485
- void fetch_config()
486
- {
487
- if (closed_) {
488
- return;
489
- }
490
- std::optional<io::mcbp_session> session{};
491
- {
492
- std::scoped_lock lock(sessions_mutex_);
493
-
494
- std::size_t start = heartbeat_next_index_.fetch_add(1);
495
- std::size_t i = start;
496
- do {
497
- auto ptr = sessions_.find(i % sessions_.size());
498
- if (ptr != sessions_.end() && ptr->second.is_bootstrapped() && ptr->second.supports_gcccp()) {
499
- session = ptr->second;
500
- }
501
- i = heartbeat_next_index_.fetch_add(1);
502
- } while (start % sessions_.size() != i % sessions_.size());
503
- }
504
- if (session) {
505
- protocol::client_request<protocol::get_cluster_config_request_body> req;
506
- req.opaque(session->next_opaque());
507
- session->write_and_flush(req.data());
508
- } else {
509
- CB_LOG_WARNING(R"({} unable to find connected session with GCCCP support, retry in {})", log_prefix_, heartbeat_interval_);
510
- }
429
+ if (found) {
430
+ asio::post(asio::bind_executor(ctx_, [self = shared_from_this()]() {
431
+ return self->restart_sessions();
432
+ }));
511
433
  }
434
+ }
512
435
 
513
- void poll_config(std::error_code ec)
514
- {
515
- if (ec == asio::error::operation_aborted || closed_) {
516
- return;
517
- }
518
- if (heartbeat_timer_.expiry() > std::chrono::steady_clock::now()) {
519
- return;
520
- }
521
-
522
- fetch_config();
523
-
524
- heartbeat_timer_.expires_after(heartbeat_interval_);
525
- return heartbeat_timer_.async_wait([self = shared_from_this()](std::error_code e) {
526
- if (e == asio::error::operation_aborted) {
527
- return;
528
- }
529
- self->poll_config(e);
530
- });
436
+ void bootstrap(utils::movable_function<void(std::error_code, topology::configuration)>&& handler)
437
+ {
438
+ if (state_listener_) {
439
+ state_listener_->register_config_listener(shared_from_this());
531
440
  }
441
+ io::mcbp_session new_session =
442
+ origin_.options().enable_tls
443
+ ? io::mcbp_session(client_id_, ctx_, tls_, origin_, state_listener_, name_, known_features_)
444
+ : io::mcbp_session(client_id_, ctx_, origin_, state_listener_, name_, known_features_);
445
+ new_session.bootstrap([self = shared_from_this(), new_session, h = std::move(handler)](
446
+ std::error_code ec, topology::configuration cfg) mutable {
447
+ if (ec) {
448
+ CB_LOG_WARNING(R"({} failed to bootstrap session ec={}, bucket="{}")",
449
+ new_session.log_prefix(),
450
+ ec.message(),
451
+ self->name_);
452
+ self->remove_session(new_session.id());
453
+ } else {
454
+ const std::size_t this_index = new_session.index();
455
+ new_session.on_configuration_update(self);
456
+ new_session.on_stop([id = new_session.id(), self]() {
457
+ self->remove_session(id);
458
+ });
532
459
 
533
- void close()
534
- {
535
- if (bool expected_state{ false }; !closed_.compare_exchange_strong(expected_state, true)) {
536
- return;
537
- }
538
-
539
- heartbeat_timer_.cancel();
540
-
541
- drain_deferred_queue();
542
-
543
- if (state_listener_ != nullptr) {
544
- state_listener_->unregister_config_listener(shared_from_this());
545
- }
546
-
547
- {
548
- std::scoped_lock lock(config_listeners_mutex_);
549
- config_listeners_.clear();
550
- }
551
-
552
- std::map<size_t, io::mcbp_session> old_sessions;
553
460
  {
554
- std::scoped_lock lock(sessions_mutex_);
555
- std::swap(old_sessions, sessions_);
556
- }
557
- for (auto& [index, session] : old_sessions) {
558
- session.stop(retry_reason::do_not_retry);
461
+ std::scoped_lock lock(self->sessions_mutex_);
462
+ self->sessions_.insert_or_assign(this_index, std::move(new_session));
559
463
  }
464
+ self->update_config(cfg);
465
+ self->drain_deferred_queue();
466
+ self->poll_config({});
467
+ }
468
+ asio::post(
469
+ asio::bind_executor(self->ctx_, [h = std::move(h), ec, cfg = std::move(cfg)]() mutable {
470
+ h(ec, cfg);
471
+ }));
472
+ });
473
+ }
474
+
475
+ void with_configuration(
476
+ utils::movable_function<void(std::error_code, topology::configuration)>&& handler)
477
+ {
478
+ if (closed_) {
479
+ return handler(errc::network::configuration_not_available, topology::configuration{});
560
480
  }
561
-
562
- /**
563
- * copies nodes from rhs that are not in lhs to output vector
564
- */
565
- void diff_nodes(const std::vector<topology::configuration::node>& lhs,
566
- const std::vector<topology::configuration::node>& rhs,
567
- std::vector<topology::configuration::node>& output)
568
- {
569
- for (const auto& re : rhs) {
570
- bool known = false;
571
- const auto& rhost = re.hostname_for(origin_.options().network);
572
- const auto rport = re.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
573
- for (const auto& le : lhs) {
574
- const auto& lhost = le.hostname_for(origin_.options().network);
575
- const auto lport = le.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
576
- if (rhost == lhost && rport == lport) {
577
- known = true;
578
- break;
579
- }
580
- }
581
- if (!known) {
582
- output.push_back(re);
583
- }
584
- }
481
+ if (configured_) {
482
+ std::optional<topology::configuration> config{};
483
+ {
484
+ std::scoped_lock config_lock(config_mutex_);
485
+ config = config_;
486
+ }
487
+ if (config) {
488
+ return handler({}, config.value());
489
+ }
490
+ return handler(errc::network::configuration_not_available, topology::configuration{});
585
491
  }
586
-
587
- void update_config(topology::configuration config) override
492
+ std::scoped_lock lock(deferred_commands_mutex_);
493
+ deferred_commands_.emplace([self = shared_from_this(), handler = std::move(handler)]() mutable {
494
+ if (self->closed_ || !self->configured_) {
495
+ return handler(errc::network::configuration_not_available, topology::configuration{});
496
+ }
497
+
498
+ std::optional<topology::configuration> config{};
499
+ {
500
+ std::scoped_lock config_lock(self->config_mutex_);
501
+ config = self->config_;
502
+ }
503
+ if (config) {
504
+ return handler({}, config.value());
505
+ }
506
+ return handler(errc::network::configuration_not_available, topology::configuration{});
507
+ });
508
+ }
509
+
510
+ void drain_deferred_queue()
511
+ {
512
+ std::queue<utils::movable_function<void()>> commands{};
588
513
  {
589
- std::vector<topology::configuration::node> added{};
590
- std::vector<topology::configuration::node> removed{};
591
- bool sequence_changed = false;
592
- {
593
- std::scoped_lock lock(config_mutex_);
594
- // MB-60405 fixes this for 7.6.2, but for earlier versions we need to protect against using a
595
- // config that has an empty vbucket map. Ideally we only run into this condition on initial
596
- // bootstrap and that is handled in the session's update_config(), but just in case, only accept
597
- // a config w/ a non-empty vbucket map.
598
- if (config.vbmap && config.vbmap->size() == 0) {
599
- if (!config_) {
600
- CB_LOG_WARNING("{} will not initialize configuration rev={} because config has an empty partition map",
601
- log_prefix_,
602
- config.rev_str());
603
- } else {
604
- CB_LOG_WARNING("{} will not update the configuration old={} -> new={}, because new config has an empty partition map",
605
- log_prefix_,
606
- config_->rev_str(),
607
- config.rev_str());
608
- }
609
- // this is to make sure we can get a correct config soon
610
- poll_config(errc::network::configuration_not_available);
611
- return;
612
- } else if (!config_) {
613
- CB_LOG_DEBUG("{} initialize configuration rev={}", log_prefix_, config.rev_str());
614
- } else if (config.force) {
615
- CB_LOG_DEBUG("{} forced to accept configuration rev={}", log_prefix_, config.rev_str());
616
- } else if (!config.vbmap) {
617
- CB_LOG_DEBUG("{} will not update the configuration old={} -> new={}, because new config does not have partition map",
618
- log_prefix_,
619
- config_->rev_str(),
620
- config.rev_str());
621
- return;
622
- } else if (config_ < config) {
623
- CB_LOG_DEBUG("{} will update the configuration old={} -> new={}", log_prefix_, config_->rev_str(), config.rev_str());
624
- } else {
625
- return;
626
- }
627
-
628
- if (config_) {
629
- diff_nodes(config_->nodes, config.nodes, added);
630
- diff_nodes(config.nodes, config_->nodes, removed);
631
- if (added.empty() && removed.empty() && config.nodes.size() == config_->nodes.size()) {
632
- for (std::size_t i = 0; i < config.nodes.size(); ++i) {
633
- if (config.nodes[i] != config_->nodes[i]) {
634
- sequence_changed = true;
635
- break;
636
- }
637
- }
638
- } else {
639
- sequence_changed = true;
640
- }
641
- } else {
642
- sequence_changed = true;
643
- added = config.nodes;
644
- }
645
- config_.reset();
646
- config_ = config;
647
- configured_ = true;
648
-
649
- {
650
- std::scoped_lock listeners_lock(config_listeners_mutex_);
651
- for (const auto& listener : config_listeners_) {
652
- listener->update_config(*config_);
653
- }
654
- }
655
- }
656
- if (!added.empty() || !removed.empty() || sequence_changed) {
657
- std::scoped_lock lock(sessions_mutex_);
658
- std::map<size_t, io::mcbp_session> new_sessions{};
659
-
660
- std::size_t next_index{ 0 };
661
- for (const auto& node : config.nodes) {
662
- const auto& hostname = node.hostname_for(origin_.options().network);
663
- auto port = node.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
664
- if (port == 0) {
665
- continue;
666
- }
667
-
668
- bool reused_session{ false };
669
- for (auto it = sessions_.begin(); it != sessions_.end(); ++it) {
670
- if (it->second.bootstrap_hostname() == hostname && it->second.bootstrap_port_number() == port) {
671
- CB_LOG_DEBUG(R"({} rev={}, preserve session="{}", address="{}:{}", index={}->{})",
672
- log_prefix_,
673
- config.rev_str(),
674
- it->second.id(),
675
- it->second.bootstrap_hostname(),
676
- it->second.bootstrap_port(),
677
- it->first,
678
- next_index);
679
- new_sessions.insert_or_assign(next_index, std::move(it->second));
680
- reused_session = true;
681
- ++next_index;
682
- sessions_.erase(it);
683
- break;
684
- }
685
- }
686
- if (reused_session) {
687
- continue;
688
- }
689
-
690
- couchbase::core::origin origin(origin_.credentials(), hostname, port, origin_.options());
691
- io::mcbp_session session = origin_.options().enable_tls
692
- ? io::mcbp_session(client_id_, ctx_, tls_, origin, state_listener_, name_, known_features_)
693
- : io::mcbp_session(client_id_, ctx_, origin, state_listener_, name_, known_features_);
694
- CB_LOG_DEBUG(R"({} rev={}, add session="{}", address="{}:{}", index={})",
695
- log_prefix_,
696
- config.rev_str(),
697
- session.id(),
698
- hostname,
699
- port,
700
- node.index);
701
- session.bootstrap(
702
- [self = shared_from_this(), session, idx = next_index](std::error_code err, topology::configuration cfg) mutable {
703
- if (err) {
704
- CB_LOG_WARNING(R"({} failed to bootstrap session="{}", address="{}:{}", index={}, ec={})",
705
- session.log_prefix(),
706
- session.id(),
707
- session.bootstrap_hostname(),
708
- session.bootstrap_port(),
709
- idx,
710
- err.message());
711
- return self->remove_session(session.id());
712
- }
713
- self->update_config(std::move(cfg));
714
- session.on_configuration_update(self);
715
- session.on_stop([id = session.id(), self]() { self->remove_session(id); });
716
- self->drain_deferred_queue();
717
- },
718
- true);
719
- new_sessions.insert_or_assign(next_index, std::move(session));
720
- ++next_index;
721
- }
722
- std::swap(sessions_, new_sessions);
723
-
724
- for (auto it = new_sessions.begin(); it != new_sessions.end(); ++it) {
725
- CB_LOG_DEBUG(R"({} rev={}, drop session="{}", address="{}:{}", index={})",
726
- log_prefix_,
727
- config.rev_str(),
728
- it->second.id(),
729
- it->second.bootstrap_hostname(),
730
- it->second.bootstrap_port(),
731
- it->first);
732
- asio::post(asio::bind_executor(
733
- ctx_, [session = std::move(it->second)]() mutable { return session.stop(retry_reason::do_not_retry); }));
734
- }
735
- }
514
+ std::scoped_lock lock(deferred_commands_mutex_);
515
+ std::swap(deferred_commands_, commands);
736
516
  }
737
-
738
- [[nodiscard]] auto find_session_by_index(std::size_t index) const -> std::optional<io::mcbp_session>
739
- {
740
- std::scoped_lock lock(sessions_mutex_);
741
- if (auto ptr = sessions_.find(index); ptr != sessions_.end()) {
742
- return ptr->second;
743
- }
744
- return {};
517
+ if (!commands.empty()) {
518
+ CB_LOG_TRACE(
519
+ R"({} draining deferred operation queue, size={})", log_prefix_, commands.size());
520
+ }
521
+ while (!commands.empty()) {
522
+ commands.front()();
523
+ commands.pop();
745
524
  }
525
+ }
746
526
 
747
- [[nodiscard]] auto next_session_index() -> std::size_t
527
+ void fetch_config()
528
+ {
529
+ if (closed_) {
530
+ return;
531
+ }
532
+ std::optional<io::mcbp_session> session{};
748
533
  {
749
- std::scoped_lock lock(sessions_mutex_);
750
-
751
- if (auto index = round_robin_next_.fetch_add(1); index < sessions_.size()) {
752
- return index;
534
+ std::scoped_lock lock(sessions_mutex_);
535
+ if (sessions_.empty()) {
536
+ CB_LOG_WARNING(R"({} unable to find connected session (sessions_ is empty), retry in {})",
537
+ log_prefix_,
538
+ heartbeat_interval_);
539
+ return;
540
+ }
541
+
542
+ std::size_t start = heartbeat_next_index_.fetch_add(1);
543
+ std::size_t i = start;
544
+ do {
545
+ auto ptr = sessions_.find(i % sessions_.size());
546
+ if (ptr != sessions_.end() && ptr->second.is_bootstrapped() &&
547
+ ptr->second.supports_gcccp()) {
548
+ session = ptr->second;
753
549
  }
754
- round_robin_next_ = 0;
755
- return 0;
550
+ i = heartbeat_next_index_.fetch_add(1);
551
+ } while (start % sessions_.size() != i % sessions_.size());
756
552
  }
757
-
758
- [[nodiscard]] auto default_timeout() const -> std::chrono::milliseconds
759
- {
760
- return origin_.options().default_timeout_for(service_type::key_value);
553
+ if (session) {
554
+ protocol::client_request<protocol::get_cluster_config_request_body> req;
555
+ req.opaque(session->next_opaque());
556
+ session->write_and_flush(req.data());
557
+ } else {
558
+ CB_LOG_WARNING(R"({} unable to find connected session with GCCCP support, retry in {})",
559
+ log_prefix_,
560
+ heartbeat_interval_);
761
561
  }
562
+ }
762
563
 
763
- [[nodiscard]] auto name() const -> const std::string&
764
- {
765
- return name_;
564
+ void poll_config(std::error_code ec)
565
+ {
566
+ if (ec == asio::error::operation_aborted || closed_) {
567
+ return;
766
568
  }
767
-
768
- [[nodiscard]] auto log_prefix() const -> const std::string&
769
- {
770
- return client_id_;
569
+ if (heartbeat_timer_.expiry() > std::chrono::steady_clock::now()) {
570
+ return;
771
571
  }
772
572
 
773
- [[nodiscard]] auto is_closed() const -> bool
774
- {
775
- return closed_;
573
+ fetch_config();
574
+
575
+ heartbeat_timer_.expires_after(heartbeat_interval_);
576
+ return heartbeat_timer_.async_wait([self = shared_from_this()](std::error_code e) {
577
+ if (e == asio::error::operation_aborted) {
578
+ return;
579
+ }
580
+ self->poll_config(e);
581
+ });
582
+ }
583
+
584
+ void close()
585
+ {
586
+ if (bool expected_state{ false }; !closed_.compare_exchange_strong(expected_state, true)) {
587
+ return;
776
588
  }
777
589
 
778
- [[nodiscard]] auto is_configured() const -> bool
779
- {
780
- return configured_;
590
+ heartbeat_timer_.cancel();
591
+
592
+ drain_deferred_queue();
593
+
594
+ if (state_listener_ != nullptr) {
595
+ state_listener_->unregister_config_listener(shared_from_this());
781
596
  }
782
597
 
783
- [[nodiscard]] auto tracer() const -> std::shared_ptr<couchbase::tracing::request_tracer>
784
598
  {
785
- return tracer_;
599
+ std::scoped_lock lock(config_listeners_mutex_);
600
+ config_listeners_.clear();
786
601
  }
787
602
 
788
- [[nodiscard]] auto meter() const -> std::shared_ptr<couchbase::metrics::meter>
603
+ std::map<size_t, io::mcbp_session> old_sessions;
789
604
  {
790
- return meter_;
605
+ std::scoped_lock lock(sessions_mutex_);
606
+ std::swap(old_sessions, sessions_);
607
+ }
608
+ for (auto& [index, session] : old_sessions) {
609
+ session.stop(retry_reason::do_not_retry);
610
+ }
611
+ }
612
+
613
+ /**
614
+ * copies nodes from rhs that are not in lhs to output vector
615
+ */
616
+ void diff_nodes(const std::vector<topology::configuration::node>& lhs,
617
+ const std::vector<topology::configuration::node>& rhs,
618
+ std::vector<topology::configuration::node>& output)
619
+ {
620
+ for (const auto& re : rhs) {
621
+ bool known = false;
622
+ const auto& rhost = re.hostname_for(origin_.options().network);
623
+ const auto rport = re.port_or(
624
+ origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
625
+ for (const auto& le : lhs) {
626
+ const auto& lhost = le.hostname_for(origin_.options().network);
627
+ const auto lport = le.port_or(
628
+ origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
629
+ if (rhost == lhost && rport == lport) {
630
+ known = true;
631
+ break;
632
+ }
633
+ }
634
+ if (!known) {
635
+ output.push_back(re);
636
+ }
791
637
  }
638
+ }
792
639
 
793
- void export_diag_info(diag::diagnostics_result& res) const
640
+ void update_config(topology::configuration config) override
641
+ {
642
+ std::vector<topology::configuration::node> added{};
643
+ std::vector<topology::configuration::node> removed{};
644
+ bool sequence_changed = false;
794
645
  {
795
- std::map<size_t, io::mcbp_session> sessions;
796
- {
797
- std::scoped_lock lock(sessions_mutex_);
798
- sessions = sessions_;
646
+ std::scoped_lock lock(config_mutex_);
647
+ // MB-60405 fixes this for 7.6.2, but for earlier versions we need to protect against using a
648
+ // config that has an empty vbucket map. Ideally we only run into this condition on initial
649
+ // bootstrap and that is handled in the session's update_config(), but just in case, only
650
+ // accept a config w/ a non-empty vbucket map.
651
+ if (config.vbmap && config.vbmap->size() == 0) {
652
+ if (!config_) {
653
+ CB_LOG_WARNING(
654
+ "{} will not initialize configuration rev={} because config has an empty partition map",
655
+ log_prefix_,
656
+ config.rev_str());
657
+ } else {
658
+ CB_LOG_WARNING("{} will not update the configuration old={} -> new={}, because new "
659
+ "config has an empty partition map",
660
+ log_prefix_,
661
+ config_->rev_str(),
662
+ config.rev_str());
663
+ }
664
+ // this is to make sure we can get a correct config soon
665
+ poll_config(errc::network::configuration_not_available);
666
+ return;
667
+ } else if (!config_) {
668
+ CB_LOG_DEBUG("{} initialize configuration rev={}", log_prefix_, config.rev_str());
669
+ } else if (config.force) {
670
+ CB_LOG_DEBUG("{} forced to accept configuration rev={}", log_prefix_, config.rev_str());
671
+ } else if (!config.vbmap) {
672
+ CB_LOG_DEBUG("{} will not update the configuration old={} -> new={}, because new config "
673
+ "does not have partition map",
674
+ log_prefix_,
675
+ config_->rev_str(),
676
+ config.rev_str());
677
+ return;
678
+ } else if (config_ < config) {
679
+ CB_LOG_DEBUG("{} will update the configuration old={} -> new={}",
680
+ log_prefix_,
681
+ config_->rev_str(),
682
+ config.rev_str());
683
+ } else {
684
+ return;
685
+ }
686
+
687
+ if (config_) {
688
+ diff_nodes(config_->nodes, config.nodes, added);
689
+ diff_nodes(config.nodes, config_->nodes, removed);
690
+ if (added.empty() && removed.empty() && config.nodes.size() == config_->nodes.size()) {
691
+ for (std::size_t i = 0; i < config.nodes.size(); ++i) {
692
+ if (config.nodes[i] != config_->nodes[i]) {
693
+ sequence_changed = true;
694
+ break;
695
+ }
696
+ }
697
+ } else {
698
+ sequence_changed = true;
799
699
  }
800
- for (const auto& [index, session] : sessions) {
801
- res.services[service_type::key_value].emplace_back(session.diag_info());
700
+ } else {
701
+ sequence_changed = true;
702
+ added = config.nodes;
703
+ }
704
+ config_.reset();
705
+ config_ = config;
706
+ configured_ = true;
707
+
708
+ {
709
+ std::scoped_lock listeners_lock(config_listeners_mutex_);
710
+ for (const auto& listener : config_listeners_) {
711
+ listener->update_config(*config_);
802
712
  }
713
+ }
803
714
  }
715
+ if (!added.empty() || !removed.empty() || sequence_changed) {
716
+ std::scoped_lock lock(sessions_mutex_);
717
+ std::map<size_t, io::mcbp_session> new_sessions{};
718
+
719
+ std::size_t next_index{ 0 };
720
+ for (const auto& node : config.nodes) {
721
+ const auto& hostname = node.hostname_for(origin_.options().network);
722
+ auto port = node.port_or(
723
+ origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
724
+ if (port == 0) {
725
+ continue;
726
+ }
804
727
 
805
- void ping(std::shared_ptr<diag::ping_collector> collector, std::optional<std::chrono::milliseconds> timeout)
806
- {
807
- std::map<size_t, io::mcbp_session> sessions;
808
- {
809
- std::scoped_lock lock(sessions_mutex_);
810
- sessions = sessions_;
728
+ bool reused_session{ false };
729
+ for (auto it = sessions_.begin(); it != sessions_.end(); ++it) {
730
+ if (it->second.bootstrap_hostname() == hostname &&
731
+ it->second.bootstrap_port_number() == port) {
732
+ CB_LOG_DEBUG(R"({} rev={}, preserve session="{}", address="{}:{}", index={}->{})",
733
+ log_prefix_,
734
+ config.rev_str(),
735
+ it->second.id(),
736
+ it->second.bootstrap_hostname(),
737
+ it->second.bootstrap_port(),
738
+ it->first,
739
+ next_index);
740
+ new_sessions.insert_or_assign(next_index, std::move(it->second));
741
+ reused_session = true;
742
+ ++next_index;
743
+ sessions_.erase(it);
744
+ break;
745
+ }
811
746
  }
812
- for (const auto& [index, session] : sessions) {
813
- session.ping(collector->build_reporter(), timeout);
747
+ if (reused_session) {
748
+ continue;
814
749
  }
815
- }
816
750
 
817
- auto default_retry_strategy() const -> std::shared_ptr<couchbase::retry_strategy>
818
- {
819
- return origin_.options().default_retry_strategy_;
751
+ couchbase::core::origin origin(origin_.credentials(), hostname, port, origin_.options());
752
+ io::mcbp_session session =
753
+ origin_.options().enable_tls
754
+ ? io::mcbp_session(
755
+ client_id_, ctx_, tls_, origin, state_listener_, name_, known_features_)
756
+ : io::mcbp_session(client_id_, ctx_, origin, state_listener_, name_, known_features_);
757
+ CB_LOG_DEBUG(R"({} rev={}, add session="{}", address="{}:{}", index={})",
758
+ log_prefix_,
759
+ config.rev_str(),
760
+ session.id(),
761
+ hostname,
762
+ port,
763
+ node.index);
764
+ session.bootstrap(
765
+ [self = shared_from_this(), session, idx = next_index](
766
+ std::error_code err, topology::configuration cfg) mutable {
767
+ if (err) {
768
+ CB_LOG_WARNING(
769
+ R"({} failed to bootstrap session="{}", address="{}:{}", index={}, ec={})",
770
+ session.log_prefix(),
771
+ session.id(),
772
+ session.bootstrap_hostname(),
773
+ session.bootstrap_port(),
774
+ idx,
775
+ err.message());
776
+ return self->remove_session(session.id());
777
+ }
778
+ self->update_config(std::move(cfg));
779
+ session.on_configuration_update(self);
780
+ session.on_stop([id = session.id(), self]() {
781
+ self->remove_session(id);
782
+ });
783
+ self->drain_deferred_queue();
784
+ },
785
+ true);
786
+ new_sessions.insert_or_assign(next_index, std::move(session));
787
+ ++next_index;
788
+ }
789
+ std::swap(sessions_, new_sessions);
790
+
791
+ for (auto it = new_sessions.begin(); it != new_sessions.end(); ++it) {
792
+ CB_LOG_DEBUG(R"({} rev={}, drop session="{}", address="{}:{}", index={})",
793
+ log_prefix_,
794
+ config.rev_str(),
795
+ it->second.id(),
796
+ it->second.bootstrap_hostname(),
797
+ it->second.bootstrap_port(),
798
+ it->first);
799
+ asio::post(asio::bind_executor(ctx_, [session = std::move(it->second)]() mutable {
800
+ return session.stop(retry_reason::do_not_retry);
801
+ }));
802
+ }
803
+ }
804
+ }
805
+
806
+ [[nodiscard]] auto find_session_by_index(std::size_t index) const
807
+ -> std::optional<io::mcbp_session>
808
+ {
809
+ std::scoped_lock lock(sessions_mutex_);
810
+ if (auto ptr = sessions_.find(index); ptr != sessions_.end()) {
811
+ return ptr->second;
820
812
  }
813
+ return {};
814
+ }
815
+
816
+ [[nodiscard]] auto next_session_index() -> std::size_t
817
+ {
818
+ std::scoped_lock lock(sessions_mutex_);
821
819
 
822
- void on_configuration_update(std::shared_ptr<config_listener> handler)
820
+ if (auto index = round_robin_next_.fetch_add(1); index < sessions_.size()) {
821
+ return index;
822
+ }
823
+ round_robin_next_ = 0;
824
+ return 0;
825
+ }
826
+
827
+ [[nodiscard]] auto default_timeout() const -> std::chrono::milliseconds
828
+ {
829
+ return origin_.options().default_timeout_for(service_type::key_value);
830
+ }
831
+
832
+ [[nodiscard]] auto name() const -> const std::string&
833
+ {
834
+ return name_;
835
+ }
836
+
837
+ [[nodiscard]] auto log_prefix() const -> const std::string&
838
+ {
839
+ return client_id_;
840
+ }
841
+
842
+ [[nodiscard]] auto is_closed() const -> bool
843
+ {
844
+ return closed_;
845
+ }
846
+
847
+ [[nodiscard]] auto is_configured() const -> bool
848
+ {
849
+ return configured_;
850
+ }
851
+
852
+ [[nodiscard]] auto tracer() const -> std::shared_ptr<couchbase::tracing::request_tracer>
853
+ {
854
+ return tracer_;
855
+ }
856
+
857
+ [[nodiscard]] auto meter() const -> std::shared_ptr<couchbase::metrics::meter>
858
+ {
859
+ return meter_;
860
+ }
861
+
862
+ void export_diag_info(diag::diagnostics_result& res) const
863
+ {
864
+ std::map<size_t, io::mcbp_session> sessions;
823
865
  {
824
- std::scoped_lock lock(config_listeners_mutex_);
825
- config_listeners_.emplace_back(std::move(handler));
866
+ std::scoped_lock lock(sessions_mutex_);
867
+ sessions = sessions_;
868
+ }
869
+ for (const auto& [index, session] : sessions) {
870
+ res.services[service_type::key_value].emplace_back(session.diag_info());
826
871
  }
872
+ }
827
873
 
828
- auto defer_command(utils::movable_function<void()> command) -> std::error_code
874
+ void ping(std::shared_ptr<diag::ping_collector> collector,
875
+ std::optional<std::chrono::milliseconds> timeout)
876
+ {
877
+ std::map<size_t, io::mcbp_session> sessions;
829
878
  {
830
- std::scoped_lock lock_for_deferred_commands(deferred_commands_mutex_);
831
- deferred_commands_.emplace(std::move(command));
832
- return {};
879
+ std::scoped_lock lock(sessions_mutex_);
880
+ sessions = sessions_;
833
881
  }
834
-
835
- private:
836
- const std::string client_id_;
837
- const std::string name_;
838
- const std::string log_prefix_;
839
- const origin origin_;
840
- const std::shared_ptr<couchbase::tracing::request_tracer> tracer_;
841
- const std::shared_ptr<couchbase::metrics::meter> meter_;
842
- const std::vector<protocol::hello_feature> known_features_;
843
- const std::shared_ptr<impl::bootstrap_state_listener> state_listener_;
844
- mcbp::codec codec_;
845
-
846
- asio::io_context& ctx_;
847
- asio::ssl::context& tls_;
848
-
849
- asio::steady_timer heartbeat_timer_;
850
- std::chrono::milliseconds heartbeat_interval_;
851
- std::atomic_size_t heartbeat_next_index_{ 0 };
852
-
853
- std::atomic_bool closed_{ false };
854
- std::atomic_bool configured_{ false };
855
-
856
- std::optional<topology::configuration> config_{};
857
- mutable std::mutex config_mutex_{};
858
-
859
- std::vector<std::shared_ptr<config_listener>> config_listeners_{};
860
- std::mutex config_listeners_mutex_{};
861
-
862
- std::queue<utils::movable_function<void()>> deferred_commands_{};
863
- std::mutex deferred_commands_mutex_{};
864
-
865
- std::map<size_t, io::mcbp_session> sessions_{};
866
- mutable std::mutex sessions_mutex_{};
867
- std::atomic_size_t round_robin_next_{ 0 };
882
+ for (const auto& [index, session] : sessions) {
883
+ session.ping(collector->build_reporter(), timeout);
884
+ }
885
+ }
886
+
887
+ auto default_retry_strategy() const -> std::shared_ptr<couchbase::retry_strategy>
888
+ {
889
+ return origin_.options().default_retry_strategy_;
890
+ }
891
+
892
+ void on_configuration_update(std::shared_ptr<config_listener> handler)
893
+ {
894
+ std::scoped_lock lock(config_listeners_mutex_);
895
+ config_listeners_.emplace_back(std::move(handler));
896
+ }
897
+
898
+ auto defer_command(utils::movable_function<void()> command) -> std::error_code
899
+ {
900
+ std::scoped_lock lock_for_deferred_commands(deferred_commands_mutex_);
901
+ deferred_commands_.emplace(std::move(command));
902
+ return {};
903
+ }
904
+
905
+ private:
906
+ const std::string client_id_;
907
+ const std::string name_;
908
+ const std::string log_prefix_;
909
+ const origin origin_;
910
+ const std::shared_ptr<couchbase::tracing::request_tracer> tracer_;
911
+ const std::shared_ptr<couchbase::metrics::meter> meter_;
912
+ const std::vector<protocol::hello_feature> known_features_;
913
+ const std::shared_ptr<impl::bootstrap_state_listener> state_listener_;
914
+ mcbp::codec codec_;
915
+
916
+ asio::io_context& ctx_;
917
+ asio::ssl::context& tls_;
918
+
919
+ asio::steady_timer heartbeat_timer_;
920
+ std::chrono::milliseconds heartbeat_interval_;
921
+ std::atomic_size_t heartbeat_next_index_{ 0 };
922
+
923
+ std::atomic_bool closed_{ false };
924
+ std::atomic_bool configured_{ false };
925
+
926
+ std::optional<topology::configuration> config_{};
927
+ mutable std::mutex config_mutex_{};
928
+
929
+ std::vector<std::shared_ptr<config_listener>> config_listeners_{};
930
+ std::mutex config_listeners_mutex_{};
931
+
932
+ std::queue<utils::movable_function<void()>> deferred_commands_{};
933
+ std::mutex deferred_commands_mutex_{};
934
+
935
+ std::map<size_t, io::mcbp_session> sessions_{};
936
+ mutable std::mutex sessions_mutex_{};
937
+ std::atomic_size_t round_robin_next_{ 0 };
868
938
  };
869
939
 
870
940
  bucket::bucket(std::string client_id,
@@ -892,144 +962,146 @@ bucket::bucket(std::string client_id,
892
962
 
893
963
  bucket::~bucket()
894
964
  {
895
- impl_->close();
965
+ impl_->close();
896
966
  }
897
967
 
898
968
  void
899
969
  bucket::export_diag_info(diag::diagnostics_result& res) const
900
970
  {
901
- return impl_->export_diag_info(res);
971
+ return impl_->export_diag_info(res);
902
972
  }
903
973
 
904
974
  void
905
- bucket::ping(std::shared_ptr<diag::ping_collector> collector, std::optional<std::chrono::milliseconds> timeout)
975
+ bucket::ping(std::shared_ptr<diag::ping_collector> collector,
976
+ std::optional<std::chrono::milliseconds> timeout)
906
977
  {
907
- return impl_->ping(std::move(collector), std::move(timeout));
978
+ return impl_->ping(std::move(collector), std::move(timeout));
908
979
  }
909
980
 
910
981
  void
911
982
  bucket::fetch_config()
912
983
  {
913
- return impl_->fetch_config();
984
+ return impl_->fetch_config();
914
985
  }
915
986
 
916
987
  void
917
988
  bucket::update_config(topology::configuration config)
918
989
  {
919
- return impl_->update_config(std::move(config));
990
+ return impl_->update_config(std::move(config));
920
991
  }
921
992
 
922
993
  const std::string&
923
994
  bucket::name() const
924
995
  {
925
- return impl_->name();
996
+ return impl_->name();
926
997
  }
927
998
 
928
999
  void
929
1000
  bucket::close()
930
1001
  {
931
- return impl_->close();
1002
+ return impl_->close();
932
1003
  }
933
1004
 
934
1005
  const std::string&
935
1006
  bucket::log_prefix() const
936
1007
  {
937
- return impl_->log_prefix();
1008
+ return impl_->log_prefix();
938
1009
  }
939
1010
 
940
1011
  auto
941
1012
  bucket::tracer() const -> std::shared_ptr<couchbase::tracing::request_tracer>
942
1013
  {
943
- return impl_->tracer();
1014
+ return impl_->tracer();
944
1015
  }
945
1016
 
946
1017
  auto
947
1018
  bucket::meter() const -> std::shared_ptr<couchbase::metrics::meter>
948
1019
  {
949
- return impl_->meter();
1020
+ return impl_->meter();
950
1021
  }
951
1022
 
952
1023
  auto
953
1024
  bucket::default_retry_strategy() const -> std::shared_ptr<couchbase::retry_strategy>
954
1025
  {
955
- return impl_->default_retry_strategy();
1026
+ return impl_->default_retry_strategy();
956
1027
  }
957
1028
 
958
1029
  void
959
1030
  bucket::on_configuration_update(std::shared_ptr<config_listener> handler)
960
1031
  {
961
- return impl_->on_configuration_update(std::move(handler));
1032
+ return impl_->on_configuration_update(std::move(handler));
962
1033
  }
963
1034
 
964
1035
  void
965
1036
  bucket::bootstrap(utils::movable_function<void(std::error_code, topology::configuration)>&& handler)
966
1037
  {
967
- return impl_->bootstrap(std::move(handler));
1038
+ return impl_->bootstrap(std::move(handler));
968
1039
  }
969
1040
 
970
1041
  void
971
- bucket::with_configuration(utils::movable_function<void(std::error_code, topology::configuration)>&& handler)
1042
+ bucket::with_configuration(
1043
+ utils::movable_function<void(std::error_code, topology::configuration)>&& handler)
972
1044
  {
973
- return impl_->with_configuration(std::move(handler));
1045
+ return impl_->with_configuration(std::move(handler));
974
1046
  }
975
1047
 
976
1048
  auto
977
1049
  bucket::is_closed() const -> bool
978
1050
  {
979
- return impl_->is_closed();
1051
+ return impl_->is_closed();
980
1052
  }
981
1053
 
982
1054
  auto
983
1055
  bucket::is_configured() const -> bool
984
1056
  {
985
- return impl_->is_configured();
1057
+ return impl_->is_configured();
986
1058
  }
987
1059
 
988
1060
  void
989
1061
  bucket::defer_command(utils::movable_function<void()> command)
990
1062
  {
991
- impl_->defer_command(std::move(command));
1063
+ impl_->defer_command(std::move(command));
992
1064
  }
993
1065
 
994
1066
  auto
995
1067
  bucket::default_timeout() const -> std::chrono::milliseconds
996
1068
  {
997
- return impl_->default_timeout();
1069
+ return impl_->default_timeout();
998
1070
  }
999
1071
 
1000
1072
  auto
1001
1073
  bucket::find_session_by_index(std::size_t index) const -> std::optional<io::mcbp_session>
1002
1074
  {
1003
- return impl_->find_session_by_index(index);
1075
+ return impl_->find_session_by_index(index);
1004
1076
  }
1005
1077
 
1006
1078
  auto
1007
1079
  bucket::next_session_index() -> std::size_t
1008
1080
  {
1009
- return impl_->next_session_index();
1081
+ return impl_->next_session_index();
1010
1082
  }
1011
1083
 
1012
1084
  auto
1013
1085
  bucket::map_id(const document_id& id) -> std::pair<std::uint16_t, std::optional<std::size_t>>
1014
1086
  {
1015
- return impl_->map_id(id);
1087
+ return impl_->map_id(id);
1016
1088
  }
1017
1089
 
1018
1090
  auto
1019
1091
  bucket::config_rev() const -> std::string
1020
1092
  {
1021
- return impl_->config_rev();
1093
+ return impl_->config_rev();
1022
1094
  }
1023
1095
 
1024
1096
  auto
1025
1097
  bucket::direct_dispatch(std::shared_ptr<mcbp::queue_request> req) -> std::error_code
1026
1098
  {
1027
- return impl_->direct_dispatch(std::move(req));
1099
+ return impl_->direct_dispatch(std::move(req));
1028
1100
  }
1029
1101
 
1030
1102
  auto
1031
1103
  bucket::direct_re_queue(std::shared_ptr<mcbp::queue_request> req, bool is_retry) -> std::error_code
1032
1104
  {
1033
- return impl_->direct_re_queue(std::move(req), is_retry);
1105
+ return impl_->direct_re_queue(std::move(req), is_retry);
1034
1106
  }
1035
1107
  } // namespace couchbase::core