couchbase 4.4.2 → 4.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. package/CMakeLists.txt +2 -0
  2. package/deps/couchbase-cxx-client/CMakeLists.txt +17 -14
  3. package/deps/couchbase-cxx-client/README.md +2 -2
  4. package/deps/couchbase-cxx-client/cmake/Packaging.cmake +4 -0
  5. package/deps/couchbase-cxx-client/cmake/Testing.cmake +1 -1
  6. package/deps/couchbase-cxx-client/cmake/VersionInfo.cmake +24 -2
  7. package/deps/couchbase-cxx-client/cmake/couchbase-cxx-client.spec.in +43 -4
  8. package/deps/couchbase-cxx-client/core/agent_group.cxx +8 -0
  9. package/deps/couchbase-cxx-client/core/agent_group.hxx +4 -0
  10. package/deps/couchbase-cxx-client/core/bucket.cxx +16 -20
  11. package/deps/couchbase-cxx-client/core/bucket.hxx +12 -12
  12. package/deps/couchbase-cxx-client/core/cluster.cxx +44 -52
  13. package/deps/couchbase-cxx-client/core/cluster_agent.cxx +8 -0
  14. package/deps/couchbase-cxx-client/core/cluster_agent.hxx +4 -0
  15. package/deps/couchbase-cxx-client/core/collections_component.cxx +2 -2
  16. package/deps/couchbase-cxx-client/core/columnar/agent.cxx +2 -2
  17. package/deps/couchbase-cxx-client/core/columnar/agent.hxx +1 -1
  18. package/deps/couchbase-cxx-client/core/columnar/management_component.cxx +3 -3
  19. package/deps/couchbase-cxx-client/core/columnar/query_component.cxx +103 -45
  20. package/deps/couchbase-cxx-client/core/columnar/query_component.hxx +1 -0
  21. package/deps/couchbase-cxx-client/core/free_form_http_request.hxx +8 -0
  22. package/deps/couchbase-cxx-client/core/http_component.cxx +55 -24
  23. package/deps/couchbase-cxx-client/core/http_component.hxx +4 -0
  24. package/deps/couchbase-cxx-client/core/impl/analytics_index_manager.cxx +15 -15
  25. package/deps/couchbase-cxx-client/core/impl/bootstrap_error.hxx +10 -2
  26. package/deps/couchbase-cxx-client/core/impl/bucket.cxx +1 -1
  27. package/deps/couchbase-cxx-client/core/impl/bucket_manager.cxx +6 -6
  28. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +36 -40
  29. package/deps/couchbase-cxx-client/core/impl/collection.cxx +2 -2
  30. package/deps/couchbase-cxx-client/core/impl/collection_manager.cxx +5 -5
  31. package/deps/couchbase-cxx-client/core/impl/observe_poll.cxx +13 -5
  32. package/deps/couchbase-cxx-client/core/impl/observe_poll.hxx +1 -3
  33. package/deps/couchbase-cxx-client/core/impl/query_index_manager.cxx +6 -6
  34. package/deps/couchbase-cxx-client/core/impl/scan_result.cxx +1 -1
  35. package/deps/couchbase-cxx-client/core/impl/search_index_manager.cxx +12 -12
  36. package/deps/couchbase-cxx-client/core/io/http_command.hxx +31 -20
  37. package/deps/couchbase-cxx-client/core/io/http_session.cxx +5 -0
  38. package/deps/couchbase-cxx-client/core/io/http_session.hxx +17 -4
  39. package/deps/couchbase-cxx-client/core/io/http_session_manager.hxx +97 -49
  40. package/deps/couchbase-cxx-client/core/io/mcbp_command.hxx +15 -14
  41. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +48 -33
  42. package/deps/couchbase-cxx-client/core/io/streams.cxx +256 -0
  43. package/deps/couchbase-cxx-client/core/io/streams.hxx +31 -155
  44. package/deps/couchbase-cxx-client/core/logger/configuration.hxx +5 -0
  45. package/deps/couchbase-cxx-client/core/logger/custom_rotating_file_sink.cxx +2 -3
  46. package/deps/couchbase-cxx-client/core/logger/logger.cxx +39 -7
  47. package/deps/couchbase-cxx-client/core/logger/logger.hxx +7 -0
  48. package/deps/couchbase-cxx-client/core/metrics/meter_wrapper.cxx +188 -0
  49. package/deps/couchbase-cxx-client/core/metrics/meter_wrapper.hxx +73 -0
  50. package/deps/couchbase-cxx-client/core/operations/management/bucket_describe.cxx +2 -1
  51. package/deps/couchbase-cxx-client/core/operations/management/bucket_drop.cxx +3 -1
  52. package/deps/couchbase-cxx-client/core/operations/management/bucket_flush.cxx +3 -1
  53. package/deps/couchbase-cxx-client/core/operations/management/bucket_get.cxx +3 -1
  54. package/deps/couchbase-cxx-client/core/operations/management/bucket_update.cxx +3 -1
  55. package/deps/couchbase-cxx-client/core/operations/management/collection_create.cxx +3 -2
  56. package/deps/couchbase-cxx-client/core/operations/management/collection_drop.cxx +5 -2
  57. package/deps/couchbase-cxx-client/core/operations/management/collection_update.cxx +4 -2
  58. package/deps/couchbase-cxx-client/core/operations/management/group_upsert.cxx +3 -3
  59. package/deps/couchbase-cxx-client/core/operations/management/scope_create.cxx +2 -1
  60. package/deps/couchbase-cxx-client/core/operations/management/scope_drop.cxx +4 -1
  61. package/deps/couchbase-cxx-client/core/operations/management/scope_get_all.cxx +3 -1
  62. package/deps/couchbase-cxx-client/core/operations/management/search_index_analyze_document.cxx +3 -2
  63. package/deps/couchbase-cxx-client/core/operations/management/search_index_control_ingest.cxx +3 -2
  64. package/deps/couchbase-cxx-client/core/operations/management/search_index_control_plan_freeze.cxx +3 -2
  65. package/deps/couchbase-cxx-client/core/operations/management/search_index_control_query.cxx +3 -2
  66. package/deps/couchbase-cxx-client/core/operations/management/search_index_drop.cxx +5 -2
  67. package/deps/couchbase-cxx-client/core/operations/management/search_index_get.cxx +5 -2
  68. package/deps/couchbase-cxx-client/core/operations/management/search_index_get_all.cxx +4 -2
  69. package/deps/couchbase-cxx-client/core/operations/management/search_index_get_documents_count.cxx +3 -2
  70. package/deps/couchbase-cxx-client/core/operations/management/search_index_upsert.cxx +5 -2
  71. package/deps/couchbase-cxx-client/core/operations/management/view_index_drop.cxx +2 -1
  72. package/deps/couchbase-cxx-client/core/operations/management/view_index_get.cxx +2 -1
  73. package/deps/couchbase-cxx-client/core/operations/management/view_index_get_all.cxx +3 -1
  74. package/deps/couchbase-cxx-client/core/operations/management/view_index_upsert.cxx +2 -1
  75. package/deps/couchbase-cxx-client/core/origin.cxx +37 -17
  76. package/deps/couchbase-cxx-client/core/platform/base64.cc +1 -1
  77. package/deps/couchbase-cxx-client/core/platform/random.cc +2 -0
  78. package/deps/couchbase-cxx-client/core/platform/uuid.h +6 -6
  79. package/deps/couchbase-cxx-client/core/row_streamer.cxx +1 -1
  80. package/deps/couchbase-cxx-client/core/sasl/scram-sha/stringutils.cc +1 -1
  81. package/deps/couchbase-cxx-client/core/sasl/scram-sha/stringutils.h +4 -4
  82. package/deps/couchbase-cxx-client/core/topology/configuration.hxx +2 -0
  83. package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +8 -0
  84. package/deps/couchbase-cxx-client/core/tracing/constants.hxx +3 -0
  85. package/deps/couchbase-cxx-client/core/tracing/tracer_wrapper.cxx +87 -0
  86. package/deps/couchbase-cxx-client/core/tracing/tracer_wrapper.hxx +57 -0
  87. package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.cxx +16 -15
  88. package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.hxx +2 -2
  89. package/deps/couchbase-cxx-client/core/transactions/staged_mutation.cxx +2 -2
  90. package/deps/couchbase-cxx-client/core/transactions/transactions.cxx +2 -2
  91. package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +128 -52
  92. package/deps/couchbase-cxx-client/couchbase/analytics_options.hxx +4 -3
  93. package/deps/couchbase-cxx-client/couchbase/codec/tao_json_serializer.hxx +1 -1
  94. package/deps/couchbase-cxx-client/couchbase/mutate_in_specs.hxx +2 -2
  95. package/deps/couchbase-cxx-client/couchbase/query_options.hxx +4 -3
  96. package/deps/couchbase-cxx-client/couchbase/search_options.hxx +1 -1
  97. package/package.json +8 -8
  98. package/src/binding.cpp +13 -13
