couchbase 4.7.0-dev.1 → 4.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/deps/couchbase-cxx-cache/mozilla-ca-bundle.crt +3 -575
  2. package/deps/couchbase-cxx-cache/mozilla-ca-bundle.sha256 +1 -1
  3. package/deps/couchbase-cxx-client/CMakeLists.txt +3 -1
  4. package/deps/couchbase-cxx-client/README.md +2 -2
  5. package/deps/couchbase-cxx-client/core/error_context/base_error_context.hxx +32 -0
  6. package/deps/couchbase-cxx-client/core/error_context/key_value.cxx +1 -0
  7. package/deps/couchbase-cxx-client/core/error_context/key_value.hxx +23 -0
  8. package/deps/couchbase-cxx-client/core/error_context/key_value_error_context.hxx +35 -0
  9. package/deps/couchbase-cxx-client/core/error_context/subdocument_error_context.hxx +41 -0
  10. package/deps/couchbase-cxx-client/core/impl/binary_collection.cxx +123 -88
  11. package/deps/couchbase-cxx-client/core/impl/collection.cxx +416 -189
  12. package/deps/couchbase-cxx-client/core/impl/error.cxx +29 -4
  13. package/deps/couchbase-cxx-client/core/impl/invoke_with_node_id.hxx +44 -0
  14. package/deps/couchbase-cxx-client/core/impl/node_id.cxx +110 -0
  15. package/deps/couchbase-cxx-client/core/impl/node_id.hxx +40 -0
  16. package/deps/couchbase-cxx-client/core/io/configuration_belongs_to_session.hxx +67 -0
  17. package/deps/couchbase-cxx-client/core/io/http_session_manager.hxx +97 -57
  18. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +7 -16
  19. package/deps/couchbase-cxx-client/core/operations/document_get_all_replicas.hxx +14 -4
  20. package/deps/couchbase-cxx-client/core/operations/document_get_projected.cxx +3 -4
  21. package/deps/couchbase-cxx-client/core/operations/document_lookup_in_all_replicas.hxx +4 -0
  22. package/deps/couchbase-cxx-client/core/operations/document_query.cxx +12 -12
  23. package/deps/couchbase-cxx-client/core/operations/management/collection_create.cxx +11 -11
  24. package/deps/couchbase-cxx-client/core/operations/management/collection_drop.cxx +11 -11
  25. package/deps/couchbase-cxx-client/core/operations/management/collection_update.cxx +11 -11
  26. package/deps/couchbase-cxx-client/core/operations/management/error_utils.cxx +9 -6
  27. package/deps/couchbase-cxx-client/core/operations/management/query_index_create.cxx +5 -4
  28. package/deps/couchbase-cxx-client/core/operations/management/query_index_drop.cxx +7 -6
  29. package/deps/couchbase-cxx-client/core/operations/management/scope_create.cxx +12 -13
  30. package/deps/couchbase-cxx-client/core/operations/management/scope_drop.cxx +8 -9
  31. package/deps/couchbase-cxx-client/core/topology/configuration.cxx +21 -0
  32. package/deps/couchbase-cxx-client/core/topology/configuration.hxx +28 -0
  33. package/deps/couchbase-cxx-client/core/utils/contains_string.cxx +61 -0
  34. package/deps/couchbase-cxx-client/core/utils/contains_string.hxx +26 -0
  35. package/deps/couchbase-cxx-client/couchbase/collection.hxx +73 -0
  36. package/deps/couchbase-cxx-client/couchbase/error.hxx +16 -0
  37. package/deps/couchbase-cxx-client/couchbase/node_id.hxx +123 -0
  38. package/deps/couchbase-cxx-client/couchbase/node_id_for_options.hxx +61 -0
  39. package/deps/couchbase-cxx-client/couchbase/node_ids_options.hxx +62 -0
  40. package/deps/couchbase-cxx-client/couchbase/result.hxx +42 -0
  41. package/dist/binding.d.ts +1 -0
  42. package/dist/bucket.d.ts +9 -1
  43. package/dist/bucket.js +21 -0
  44. package/dist/cluster.d.ts +10 -1
  45. package/dist/cluster.js +22 -0
  46. package/dist/collection.d.ts +3 -3
  47. package/dist/collection.js +161 -123
  48. package/dist/diagnosticsexecutor.js +2 -2
  49. package/dist/diagnosticstypes.d.ts +36 -0
  50. package/dist/diagnosticstypes.js +22 -1
  51. package/dist/observability.d.ts +5 -1
  52. package/dist/observability.js +11 -3
  53. package/dist/observabilityhandler.d.ts +6 -0
  54. package/dist/observabilityhandler.js +51 -14
  55. package/dist/observabilitytypes.js +19 -42
  56. package/dist/observabilityutilities.js +1 -1
  57. package/dist/oteltracer.d.ts +5 -0
  58. package/dist/oteltracer.js +7 -0
  59. package/dist/queryindexmanager.js +15 -0
  60. package/dist/thresholdlogging.d.ts +5 -0
  61. package/dist/thresholdlogging.js +7 -0
  62. package/dist/tracing.d.ts +6 -0
  63. package/dist/version.d.ts +1 -1
  64. package/dist/version.js +1 -1
  65. package/dist/waituntilreadyexecutor.d.ts +37 -0
  66. package/dist/waituntilreadyexecutor.js +156 -0
  67. package/package.json +8 -8
  68. package/scripts/prebuilds.js +13 -0
  69. package/src/binding.cpp +1 -1