@@ -49,7 +49,7 @@ public:
49
49
 
50
50
  auto free_form_http_request(const http_request& request,
51
51
  free_form_http_request_callback&& callback)
52
- -> tl::expected<std::shared_ptr<pending_operation>, std::error_code>
52
+ -> tl::expected<std::shared_ptr<pending_operation>, error_union>
53
53
  {
54
54
  return http_.do_http_request(request, std::move(callback));
55
55
  }
@@ -102,7 +102,7 @@ agent::agent(asio::io_context& io, couchbase::core::columnar::agent_config confi
102
102
  auto
103
103
  agent::free_form_http_request(const http_request& request,
104
104
  free_form_http_request_callback&& callback)
105
- -> tl::expected<std::shared_ptr<pending_operation>, std::error_code>
105
+ -> tl::expected<std::shared_ptr<pending_operation>, error_union>
106
106
  {
107
107
  return impl_->free_form_http_request(request, std::move(callback));
108
108
  }
@@ -46,7 +46,7 @@ public:
46
46
 
47
47
  auto free_form_http_request(const http_request& request,
48
48
  free_form_http_request_callback&& callback)
49
- -> tl::expected<std::shared_ptr<pending_operation>, std::error_code>;
49
+ -> tl::expected<std::shared_ptr<pending_operation>, error_union>;
50
50
 
51
51
  auto free_form_http_request_buffered(const http_request& request,
52
52
  buffered_free_form_http_request_callback&& callback)
@@ -189,7 +189,7 @@ public:
189
189
  "SELECT d.* FROM `System`.`Metadata`.`Database` AS d",
190
190
  options.timeout,
191
191
  };