@@ -21,7 +21,7 @@ endif()
21
21
 
22
22
  project(
23
23
  couchbase_cxx_client
24
- VERSION "1.3.1"
24
+ VERSION "1.3.2"
25
25
  LANGUAGES CXX C)
26
26
  message(
27
27
  STATUS
@@ -128,6 +128,7 @@ set(couchbase_cxx_client_FILES
128
128
  core/impl/doc_id_query.cxx
129
129
  core/impl/error.cxx
130
130
  core/impl/error_context.cxx
131
+ core/impl/node_id.cxx
131
132
  core/impl/expiry.cxx
132
133
  core/impl/fail_fast_retry_strategy.cxx
133
134
  core/impl/field_level_encryption_error_category.cxx
@@ -436,6 +437,7 @@ set(couchbase_cxx_client_FILES
436
437
  core/transactions/utils.cxx
437
438
  core/utils/binary.cxx
438
439
  core/utils/connection_string.cxx
440
+ core/utils/contains_string.cxx
439
441
  core/utils/duration_parser.cxx
440
442
  core/utils/json.cxx
441
443
  core/utils/json_streaming_lexer.cxx
@@ -22,9 +22,9 @@ CPMAddPackage(
22
22
  NAME
23
23
  couchbase_cxx_client
24
24
  GIT_TAG
25
- 1.3.1
25
+ 1.3.2
26
26
  VERSION
27
- 1.3.1
27
+ 1.3.2
28
28
  GITHUB_REPOSITORY
29
29
  "couchbase/couchbase-cxx-client"
30
30
  OPTIONS
@@ -17,6 +17,7 @@
17
17
 
18
18
  #pragma once
19
19
 
20
+ #include <couchbase/node_id.hxx>
20
21
  #include <couchbase/retry_reason.hxx>
21
22
 
22
23
  #include <cstdint>
@@ -74,6 +75,23 @@ public:
74
75
  {
75
76
  }
76
77
 
78
+ base_error_context(std::string operation_id,
79
+ std::error_code ec,
80
+ std::optional<std::string> last_dispatched_to,
81
+ std::optional<std::string> last_dispatched_from,
82
+ std::size_t retry_attempts,
83
+ std::set<retry_reason> retry_reasons,
84
+ couchbase::node_id last_dispatched_to_node_id)
85
+ : operation_id_{ std::move(operation_id) }
86
+ , ec_{ ec }
87
+ , last_dispatched_to_{ std::move(last_dispatched_to) }
88
+ , last_dispatched_from_{ std::move(last_dispatched_from) }
89
+ , retry_attempts_{ retry_attempts }
90
+ , retry_reasons_{ std::move(retry_reasons) }
91
+ , last_dispatched_to_node_id_{ std::move(last_dispatched_to_node_id) }
92
+ {
93
+ }
94
+
77
95
  [[nodiscard]] virtual auto operation_id() const -> const std::string&
78
96
  {
79
97
  return operation_id_;
@@ -173,6 +191,19 @@ public:
173
191
  return retry_reasons_.count(reason) > 0;
174
192
  }
175
193
 
194
+ /**
195
+ * Identity of the cluster node that last handled this request.
196
+ *
197
+ * @return node_id (default-constructed / falsy when unknown)
198
+ *
199
+ * @since 1.3.2
200
+ * @uncommitted
201
+ */
202
+ [[nodiscard]] virtual auto last_dispatched_to_node_id() const -> const couchbase::node_id&
203
+ {
204
+ return last_dispatched_to_node_id_;
205
+ }
206
+
176
207
  private:
177
208
  std::string operation_id_{};
178
209
  std::error_code ec_{};
@@ -180,5 +211,6 @@ private:
180
211
  std::optional<std::string> last_dispatched_from_{};
181
212
  std::size_t retry_attempts_{ 0 };
182
213
  std::set<retry_reason> retry_reasons_{};
214
+ couchbase::node_id last_dispatched_to_node_id_{};
183
215
  };
184
216
  } // namespace couchbase::core
@@ -51,6 +51,7 @@ make_subdocument_error_context(const key_value_error_context& ctx,
51
51
  ctx.last_dispatched_from(),
52
52
  ctx.retry_attempts(),
53
53
  ctx.retry_reasons(),
54
+ ctx.last_dispatched_to_node_id(),
54
55
  ctx.id(),
55
56
  ctx.bucket(),
56
57
  ctx.scope(),
@@ -20,6 +20,7 @@
20
20
  #include "subdocument_error_context.hxx"
21
21
 
22
22
  #include "core/document_id.hxx"
23
+ #include "core/impl/node_id.hxx"
23
24
  #include "key_value_error_context.hxx"
24
25
 
25
26
  #include <optional>
@@ -57,12 +58,34 @@ make_key_value_error_context(std::error_code ec,
57
58
  auto retry_attempts = command->request.retries.retry_attempts();
58
59
  auto retry_reasons = command->request.retries.retry_reasons();
59
60
 
61
+ // Build node_id from the session that handled this request.
62
+ // The session carries the node_uuid (empty on pre-8.0 servers),
63
+ // canonical hostname, and port — we use these to construct the
64
+ // fallback identifier when nodeUUID is unavailable.
65
+ //
66
+ // Only construct a node_id once the session has actually been bound to a
67
+ // concrete node: either a non-empty UUID, or a non-empty canonical
68
+ // hostname *and* a non-zero canonical KV port. Otherwise the fallback
69
+ // hash of ("", "", 0) would yield a truthy-but-meaningless node_id and
70
+ // break the contract that a default-constructed node_id means "unknown".
71
+ couchbase::node_id dispatched_to_node_id{};
72
+ if (command->session_) {
73
+ const auto& node_uuid = command->session_->node_uuid();
74
+ const auto& canonical_hostname = command->session_->canonical_hostname();
75
+ const auto canonical_port = command->session_->canonical_port_number();
76
+ if (!node_uuid.empty() || (!canonical_hostname.empty() && canonical_port != 0)) {
77
+ dispatched_to_node_id =
78
+ internal_node_id::build(node_uuid, canonical_hostname, canonical_port);
79
+ }
80
+ }
81
+
60
82
  return { command->id_,
61
83
  ec,
62
84
  command->last_dispatched_to_,
63
85
  command->last_dispatched_from_,
64
86
  retry_attempts,
65
87
  std::move(retry_reasons),
88
+ std::move(dispatched_to_node_id),
66
89
  key,
67
90
  bucket,
68
91
  scope,
@@ -101,6 +101,41 @@ public:
101
101
  {
102
102
  }
103
103
 
104
+ key_value_error_context(std::string operation_id,
105
+ std::error_code ec,
106
+ std::optional<std::string> last_dispatched_to,
107
+ std::optional<std::string> last_dispatched_from,
108
+ std::size_t retry_attempts,
109
+ std::set<retry_reason> retry_reasons,
110
+ couchbase::node_id dispatched_to_node_id,
111
+ std::string id,
112
+ std::string bucket,
113
+ std::string scope,
114
+ std::string collection,
115
+ std::uint32_t opaque,
116
+ std::optional<key_value_status_code> status_code,
117
+ couchbase::cas cas,
118
+ std::optional<key_value_error_map_info> error_map_info,
119
+ std::optional<key_value_extended_error_info> extended_error_info)
120
+ : base_error_context{ std::move(operation_id),
121
+ ec,
122
+ std::move(last_dispatched_to),
123
+ std::move(last_dispatched_from),
124
+ retry_attempts,
125
+ std::move(retry_reasons),
126
+ std::move(dispatched_to_node_id) }
127
+ , id_{ std::move(id) }
128
+ , bucket_{ std::move(bucket) }
129
+ , scope_{ std::move(scope) }
130
+ , collection_{ std::move(collection) }
131
+ , opaque_{ opaque }
132
+ , status_code_{ status_code }
133
+ , cas_{ cas }
134
+ , error_map_info_{ std::move(error_map_info) }
135
+ , extended_error_info_{ std::move(extended_error_info) }
136
+ {
137
+ }
138
+
104
139
  /**
105
140
  * Returns identifier (key) of the document referenced in the operation.
106
141
  *
@@ -102,6 +102,47 @@ public:
102
102
  {
103
103
  }
104
104
 
105
+ subdocument_error_context(std::string operation_id,
106
+ std::error_code ec,
107
+ std::optional<std::string> last_dispatched_to,
108
+ std::optional<std::string> last_dispatched_from,
109
+ std::size_t retry_attempts,
110
+ std::set<retry_reason> retry_reasons,
111
+ couchbase::node_id dispatched_to_node_id,
112
+ std::string id,
113
+ std::string bucket,
114
+ std::string scope,
115
+ std::string collection,
116
+ std::uint32_t opaque,
117
+ std::optional<key_value_status_code> status_code,
118
+ couchbase::cas cas,
119
+ std::optional<key_value_error_map_info> error_map_info,
120
+ std::optional<key_value_extended_error_info> extended_error_info,
121
+ std::optional<std::string> first_error_path,
122
+ std::optional<std::uint64_t> first_error_index,
123
+ bool deleted)
124
+ : key_value_error_context{ std::move(operation_id),
125
+ ec,
126
+ std::move(last_dispatched_to),
127
+ std::move(last_dispatched_from),
128
+ retry_attempts,
129
+ std::move(retry_reasons),
130
+ std::move(dispatched_to_node_id),
131
+ std::move(id),
132
+ std::move(bucket),
133
+ std::move(scope),
134
+ std::move(collection),
135
+ opaque,
136
+ status_code,
137
+ cas,
138
+ std::move(error_map_info),
139
+ std::move(extended_error_info) }
140
+ , first_error_path_{ std::move(first_error_path) }
141
+ , first_error_index_{ first_error_index }
142
+ , deleted_{ deleted }
143
+ {
144
+ }
145
+
105
146
  /**
106
147
  * Returns path of the operation that generated first error
107
148
  *
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include "core/cluster.hxx"
21
21
  #include "core/impl/error.hxx"
22
+ #include "core/impl/invoke_with_node_id.hxx"
22
23
  #include "core/impl/observability_recorder.hxx"
23
24
  #include "core/operations/document_append.hxx"
24
25
  #include "core/operations/document_decrement.hxx"
@@ -53,6 +54,8 @@
53
54
 
54
55
  namespace couchbase
55
56
  {
57
+ using core::impl::invoke_with_node_id;
58
+
56
59
  class binary_collection_impl : public std::enable_shared_from_this<binary_collection_impl>
57
60
  {
58
61
  public:
@@ -113,10 +116,13 @@ public:
113
116
  [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto&& resp) mutable {
114
117
  obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
115
118
  if (resp.ctx.ec()) {
116
- return handler(core::impl::make_error(std::move(resp.ctx)), mutation_result{});
119
+ invoke_with_node_id(
120
+ std::move(handler), core::impl::make_error(std::move(resp.ctx)), mutation_result{});
121
+ return;
117
122
  }
118
- return handler(core::impl::make_error(std::move(resp.ctx)),
119
- mutation_result{ resp.cas, std::move(resp.token) });
123
+ invoke_with_node_id(std::move(handler),
124
+ core::impl::make_error(std::move(resp.ctx)),
125
+ mutation_result{ resp.cas, std::move(resp.token) });
120
126
  });
121
127
  }
122
128
 
@@ -131,39 +137,44 @@ public:
131
137
  { options.retry_strategy },
132
138
  obs_rec->operation_span(),
133
139
  };
134
- return core_.execute(std::move(request),
135
- [core = core_,
136
- id = std::move(id),
137
- options,
138
- obs_rec = std::move(obs_rec),
139
- handler = std::move(handler)](auto&& resp) mutable {
140
- if (resp.ctx.ec()) {
141
- obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
142
- return handler(core::impl::make_error(std::move(resp.ctx)),
143
- mutation_result{ resp.cas, std::move(resp.token) });
144
- }
145
-
146
- auto token = resp.token;
147
- core::impl::initiate_observe_poll(
148
- core,
149
- std::move(id),
150
- token,
151
- options.timeout,
152
- options.persist_to,
153
- options.replicate_to,
154
- [obs_rec = std::move(obs_rec),
155
- resp = std::forward<decltype(resp)>(resp),
156
- handler = std::move(handler)](std::error_code ec) mutable {
157
- obs_rec->finish(resp.ctx.retry_attempts(), ec);
158
- if (ec) {
159
- resp.ctx.override_ec(ec);
160
- return handler(core::impl::make_error(std::move(resp.ctx)),
161
- mutation_result{});
162
- }
163
- return handler(core::impl::make_error(std::move(resp.ctx)),
164
- mutation_result{ resp.cas, std::move(resp.token) });
165
- });
166
- });
140
+ return core_.execute(
141
+ std::move(request),
142
+ [core = core_,
143
+ id = std::move(id),
144
+ options,
145
+ obs_rec = std::move(obs_rec),
146
+ handler = std::move(handler)](auto&& resp) mutable {
147
+ if (resp.ctx.ec()) {
148
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
149
+ invoke_with_node_id(std::move(handler),
150
+ core::impl::make_error(std::move(resp.ctx)),
151
+ mutation_result{ resp.cas, std::move(resp.token) });
152
+ return;
153
+ }
154
+
155
+ auto token = resp.token;
156
+ core::impl::initiate_observe_poll(
157
+ core,
158
+ std::move(id),
159
+ token,
160
+ options.timeout,
161
+ options.persist_to,
162
+ options.replicate_to,
163
+ [obs_rec = std::move(obs_rec),
164
+ resp = std::forward<decltype(resp)>(resp),
165
+ handler = std::move(handler)](std::error_code ec) mutable {
166
+ obs_rec->finish(resp.ctx.retry_attempts(), ec);
167
+ if (ec) {
168
+ resp.ctx.override_ec(ec);
169
+ invoke_with_node_id(
170
+ std::move(handler), core::impl::make_error(std::move(resp.ctx)), mutation_result{});
171
+ return;
172
+ }
173
+ invoke_with_node_id(std::move(handler),
174
+ core::impl::make_error(std::move(resp.ctx)),
175
+ mutation_result{ resp.cas, std::move(resp.token) });
176
+ });
177
+ });
167
178
  }
168
179
 
169
180
  void prepend(std::string document_key,
@@ -197,10 +208,13 @@ public:
197
208
  [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto&& resp) mutable {
198
209
  obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
199
210
  if (resp.ctx.ec()) {
200
- return handler(core::impl::make_error(std::move(resp.ctx)), mutation_result{});
211
+ invoke_with_node_id(
212
+ std::move(handler), core::impl::make_error(std::move(resp.ctx)), mutation_result{});
213
+ return;
201
214
  }
202
- return handler(core::impl::make_error(std::move(resp.ctx)),
203
- mutation_result{ resp.cas, std::move(resp.token) });
215
+ invoke_with_node_id(std::move(handler),
216
+ core::impl::make_error(std::move(resp.ctx)),
217
+ mutation_result{ resp.cas, std::move(resp.token) });
204
218
  });
205
219
  }
206
220
 
@@ -215,39 +229,44 @@ public:
215
229
  { options.retry_strategy },
216
230
  obs_rec->operation_span(),
217
231
  };
218
- return core_.execute(std::move(request),
219
- [obs_rec = std::move(obs_rec),
220
- core = core_,
221
- id = std::move(id),
222
- options,
223
- handler = std::move(handler)](auto&& resp) mutable {
224
- if (resp.ctx.ec()) {
225
- obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
226
- return handler(core::impl::make_error(std::move(resp.ctx)),
227
- mutation_result{ resp.cas, std::move(resp.token) });
228
- }
229
-
230
- auto token = resp.token;
231
- core::impl::initiate_observe_poll(
232
- core,
233
- std::move(id),
234
- token,
235
- options.timeout,
236
- options.persist_to,
237
- options.replicate_to,
238
- [obs_rec = std::move(obs_rec),
239
- resp = std::forward<decltype(resp)>(resp),
240
- handler = std::move(handler)](std::error_code ec) mutable {
241
- obs_rec->finish(resp.ctx.retry_attempts(), ec);
242
- if (ec) {
243
- resp.ctx.override_ec(ec);
244
- return handler(core::impl::make_error(std::move(resp.ctx)),
245
- mutation_result{});
246
- }
247
- return handler(core::impl::make_error(std::move(resp.ctx)),
248
- mutation_result{ resp.cas, std::move(resp.token) });
249
- });
250
- });
232
+ return core_.execute(
233
+ std::move(request),
234
+ [obs_rec = std::move(obs_rec),
235
+ core = core_,
236
+ id = std::move(id),
237
+ options,
238
+ handler = std::move(handler)](auto&& resp) mutable {
239
+ if (resp.ctx.ec()) {
240
+ obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
241
+ invoke_with_node_id(std::move(handler),
242
+ core::impl::make_error(std::move(resp.ctx)),
243
+ mutation_result{ resp.cas, std::move(resp.token) });
244
+ return;
245
+ }
246
+
247
+ auto token = resp.token;
248
+ core::impl::initiate_observe_poll(
249
+ core,
250
+ std::move(id),
251
+ token,
252
+ options.timeout,
253
+ options.persist_to,
254
+ options.replicate_to,
255
+ [obs_rec = std::move(obs_rec),
256
+ resp = std::forward<decltype(resp)>(resp),
257
+ handler = std::move(handler)](std::error_code ec) mutable {
258
+ obs_rec->finish(resp.ctx.retry_attempts(), ec);
259
+ if (ec) {
260
+ resp.ctx.override_ec(ec);
261
+ invoke_with_node_id(
262
+ std::move(handler), core::impl::make_error(std::move(resp.ctx)), mutation_result{});
263
+ return;
264
+ }
265
+ invoke_with_node_id(std::move(handler),
266
+ core::impl::make_error(std::move(resp.ctx)),
267
+ mutation_result{ resp.cas, std::move(resp.token) });
268
+ });
269
+ });
251
270
  }
252
271
 
253
272
  void decrement(std::string document_key,
@@ -282,10 +301,13 @@ public:
282
301
  obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
283
302
 
284
303
  if (resp.ctx.ec()) {
285
- return handler(core::impl::make_error(std::move(resp.ctx)), counter_result{});
304
+ invoke_with_node_id(
305
+ std::move(handler), core::impl::make_error(std::move(resp.ctx)), counter_result{});
306
+ return;
286
307
  }
287
- return handler(core::impl::make_error(std::move(resp.ctx)),
288
- counter_result{ resp.cas, std::move(resp.token), resp.content });
308
+ invoke_with_node_id(std::move(handler),
309
+ core::impl::make_error(std::move(resp.ctx)),
310
+ counter_result{ resp.cas, std::move(resp.token), resp.content });
289
311
  });
290
312
  }
291
313
 
@@ -310,8 +332,10 @@ public:
310
332
  handler = std::move(handler)](auto&& resp) mutable {
311
333
  if (resp.ctx.ec()) {
312
334
  obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
313
- return handler(core::impl::make_error(std::move(resp.ctx)),
314
- counter_result{ resp.cas, std::move(resp.token), resp.content });
335
+ invoke_with_node_id(std::move(handler),
336
+ core::impl::make_error(std::move(resp.ctx)),
337
+ counter_result{ resp.cas, std::move(resp.token), resp.content });
338
+ return;
315
339
  }
316
340
 
317
341
  auto token = resp.token;
@@ -328,10 +352,13 @@ public:
328
352
  obs_rec->finish(resp.ctx.retry_attempts(), ec);
329
353
  if (ec) {
330
354
  resp.ctx.override_ec(ec);
331
- return handler(core::impl::make_error(std::move(resp.ctx)), counter_result{});
355
+ invoke_with_node_id(
356
+ std::move(handler), core::impl::make_error(std::move(resp.ctx)), counter_result{});
357
+ return;
332
358
  }
333
- return handler(core::impl::make_error(std::move(resp.ctx)),
334
- counter_result{ resp.cas, std::move(resp.token), resp.content });
359
+ invoke_with_node_id(std::move(handler),
360
+ core::impl::make_error(std::move(resp.ctx)),
361
+ counter_result{ resp.cas, std::move(resp.token), resp.content });
335
362
  });
336
363
  });
337
364
  }
@@ -367,10 +394,13 @@ public:
367
394
  [obs_rec = std::move(obs_rec), handler = std::move(handler)](auto&& resp) mutable {
368
395
  obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
369
396
  if (resp.ctx.ec()) {
370
- return handler(core::impl::make_error(std::move(resp.ctx)), counter_result{});
397
+ invoke_with_node_id(
398
+ std::move(handler), core::impl::make_error(std::move(resp.ctx)), counter_result{});
399
+ return;
371
400
  }
372
- return handler(core::impl::make_error(std::move(resp.ctx)),
373
- counter_result{ resp.cas, std::move(resp.token), resp.content });
401
+ invoke_with_node_id(std::move(handler),
402
+ core::impl::make_error(std::move(resp.ctx)),
403
+ counter_result{ resp.cas, std::move(resp.token), resp.content });
374
404
  });
375
405
  }
376
406
 
@@ -395,8 +425,10 @@ public:
395
425
  handler = std::move(handler)](auto&& resp) mutable {
396
426
  if (resp.ctx.ec()) {
397
427
  obs_rec->finish(resp.ctx.retry_attempts(), resp.ctx.ec());
398
- return handler(core::impl::make_error(std::move(resp.ctx)),
399
- counter_result{ resp.cas, std::move(resp.token), resp.content });
428
+ invoke_with_node_id(std::move(handler),
429
+ core::impl::make_error(std::move(resp.ctx)),
430
+ counter_result{ resp.cas, std::move(resp.token), resp.content });
431
+ return;
400
432
  }
401
433
 
402
434
  auto token = resp.token;
@@ -413,10 +445,13 @@ public:
413
445
  obs_rec->finish(resp.ctx.retry_attempts(), ec);
414
446
  if (ec) {
415
447
  resp.ctx.override_ec(ec);
416
- return handler(core::impl::make_error(std::move(resp.ctx)), counter_result{});
448
+ invoke_with_node_id(
449
+ std::move(handler), core::impl::make_error(std::move(resp.ctx)), counter_result{});
450
+ return;
417
451
  }
418
- return handler(core::impl::make_error(std::move(resp.ctx)),
419
- counter_result{ resp.cas, std::move(resp.token), resp.content });
452
+ invoke_with_node_id(std::move(handler),
453
+ core::impl::make_error(std::move(resp.ctx)),
454
+ counter_result{ resp.cas, std::move(resp.token), resp.content });
420
455
  });
421
456
  });
422
457
  }