192
- return execute(std::move(req), [cb = std::move(callback)](auto raw_res, auto err) {
192
+ return execute(std::move(req), [cb = std::move(callback)](const auto& raw_res, auto err) {
193
193
  if (err) {
194
194
  cb({}, std::move(err));
195
195
  return;
@@ -216,7 +216,7 @@ public:
216
216
  if (options.ignore_if_exists) {
217
217
  req.statement += " IF NOT EXISTS";
218
218
  }
219
- return execute(std::move(req), [cb = std::move(callback)](auto /*raw_res*/, auto err) {
219
+ return execute(std::move(req), [cb = std::move(callback)](const auto& /*raw_res*/, auto err) {
220
220
  cb(std::move(err));
221
221
  });
222
222
  }
@@ -231,7 +231,7 @@ public:
231
231
  if (options.ignore_if_not_exists) {
232
232
  req.statement += " IF EXISTS";
233
233
  }
234
- return execute(std::move(req), [cb = std::move(callback)](auto /*raw_res*/, auto err) {
234
+ return execute(std::move(req), [cb = std::move(callback)](const auto& /*raw_res*/, auto err) {
235
235
  cb(std::move(err));
236
236
  });
237
237
  }
@@ -79,17 +79,28 @@ public:
79
79
 
80
80
  auto dispatch() -> error
81
81
  {
82
- auto op =
83
- http_.do_http_request(http_req_, [self = shared_from_this()](auto resp, auto ec) mutable {
82
+ auto op = http_.do_http_request(
83
+ http_req_, [self = shared_from_this()](auto resp, error_union err) mutable {
84
84
  std::shared_ptr<pending_operation> op;
85
85
  {
86
86
  const std::scoped_lock lock{ self->pending_op_mutex_ };
87
87
  std::swap(op, self->pending_op_);
88
88
  }
89
- if (ec) {
90
- self->invoke_callback(
91
- {},
92
- { maybe_convert_error_code(ec), "Failed to execute the HTTP request for the query" });
89
+ if (!std::holds_alternative<std::monostate>(err)) {
90
+ if (std::holds_alternative<impl::bootstrap_error>(err)) {
91
+ auto bootstrap_error = std::get<impl::bootstrap_error>(err);
92
+ auto message = fmt::format(
93
+ "Failed to execute the HTTP request for the query due to a bootstrap error. "
94
+ "See logs for further details. bootstrap_error.message={}",
95
+ bootstrap_error.error_message);
96
+ self->invoke_callback({}, { maybe_convert_error_code(bootstrap_error.ec), message });
97
+ } else {
98
+ auto ec = maybe_convert_error_code(std::get<std::error_code>(err));
99
+ if (ec == errc::timeout) {
100
+ return self->trigger_timeout();
101
+ }
102
+ self->invoke_callback({}, { ec, "Failed to execute the HTTP request for the query" });
103
+ }
93
104
  return;
94
105
  }
95
106
  // op can be null if the pending_query_operation was cancelled.
@@ -101,7 +112,7 @@ public:
101
112
  }
102
113
  auto streamer = std::make_shared<row_streamer>(self->io_, resp.body(), "/results/^");
103
114
  return streamer->start(
104
- [self, streamer, resp = std::move(resp)](auto metadata_header, auto ec) mutable {
115
+ [self, streamer, resp = std::move(resp)](const auto& metadata_header, auto ec) mutable {
105
116
  if (ec) {
106
117
  self->invoke_callback({}, { maybe_convert_error_code(ec) });
107
118
  return;
@@ -127,7 +138,27 @@ public:
127
138
  pending_op_ = op.value();
128
139
  return {};
129
140
  }
130
- return error{ op.error() };
141
+ retry_timer_.cancel();
142
+ deadline_.cancel();
143
+ error return_error{};
144
+ #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
145
+ if (std::holds_alternative<impl::bootstrap_error>(op.error())) {
146
+ auto bootstrap_error = std::get<impl::bootstrap_error>(op.error());
147
+ auto message =
148
+ fmt::format("Failed to create the HTTP pending operation due to a bootstrap error. "
149
+ "See logs for further details. bootstrap_error.message={}",
150
+ bootstrap_error.error_message);
151
+ return_error.ec = bootstrap_error.ec;
152
+ return_error.message = message;
153
+ } else {
154
+ return_error.ec = std::get<std::error_code>(op.error());
155
+ return_error.message = "Failed to create the HTTP pending operation.";
156
+ }
157
+ #else
158
+ return_error.ec = op.error();
159
+ #endif
160
+ invoke_callback({}, return_error);
161
+ return return_error;
131
162
  }
132
163
 
133
164
  auto start(query_callback&& callback) -> error
@@ -252,11 +283,13 @@ private:
252
283
  break;
253
284
  }
254
285
  }
286
+
287
+ const std::chrono::milliseconds server_timeout = timeout_ + std::chrono::seconds(5);
288
+ payload["timeout"] = fmt::format("{}ms", server_timeout.count());
289
+
255
290
  for (const auto& [key, val] : options.raw) {
256
291
  payload[key] = utils::json::parse(val);
257
292
  }
258
- const std::chrono::milliseconds server_timeout = timeout_ + std::chrono::seconds(5);
259
- payload["timeout"] = fmt::format("{}ms", server_timeout.count());
260
293
 
261
294
  return payload;
262
295
  }
@@ -296,7 +329,7 @@ private:
296
329
  // retryable errors should be listed.
297
330
  if (err.ec == errc::timeout && retry_info_.last_error) {
298
331
  if (const auto* e = retry_info_.last_error.ctx.find("errors"); e != nullptr) {
299
- err.ctx["last_errors"] = e;
332
+ err.ctx["last_errors"] = e->get_array();
300
333
  }
301
334
  }
302
335
  }
@@ -334,53 +367,71 @@ private:
334
367
  std::int32_t first_error_code{ 0 };
335
368
  std::string first_error_msg{};
336
369
 
370
+ std::int32_t first_non_retr_error_code{ 0 };
371
+ std::string first_non_retr_error_msg{};
372
+
337
373
  for (auto error_json : errors_json->get_array()) {
338
- auto* retr = error_json.find("retriable");
339
- if (retr == nullptr) {
340
- // An error is assumed to not be retriable if the field is missing
341
- res.retriable = false;
342
- } else if (!retr->is_boolean()) {
343
- return { { errc::generic,
344
- "Could not parse error from server response - 'retriable' was not boolean" } };
345
- } else {
346
- // Operation is retriable iff all errors are retriable
347
- res.retriable = res.retriable && retr->get_boolean();
374
+ bool retr{ false }; // An error is assumed to not be retriable if the field is missing
375
+ {
376
+ auto* r = error_json.find("retriable");
377
+ if (r != nullptr) {
378
+ if (!r->is_boolean()) {
379
+ return {
380
+ { errc::generic,
381
+ "Could not parse error from server response - 'retriable' was not boolean" }
382
+ };
383
+ }
384
+ retr = r->get_boolean();
385
+ }
348
386
  }
349
387
 
350
- auto* msg = error_json.find("msg");
351
- if (msg == nullptr) {
352
- return { { errc::generic,
353
- "Could not parse error from server response - could not find 'msg' field" } };
354
- }
355
- if (!msg->is_string()) {
356
- return { { errc::generic,
357
- "Could not parse error from server response - 'msg' field was not string" } };
358
- }
388
+ // Operation is retriable iff all errors are retriable
389
+ res.retriable = res.retriable && retr;
359
390
 
360
- auto* c = error_json.find("code");
361
- if (c == nullptr) {
362
- return { { errc::generic,
363
- "Could not parse error from server response - could not find 'code' field" } };
364
- }
365
- if (!(c->is_unsigned() || c->is_signed())) {
366
- return {
367
- { errc::generic,
368
- "Could not parse error from server response - 'code' field was not an integer" }
369
- };
391
+ std::string msg{};
392
+ {
393
+ auto* m = error_json.find("msg");
394
+ if (m == nullptr) {
395
+ return { { errc::generic,
396
+ "Could not parse error from server response - could not find 'msg' field" } };
397
+ }
398
+ if (!m->is_string()) {
399
+ return { { errc::generic,
400
+ "Could not parse error from server response - 'msg' field was not string" } };
401
+ }
402
+ msg = m->get_string();
370
403
  }
371
404
 
372
- std::int32_t code = c->is_signed() ? gsl::narrow_cast<std::int32_t>(c->get_signed())
373
- : gsl::narrow_cast<std::int32_t>(c->get_unsigned());
405
+ std::int32_t code{};
406
+ {
407
+ auto* c = error_json.find("code");
408
+ if (c == nullptr) {
409
+ return { { errc::generic,
410
+ "Could not parse error from server response - could not find 'code' field" } };
411
+ }
412
+ if (!(c->is_unsigned() || c->is_signed())) {
413
+ return {
414
+ { errc::generic,
415
+ "Could not parse error from server response - 'code' field was not an integer" }
416
+ };
417
+ }
418
+ code = c->is_signed() ? gsl::narrow_cast<std::int32_t>(c->get_signed())
419
+ : gsl::narrow_cast<std::int32_t>(c->get_unsigned());
420
+ }
374
421
 
375
422
  tao::json::value error = {
376
423
  { "code", code },
377
- { "msg", msg->get_string() },
424
+ { "msg", msg },
378
425
  };
379
426
  res.err.ctx["errors"].get_array().emplace_back(std::move(error));
380
427
 
381
428
  if (first_error_code == 0) {
382
429
  first_error_code = code;
383
- first_error_msg = msg->get_string();
430
+ first_error_msg = msg;
431
+ }
432
+ if (!retr && first_non_retr_error_code == 0) {
433
+ first_non_retr_error_code = code;
434
+ first_non_retr_error_msg = msg;
384
435
  }
385
436
 
386
437
  switch (code) {
@@ -396,7 +447,14 @@ private:
396
447
  }
397
448
 
398
449
  if (res.err.ec == errc::query_error) {
399
- res.err.properties = query_error_properties{ first_error_code, first_error_msg };
450
+ // If any of the errors is not retriable, report the first non-retriable code/message in the
451
+ // error properties
452
+ if (first_non_retr_error_code != 0) {
453
+ res.err.properties =
454
+ query_error_properties{ first_non_retr_error_code, first_non_retr_error_msg };
455
+ } else {
456
+ res.err.properties = query_error_properties{ first_error_code, first_error_msg };
457
+ }
400
458
  }
401
459
 
402
460
  return res;
@@ -17,6 +17,7 @@
17
17
 
18
18
  #pragma once
19
19
 
20
+ #include "core/impl/bootstrap_error.hxx"
20
21
  #include "core/pending_operation.hxx"
21
22
  #include "error.hxx"
22
23
  #include "query_options.hxx"
@@ -15,6 +15,9 @@
15
15
 
16
16
  #pragma once
17
17
 
18
+ #include <couchbase/build_config.hxx>
19
+
20
+ #include "core/impl/bootstrap_error.hxx"
18
21
  #include "service_type.hxx"
19
22
  #include "utils/movable_function.hxx"
20
23
 
@@ -101,8 +104,13 @@ private:
101
104
  std::shared_ptr<http_response_impl> impl_;
102
105
  };
103
106
 
107
+ #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
108
+ using free_form_http_request_callback =
109
+ utils::movable_function<void(http_response response, couchbase::core::error_union err)>;
110
+ #else
104
111
  using free_form_http_request_callback =
105
112
  utils::movable_function<void(http_response response, std::error_code ec)>;
113
+ #endif
106
114
 
107
115
  class buffered_http_response_impl;
108
116
 
@@ -131,19 +131,22 @@ public:
131
131
  invoke_response_handler(errc::common::request_canceled, {});
132
132
  }
133
133
 
134
- void invoke_response_handler(std::error_code ec, io::http_streaming_response resp)
135
- {
136
- deadline_.cancel();
137
134
  #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
135
+ void invoke_response_handler(error_union err, io::http_streaming_response resp)
136
+ {
138
137
  dispatch_deadline_.cancel();
138
+ #else
139
+ void invoke_response_handler(std::error_code err, io::http_streaming_response resp)
140
+ {
139
141
  #endif
142
+ deadline_.cancel();
140
143
  free_form_http_request_callback callback{};
141
144
  {
142
145
  const std::scoped_lock lock(callback_mutex_);
143
146
  std::swap(callback, callback_);
144
147
  }
145
148
  if (callback) {
146
- callback(http_response{ std::move(resp) }, ec);
149
+ callback(http_response{ std::move(resp) }, err);
147
150
  }
148
151
  }
149
152
 
@@ -157,12 +160,22 @@ public:
157
160
  auto start_op = [self = shared_from_this()]() {
158
161
  self->session_->write_and_stream(
159
162
  self->encoded_,
163
+ #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
164
+ [self](error_union err, io::http_streaming_response resp) {
165
+ if (std::holds_alternative<std::error_code>(err) &&
166
+ std::get<std::error_code>(err) == asio::error::operation_aborted) {
167
+ return;
168
+ }
169
+ self->invoke_response_handler(err, std::move(resp));
170
+ },
171
+ #else
160
172
  [self](std::error_code ec, io::http_streaming_response resp) {
161
173
  if (ec == asio::error::operation_aborted) {
162
174
  return;
163
175
  }
164
176
  self->invoke_response_handler(ec, std::move(resp));
165
177
  },
178
+ #endif
166
179
  [self]() {
167
180
  self->stream_end_callback_();
168
181
  });
@@ -409,8 +422,13 @@ public:
409
422
  {
410
423
  }
411
424
 
425
+ #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
426
+ auto do_http_request(const http_request& request, free_form_http_request_callback&& callback)
427
+ -> tl::expected<std::shared_ptr<pending_operation>, error_union>
428
+ #else
412
429
  auto do_http_request(const http_request& request, free_form_http_request_callback&& callback)
413
430
  -> tl::expected<std::shared_ptr<pending_operation>, std::error_code>
431
+ #endif
414
432
  {
415
433
  std::shared_ptr<io::http_session_manager> session_manager;
416
434
  {
@@ -436,9 +454,9 @@ public:
436
454
  auto op =
437
455
  std::make_shared<pending_http_operation>(io_, request, session_manager->dispatch_timeout());
438
456
  if (!session_manager->is_configured()) {
439
- auto ec = defer_command(op, session_manager, credentials, std::move(callback));
440
- if (ec) {
441
- return tl::unexpected{ ec };
457
+ auto err = defer_command(op, session_manager, credentials, std::move(callback));
458
+ if (!std::holds_alternative<std::monostate>(err)) {
459
+ return tl::unexpected{ err };
442
460
  }
443
461
  return op;
444
462
  }
@@ -478,8 +496,11 @@ public:
478
496
  auto op = std::make_shared<pending_buffered_http_operation>(
479
497
  io_, request, session_manager->dispatch_timeout());
480
498
  if (!session_manager->is_configured()) {
481
- auto ec = defer_command(op, session_manager, credentials, std::move(callback));
482
- if (ec) {
499
+ auto err = defer_command(op, session_manager, credentials, std::move(callback));
500
+ if (!std::holds_alternative<std::monostate>(err)) {
501
+ auto ec = std::holds_alternative<impl::bootstrap_error>(err)
502
+ ? std::get<impl::bootstrap_error>(err).ec
503
+ : std::get<std::error_code>(err);
483
504
  return tl::unexpected{ ec };
484
505
  }
485
506
  return op;
@@ -498,16 +519,19 @@ private:
498
519
  const couchbase::core::cluster_credentials& credentials,
499
520
  free_form_http_request_callback&& callback)
500
521
  {
501
- op->start([callback = std::move(callback)](auto resp, auto ec) mutable {
502
- callback(std::move(resp), ec);
503
- });
504
-
505
522
  #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
523
+ op->start([callback = std::move(callback)](auto resp, error_union err) mutable {
524
+ callback(std::move(resp), err);
525
+ });
506
526
  // don't do anything if the op wasn't dispatched or has already timed out
507
527
  auto now = std::chrono::steady_clock::now();
508
528
  if (op->dispatch_deadline_expiry() < now || op->deadline_expiry() < now) {
509
529
  return;
510
530
  }
531
+ #else
532
+ op->start([callback = std::move(callback)](auto resp, auto ec) mutable {
533
+ callback(std::move(resp), ec);
534
+ });
511
535
  #endif
512
536
  std::shared_ptr<io::http_session> session;
513
537
  {
@@ -592,10 +616,10 @@ private:
592
616
  auto defer_command(std::shared_ptr<PendingHttpOp> pending_op,
593
617
  const std::shared_ptr<io::http_session_manager>& session_manager,
594
618
  const couchbase::core::cluster_credentials& credentials,
595
- Callback&& callback) -> std::error_code
619
+ Callback&& callback) -> error_union
596
620
  {
597
621
  if (auto last_error = session_manager->last_bootstrap_error(); last_error.has_value()) {
598
- return last_error->ec;
622
+ return last_error.value();
599
623
  }
600
624
  CB_LOG_DEBUG(
601
625
  R"(Adding pending HTTP operation to deferred queue: service={}, client_context_id={})",
@@ -605,26 +629,26 @@ private:
605
629
  callback = std::forward<Callback>(callback),
606
630
  op = std::move(pending_op),
607
631
  session_manager,
608
- credentials](std::error_code ec) mutable {
609
- if (ec) {
632
+ credentials](error_union err) mutable {
633
+ if (!std::holds_alternative<std::monostate>(err)) {
610
634
  // The deferred operation was cancelled - currently this can happen due to closing the
611
635
  // cluster
612
- return callback({}, ec);
636
+ return callback({}, err);
613
637
  }
614
638
 
615
639
  return send_http_operation(
616
640
  op, session_manager, credentials, std::forward<Callback>(callback));
617
641
  });
618
- return {};
642
+ return std::monostate{};
619
643
  }
620
644
 
621
645
  auto defer_command(std::shared_ptr<pending_buffered_http_operation> pending_op,
622
646
  const std::shared_ptr<io::http_session_manager>& session_manager,
623
647
  const couchbase::core::cluster_credentials& credentials,
624
- buffered_free_form_http_request_callback&& callback) -> std::error_code
648
+ buffered_free_form_http_request_callback&& callback) -> error_union
625
649
  {
626
650
  if (auto last_error = session_manager->last_bootstrap_error(); last_error.has_value()) {
627
- return last_error->ec;
651
+ return last_error.value();
628
652
  }
629
653
  CB_LOG_DEBUG(
630
654
  R"(Adding pending HTTP operation to deferred queue: service={}, client_context_id={})",
@@ -634,8 +658,11 @@ private:
634
658
  callback = std::move(callback),
635
659
  op = std::move(pending_op),
636
660
  session_manager,
637
- credentials](std::error_code ec) mutable {
638
- if (ec) {
661
+ credentials](error_union err) mutable {
662
+ if (!std::holds_alternative<std::monostate>(err)) {
663
+ auto ec = std::holds_alternative<impl::bootstrap_error>(err)
664
+ ? std::get<impl::bootstrap_error>(err).ec
665
+ : std::get<std::error_code>(err);
639
666
  // The deferred operation was cancelled - currently this can happen due to closing the
640
667
  // cluster
641
668
  return callback({}, ec);
@@ -643,7 +670,7 @@ private:
643
670
 
644
671
  return send_http_operation(op, session_manager, credentials, std::move(callback));
645
672
  });
646
- return {};
673
+ return std::monostate{};
647
674
  }
648
675
  #endif
649
676
 
@@ -664,7 +691,11 @@ http_component::http_component(asio::io_context& io,
664
691
  auto
665
692
  http_component::do_http_request(const http_request& request,
666
693
  free_form_http_request_callback&& callback)
694
+ #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
695
+ -> tl::expected<std::shared_ptr<pending_operation>, error_union>
696
+ #else
667
697
  -> tl::expected<std::shared_ptr<pending_operation>, std::error_code>
698
+ #endif
668
699
  {
669
700
  return impl_->do_http_request(request, std::move(callback));
670
701
  }
@@ -49,7 +49,11 @@ public:
49
49
  std::shared_ptr<retry_strategy> default_retry_strategy = {});
50
50
 
51
51
  auto do_http_request(const http_request& request, free_form_http_request_callback&& callback)
52
+ #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
53
+ -> tl::expected<std::shared_ptr<pending_operation>, error_union>;
54
+ #else
52
55
  -> tl::expected<std::shared_ptr<pending_operation>, std::error_code>;
56
+ #endif
53
57
 
54
58
  auto do_http_request_buffered(const http_request& request,
55
59
  buffered_free_form_http_request_callback&& callback)
@@ -159,7 +159,7 @@ public:
159
159
  {},
160
160
  options.timeout,
161
161
  },
162
- [dataverse_name, handler = std::move(handler)](auto resp) {
162
+ [dataverse_name, handler = std::move(handler)](const auto& resp) {
163
163
  CB_LOG_DEBUG(
164
164
  "Dataverse create for {} error code = {}", dataverse_name, resp.ctx.ec.value());
165
165
  handler(core::impl::make_error(resp.ctx));
@@ -177,7 +177,7 @@ public:
177
177
  {},
178
178
  options.timeout,
179
179
  },
180
- [handler = std::move(handler)](auto resp) {
180
+ [handler = std::move(handler)](const auto& resp) {
181
181
  handler(core::impl::make_error(resp.ctx));
182
182
  });
183
183
  }
@@ -197,7 +197,7 @@ public:
197
197
  options.timeout,
198
198
  options.ignore_if_exists,
199
199
  },
200
- [handler = std::move(handler)](auto resp) {
200
+ [handler = std::move(handler)](const auto& resp) {
201
201
  handler(core::impl::make_error(resp.ctx));
202
202
  });
203
203
  }
@@ -214,7 +214,7 @@ public:
214
214
  {},
215
215
  options.timeout,
216
216
  },
217
- [handler = std::move(handler)](auto resp) {
217
+ [handler = std::move(handler)](const auto& resp) {
218
218
  handler(core::impl::make_error(resp.ctx));
219
219
  });
220
220
  }
@@ -262,7 +262,7 @@ public:
262
262
  {},
263
263
  options.timeout,
264
264
  },
265
- [handler = std::move(handler)](auto resp) {
265
+ [handler = std::move(handler)](const auto& resp) {
266
266
  handler(core::impl::make_error(resp.ctx));
267
267
  });
268
268
  }
@@ -281,7 +281,7 @@ public:
281
281
  {},
282
282
  options.timeout,
283
283
  },
284
- [handler = std::move(handler)](auto resp) {
284
+ [handler = std::move(handler)](const auto& resp) {
285
285
  handler(core::impl::make_error(resp.ctx));
286
286
  });
287
287
  }
@@ -324,7 +324,7 @@ public:
324
324
  {},
325
325
  options.timeout,
326
326
  },
327
- [handler = std::move(handler)](auto resp) {
327
+ [handler = std::move(handler)](const auto& resp) {
328
328
  handler(core::impl::make_error(resp.ctx));
329
329
  });
330
330
  }
@@ -339,7 +339,7 @@ public:
339
339
  {},
340
340
  options.timeout,
341
341
  },
342
- [handler = std::move(handler)](auto resp) {
342
+ [handler = std::move(handler)](const auto& resp) {
343
343
  handler(core::impl::make_error(resp.ctx));
344
344
  });
345
345
  }
@@ -386,7 +386,7 @@ public:
386
386
  {},
387
387
  options.timeout,
388
388
  },
389
- [handler = std::move(handler)](auto resp) {
389
+ [handler = std::move(handler)](const auto& resp) {
390
390
  handler(core::impl::make_error(resp.ctx));
391
391
  });
392
392
 
@@ -398,7 +398,7 @@ public:
398
398
  {},
399
399
  options.timeout,
400
400
  },
401
- [handler = std::move(handler)](auto resp) {
401
+ [handler = std::move(handler)](const auto& resp) {
402
402
  handler(core::impl::make_error(resp.ctx));
403
403
  });
404
404
 
@@ -410,7 +410,7 @@ public:
410
410
  {},
411
411
  options.timeout,
412
412
  },
413
- [handler = std::move(handler)](auto resp) {
413
+ [handler = std::move(handler)](const auto& resp) {
414
414
  handler(core::impl::make_error(resp.ctx));
415
415
  });
416
416
  }
@@ -429,7 +429,7 @@ public:
429
429
  {},
430
430
  options.timeout,
431
431
  },
432
- [handler = std::move(handler)](auto resp) {
432
+ [handler = std::move(handler)](const auto& resp) {
433
433
  handler(core::impl::make_error(resp.ctx));
434
434
  });
435
435
 
@@ -441,7 +441,7 @@ public:
441
441
  {},
442
442
  options.timeout,
443
443
  },
444
- [handler = std::move(handler)](auto resp) {
444
+ [handler = std::move(handler)](const auto& resp) {
445
445
  handler(core::impl::make_error(resp.ctx));
446
446
  });
447
447
 
@@ -453,7 +453,7 @@ public:
453
453
  {},
454
454
  options.timeout,
455
455
  },
456
- [handler = std::move(handler)](auto resp) {
456
+ [handler = std::move(handler)](const auto& resp) {
457
457
  handler(core::impl::make_error(resp.ctx));
458
458
  });
459
459
  }
@@ -471,7 +471,7 @@ public:
471
471
  {},
472
472
  options.timeout,
473
473
  },
474
- [handler = std::move(handler)](auto resp) {
474
+ [handler = std::move(handler)](const auto& resp) {
475
475
  handler(core::impl::make_error(resp.ctx));
476
476
  });
477
477
  }
@@ -20,8 +20,12 @@
20
20
  #include <optional>
21
21
  #include <string>
22
22
  #include <system_error>
23
+ #include <variant>
23
24
 
24
- namespace couchbase::core::impl
25
+ namespace couchbase::core
26
+ {
27
+
28
+ namespace impl
25
29
  {
26
30
 
27
31
  struct bootstrap_error {
@@ -31,4 +35,8 @@ struct bootstrap_error {
31
35
  std::optional<std::string> port;
32
36
  };
33
37
 
34
- } // namespace couchbase::core::impl
38
+ } // namespace impl
39
+
40
+ using error_union = std::variant<std::monostate, std::error_code, impl::bootstrap_error>;
41
+
42
+ } // namespace couchbase::core
@@ -59,7 +59,7 @@ public:
59
59
  name_,
60
60
  core::impl::to_core_service_types(options.service_types),
61
61
  options.timeout,
62
- [handler = std::move(handler)](auto resp) mutable {
62
+ [handler = std::move(handler)](const auto& resp) mutable {
63
63
  return handler({}, core::impl::build_result(resp));
64
64
  });
65
65
  }