couchbase 3.2.3 → 3.2.4

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 (100) hide show
  1. package/deps/lcb/CMakeLists.txt +1 -1
  2. package/deps/lcb/CONTRIBUTING.md +1 -1
  3. package/deps/lcb/README.markdown +2 -2
  4. package/deps/lcb/RELEASE_NOTES.markdown +72 -17
  5. package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
  6. package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
  7. package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -6
  8. package/deps/lcb/doc/Doxyfile +1 -1
  9. package/deps/lcb/example/minimal/query.c +9 -7
  10. package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
  11. package/deps/lcb/include/libcouchbase/couchbase.h +3 -1
  12. package/deps/lcb/include/libcouchbase/error.h +2 -0
  13. package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
  14. package/deps/lcb/include/libcouchbase/tracing.h +2 -2
  15. package/deps/lcb/include/memcached/protocol_binary.h +21 -0
  16. package/deps/lcb/libcouchbase.gyp +347 -349
  17. package/deps/lcb/packaging/deb/control +1 -1
  18. package/deps/lcb/src/analytics/analytics_handle.cc +7 -5
  19. package/deps/lcb/src/analytics/analytics_handle.hh +28 -0
  20. package/deps/lcb/src/capi/cmd_counter.hh +6 -0
  21. package/deps/lcb/src/capi/cmd_exists.hh +6 -0
  22. package/deps/lcb/src/capi/cmd_get.hh +5 -0
  23. package/deps/lcb/src/capi/cmd_get_replica.hh +6 -0
  24. package/deps/lcb/src/capi/cmd_remove.hh +6 -0
  25. package/deps/lcb/src/capi/cmd_search.hh +6 -0
  26. package/deps/lcb/src/capi/cmd_store.hh +16 -21
  27. package/deps/lcb/src/capi/cmd_subdoc.hh +18 -0
  28. package/deps/lcb/src/capi/cmd_touch.hh +6 -0
  29. package/deps/lcb/src/capi/cmd_unlock.hh +6 -0
  30. package/deps/lcb/src/capi/cmd_view.hh +6 -0
  31. package/deps/lcb/src/capi/collection_qualifier.hh +2 -2
  32. package/deps/lcb/src/cntl.cc +42 -8
  33. package/deps/lcb/src/dns-srv.cc +5 -3
  34. package/deps/lcb/src/errmap.cc +5 -9
  35. package/deps/lcb/src/errmap.h +7 -3
  36. package/deps/lcb/src/handler.cc +24 -18
  37. package/deps/lcb/src/lcbio/ctx.cc +4 -2
  38. package/deps/lcb/src/mcserver/mcserver.cc +8 -5
  39. package/deps/lcb/src/mcserver/negotiate.cc +39 -17
  40. package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
  41. package/deps/lcb/src/n1ql/query_handle.cc +27 -16
  42. package/deps/lcb/src/n1ql/query_handle.hh +27 -1
  43. package/deps/lcb/src/operations/counter.cc +1 -1
  44. package/deps/lcb/src/operations/exists.cc +2 -2
  45. package/deps/lcb/src/operations/get.cc +2 -2
  46. package/deps/lcb/src/operations/observe.cc +1 -1
  47. package/deps/lcb/src/operations/remove.cc +1 -1
  48. package/deps/lcb/src/operations/store.cc +1 -1
  49. package/deps/lcb/src/operations/subdoc.cc +1 -2
  50. package/deps/lcb/src/operations/touch.cc +2 -2
  51. package/deps/lcb/src/operations/unlock.cc +2 -2
  52. package/deps/lcb/src/search/search_handle.cc +27 -8
  53. package/deps/lcb/src/search/search_handle.hh +29 -0
  54. package/deps/lcb/src/ssl/ssl_common.c +6 -7
  55. package/deps/lcb/src/tracing/span.cc +43 -10
  56. package/deps/lcb/src/tracing/tracing-internal.h +105 -93
  57. package/deps/lcb/src/views/view_handle.cc +13 -5
  58. package/deps/lcb/src/views/view_handle.hh +29 -0
  59. package/deps/lcb/tests/CMakeLists.txt +21 -0
  60. package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
  61. package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
  62. package/deps/lcb/tests/iotests/mock-environment.cc +15 -0
  63. package/deps/lcb/tests/iotests/mock-environment.h +47 -0
  64. package/deps/lcb/tests/iotests/mock-unit-test.cc +96 -5
  65. package/deps/lcb/tests/iotests/mock-unit-test.h +32 -0
  66. package/deps/lcb/tests/iotests/t_collections.cc +1 -1
  67. package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
  68. package/deps/lcb/tests/iotests/t_get.cc +14 -4
  69. package/deps/lcb/tests/iotests/t_n1ql.cc +17 -1
  70. package/deps/lcb/tests/iotests/t_views.cc +1 -0
  71. package/deps/lcb/tests/iotests/testutil.cc +168 -0
  72. package/deps/lcb/tests/iotests/testutil.h +111 -0
  73. package/deps/lcb/tests/mocksupport/procutil.c +32 -28
  74. package/deps/lcb/tests/mocksupport/server.c +0 -1
  75. package/deps/lcb/tools/cbc.cc +7 -0
  76. package/dist/analyticsindexmanager.js +3 -3
  77. package/dist/binding.d.ts +2 -0
  78. package/dist/bindingutilities.js +4 -0
  79. package/dist/bucketmanager.d.ts +31 -1
  80. package/dist/bucketmanager.js +28 -2
  81. package/dist/collection.js +2 -2
  82. package/dist/collectionmanager.js +2 -2
  83. package/dist/connection.js +3 -0
  84. package/dist/errors.d.ts +18 -0
  85. package/dist/errors.js +26 -2
  86. package/dist/eventingfunctionmanager.js +6 -6
  87. package/dist/queryindexmanager.js +3 -3
  88. package/dist/searchexecutor.js +3 -0
  89. package/dist/searchindexmanager.js +1 -1
  90. package/dist/searchquery.d.ts +17 -0
  91. package/dist/searchquery.js +22 -1
  92. package/dist/searchtypes.d.ts +7 -2
  93. package/dist/searchtypes.js +2 -2
  94. package/dist/usermanager.js +1 -1
  95. package/dist/viewindexmanager.js +1 -1
  96. package/package.json +1 -1
  97. package/src/connection.cpp +2 -0
  98. package/src/constants.cpp +2 -0
  99. package/src/instance.cpp +8 -1
  100. package/src/instance.h +1 -0
@@ -6,7 +6,7 @@ Standards-Version: 3.9.2
6
6
  Section: libs
7
7
  Homepage: http://www.couchbase.com/develop/c/current
8
8
  Vcs-Browser: https://github.com/couchbase/libcouchbase
9
- Vcs-Git: git://github.com/couchbase/libcouchbase.git
9
+ Vcs-Git: https://github.com/couchbase/libcouchbase.git
10
10
 
11
11
  Package: libcouchbase3-libevent
12
12
  Architecture: any
@@ -225,7 +225,7 @@ lcb_ANALYTICS_HANDLE_::lcb_ANALYTICS_HANDLE_(lcb_INSTANCE *obj, void *user_cooki
225
225
  query_params_ = Json::FastWriter().write(cmd->root());
226
226
 
227
227
  if (instance_->settings->tracer) {
228
- span_ = cmd->parent_span();
228
+ parent_span_ = cmd->parent_span();
229
229
  }
230
230
 
231
231
  if (ingest_options().method != LCB_INGEST_METHOD_NONE) {
@@ -284,8 +284,7 @@ lcb_STATUS lcb_ANALYTICS_HANDLE_::issue_htreq(const std::string &body)
284
284
  htcmd->set_header("cb-on-behalf-of", impostor_);
285
285
  }
286
286
 
287
- LCBTRACE_HTTP_START(instance_->settings, client_context_id_.c_str(), span_, LCBTRACE_TAG_SERVICE_ANALYTICS,
288
- LCBTRACE_THRESHOLD_ANALYTICS, span_);
287
+ span_ = lcb::trace::start_http_span_with_statement(instance_->settings, this, statement_);
289
288
  lcb_cmdhttp_parent_span(htcmd, span_);
290
289
 
291
290
  lcb_STATUS rc = lcb_http(instance_, this, htcmd);
@@ -394,7 +393,7 @@ void lcb_ANALYTICS_HANDLE_::invoke_row(lcb_RESPANALYTICS *resp, bool is_last)
394
393
  resp->rflags |= LCB_RESP_F_EXTDATA;
395
394
  }
396
395
  Json::Value meta;
397
- if (Json::Reader().parse(resp->row, resp->row + resp->nrow, meta)) {
396
+ if (Json::Reader(Json::Features::strictMode()).parse(resp->row, resp->row + resp->nrow, meta)) {
398
397
  const Json::Value &errors = meta["errors"];
399
398
  if (errors.isArray() && !errors.empty()) {
400
399
  const Json::Value &err = errors[0];
@@ -456,7 +455,10 @@ void lcb_ANALYTICS_HANDLE_::invoke_row(lcb_RESPANALYTICS *resp, bool is_last)
456
455
  }
457
456
  }
458
457
 
459
- LCBTRACE_HTTP_FINISH(span_);
458
+ if (span_ != nullptr) {
459
+ lcb::trace::finish_http_span(span_, this);
460
+ span_ = nullptr;
461
+ }
460
462
  if (http_request_ != nullptr) {
461
463
  http_request_->span = nullptr;
462
464
  }
@@ -208,6 +208,32 @@ struct lcb_ANALYTICS_HANDLE_ : lcb::jsparse::Parser::Actions {
208
208
  return last_error_;
209
209
  }
210
210
 
211
+ static lcbtrace_THRESHOLDOPTS service()
212
+ {
213
+ return LCBTRACE_THRESHOLD_ANALYTICS;
214
+ }
215
+
216
+ static const std::string &operation_name()
217
+ {
218
+ static std::string name = LCBTRACE_OP_ANALYTICS;
219
+ return name;
220
+ }
221
+
222
+ lcbtrace_SPAN *parent_span() const
223
+ {
224
+ return parent_span_;
225
+ }
226
+
227
+ const std::string &client_context_id() const
228
+ {
229
+ return client_context_id_;
230
+ }
231
+
232
+ int retries() const
233
+ {
234
+ return retries_;
235
+ }
236
+
211
237
  private:
212
238
  const lcb_RESPHTTP *http_response_{nullptr};
213
239
  lcb_HTTP_HANDLE *http_request_{nullptr};
@@ -219,6 +245,7 @@ struct lcb_ANALYTICS_HANDLE_ : lcb::jsparse::Parser::Actions {
219
245
  lcb_U32 timeout_{0};
220
246
  // How many rows were received. Used to avoid parsing the meta
221
247
  size_t rows_number_{0};
248
+ int retries_{0};
222
249
 
223
250
  /** Request body as received from the application */
224
251
  Json::Value json{};
@@ -240,6 +267,7 @@ struct lcb_ANALYTICS_HANDLE_ : lcb::jsparse::Parser::Actions {
240
267
  lcb::docreq::Queue *document_queue_{nullptr};
241
268
  unsigned refcount{1};
242
269
 
270
+ lcbtrace_SPAN *parent_span_{nullptr};
243
271
  lcbtrace_SPAN *span_{nullptr};
244
272
  std::string impostor_{};
245
273
  };
@@ -30,6 +30,12 @@
30
30
  */
31
31
  struct lcb_CMDCOUNTER_ {
32
32
  public:
33
+ static const std::string &operation_name()
34
+ {
35
+ static std::string name = LCBTRACE_OP_COUNTER;
36
+ return name;
37
+ }
38
+
33
39
  lcb_STATUS expiry(std::uint32_t expiry)
34
40
  {
35
41
  if (!initialize_if_does_not_exist_) {
@@ -28,6 +28,12 @@
28
28
  * @private
29
29
  */
30
30
  struct lcb_CMDEXISTS_ {
31
+ static const std::string &operation_name()
32
+ {
33
+ static std::string name = LCBTRACE_OP_EXISTS;
34
+ return name;
35
+ }
36
+
31
37
  lcb_STATUS key(std::string key)
32
38
  {
33
39
  key_ = std::move(key);
@@ -34,6 +34,11 @@ enum class get_mode {
34
34
  * @private
35
35
  */
36
36
  struct lcb_CMDGET_ {
37
+ static const std::string &operation_name()
38
+ {
39
+ static std::string name = LCBTRACE_OP_GET;
40
+ return name;
41
+ }
37
42
 
38
43
  lcb_STATUS with_touch(std::uint32_t expiry)
39
44
  {
@@ -36,6 +36,12 @@ enum class get_replica_mode {
36
36
  * @private
37
37
  */
38
38
  struct lcb_CMDGETREPLICA_ {
39
+ static const std::string &operation_name()
40
+ {
41
+ static std::string name = LCBTRACE_OP_GET_FROM_REPLICA;
42
+ return name;
43
+ }
44
+
39
45
  lcb_STATUS mode(get_replica_mode mode)
40
46
  {
41
47
  mode_ = mode;
@@ -28,6 +28,12 @@
28
28
  * @private
29
29
  */
30
30
  struct lcb_CMDREMOVE_ {
31
+ static const std::string &operation_name()
32
+ {
33
+ static std::string name = LCBTRACE_OP_REMOVE;
34
+ return name;
35
+ }
36
+
31
37
  lcb_STATUS cas(std::uint64_t cas)
32
38
  {
33
39
  cas_ = cas;
@@ -70,6 +70,12 @@ struct lcb_RESPSEARCH_ {
70
70
  * @private
71
71
  */
72
72
  struct lcb_CMDSEARCH_ {
73
+ static const std::string &operation_name()
74
+ {
75
+ static std::string name = LCBTRACE_OP_SEARCH;
76
+ return name;
77
+ }
78
+
73
79
  bool has_callback() const
74
80
  {
75
81
  return callback_ != nullptr;
@@ -35,6 +35,16 @@ enum class durability_mode {
35
35
  * @private
36
36
  */
37
37
  struct lcb_CMDSTORE_ {
38
+ const std::string &operation_name() const
39
+ {
40
+ static std::map<int, std::string> names{
41
+ {LCB_STORE_UPSERT, LCBTRACE_OP_UPSERT}, {LCB_STORE_REPLACE, LCBTRACE_OP_REPLACE},
42
+ {LCB_STORE_APPEND, LCBTRACE_OP_APPEND}, {LCB_STORE_PREPEND, LCBTRACE_OP_PREPEND},
43
+ {LCB_STORE_INSERT, LCBTRACE_OP_INSERT},
44
+ };
45
+ return names[operation_];
46
+ }
47
+
38
48
  lcb_STATUS operation(lcb_STORE_OPERATION operation)
39
49
  {
40
50
  operation_ = operation;
@@ -123,24 +133,6 @@ struct lcb_CMDSTORE_ {
123
133
  return false;
124
134
  }
125
135
 
126
- const char *operation_name() const
127
- {
128
- switch (operation_) {
129
- case LCB_STORE_UPSERT:
130
- return LCBTRACE_OP_UPSERT;
131
- case LCB_STORE_REPLACE:
132
- return LCBTRACE_OP_REPLACE;
133
- case LCB_STORE_APPEND:
134
- return LCBTRACE_OP_APPEND;
135
- case LCB_STORE_PREPEND:
136
- return LCBTRACE_OP_PREPEND;
137
- case LCB_STORE_INSERT:
138
- return LCBTRACE_OP_INSERT;
139
- }
140
- lcb_assert(false && "unknown operation name");
141
- return "unknown";
142
- }
143
-
144
136
  lcb_STATUS flags(std::uint32_t flags)
145
137
  {
146
138
  if (operation_ == LCB_STORE_APPEND || operation_ == LCB_STORE_PREPEND) {
@@ -245,13 +237,16 @@ struct lcb_CMDSTORE_ {
245
237
 
246
238
  lcb_STATUS value(const lcb_IOV *iov, std::size_t iov_len)
247
239
  {
248
- std::stringstream ss;
240
+ std::size_t total_size = 0;
241
+ for (std::size_t i = 0; i < iov_len; ++i) {
242
+ total_size += iov[i].iov_len;
243
+ }
244
+ value_.reserve(total_size);
249
245
  for (std::size_t i = 0; i < iov_len; ++i) {
250
246
  if (iov[i].iov_len > 0 && iov[i].iov_base != nullptr) {
251
- ss << std::string(static_cast<const char *>(iov[i].iov_base), iov[i].iov_len);
247
+ value_.append(static_cast<const char *>(iov[i].iov_base), iov[i].iov_len);
252
248
  }
253
249
  }
254
- value_ = ss.str();
255
250
  return LCB_SUCCESS;
256
251
  }
257
252
 
@@ -114,6 +114,12 @@ struct subdoc_spec_options {
114
114
  * This structure is provided in an array to the lcb_CMDSUBDOC::specs field.
115
115
  */
116
116
  struct subdoc_spec {
117
+ bool is_lookup() const
118
+ {
119
+ return opcode_ == subdoc_opcode::get || opcode_ == subdoc_opcode::get_count ||
120
+ opcode_ == subdoc_opcode::get_fulldoc || opcode_ == subdoc_opcode::exist;
121
+ }
122
+
117
123
  subdoc_opcode opcode() const
118
124
  {
119
125
  return opcode_;
@@ -216,11 +222,23 @@ struct lcb_SUBDOCSPECS_ {
216
222
  return specs_;
217
223
  }
218
224
 
225
+ bool is_lookup() const
226
+ {
227
+ return specs_.empty() || specs_[0].is_lookup();
228
+ }
229
+
219
230
  private:
220
231
  std::vector<subdoc_spec> specs_{};
221
232
  };
222
233
 
223
234
  struct lcb_CMDSUBDOC_ {
235
+ const std::string &operation_name() const
236
+ {
237
+ static std::string lookup_in_name = LCBTRACE_OP_LOOKUPIN;
238
+ static std::string mutate_in_name = LCBTRACE_OP_MUTATEIN;
239
+ return specs_.is_lookup() ? lookup_in_name : mutate_in_name;
240
+ }
241
+
224
242
  const subdoc_options &options() const
225
243
  {
226
244
  return options_;
@@ -28,6 +28,12 @@
28
28
  * @private
29
29
  */
30
30
  struct lcb_CMDTOUCH_ {
31
+ static const std::string &operation_name()
32
+ {
33
+ static std::string name = LCBTRACE_OP_TOUCH;
34
+ return name;
35
+ }
36
+
31
37
  lcb_STATUS expiry(std::uint32_t expiry)
32
38
  {
33
39
  expiry_ = expiry;
@@ -28,6 +28,12 @@
28
28
  * @private
29
29
  */
30
30
  struct lcb_CMDUNLOCK_ {
31
+ static const std::string &operation_name()
32
+ {
33
+ static std::string name = LCBTRACE_OP_UNLOCK;
34
+ return name;
35
+ }
36
+
31
37
  lcb_STATUS cas(std::uint64_t cas)
32
38
  {
33
39
  if (cas == 0) {
@@ -47,6 +47,12 @@ struct lcb_VIEW_ERROR_CONTEXT_ {
47
47
 
48
48
  /** @private */
49
49
  struct lcb_CMDVIEW_ {
50
+ static const std::string &operation_name()
51
+ {
52
+ static std::string name = LCBTRACE_OP_VIEW;
53
+ return name;
54
+ }
55
+
50
56
  bool view_or_design_document_empty() const
51
57
  {
52
58
  return view_name_.empty() || design_document_name_.empty();
@@ -135,8 +135,8 @@ struct collection_qualifier {
135
135
  return true;
136
136
  }
137
137
 
138
- std::string scope_{};
139
- std::string collection_{};
138
+ std::string scope_{"_default"};
139
+ std::string collection_{"_default"};
140
140
  std::string spec_{};
141
141
  std::uint32_t resolved_collection_id_{0};
142
142
  bool resolved_{false};
@@ -21,6 +21,7 @@
21
21
  #include <lcbio/iotable.h>
22
22
  #include <mcserver/negotiate.h>
23
23
  #include <lcbio/ssl.h>
24
+ #include "n1ql/query_utils.hh"
24
25
 
25
26
  #define LOGARGS(instance, lvl) instance->settings, "cntl", LCB_LOG_##lvl, __FILE__, __LINE__
26
27
 
@@ -238,7 +239,35 @@ HANDLER(select_bucket_handler){RETURN_GET_SET(int, LCBT_SETTING(instance, select
238
239
 
239
240
  HANDLER(log_redaction_handler){RETURN_GET_SET(int, LCBT_SETTING(instance, log_redaction))}
240
241
 
241
- HANDLER(enable_tracing_handler){RETURN_GET_SET(int, LCBT_SETTING(instance, use_tracing))}
242
+ HANDLER(enable_tracing_handler)
243
+ {
244
+ if (mode == LCB_CNTL_GET) {
245
+ RETURN_GET_ONLY(int, instance->settings->use_tracing)
246
+ } else if (mode == LCB_CNTL_SET) {
247
+ if (arg == nullptr) {
248
+ return LCB_ERR_INVALID_ARGUMENT;
249
+ }
250
+ int enabled = *(static_cast<int *>(arg));
251
+ if (enabled) {
252
+ if (instance->settings->use_tracing) {
253
+ /* do nothing */
254
+ return LCB_SUCCESS;
255
+ }
256
+ instance->settings->tracer = lcbtrace_new(instance, LCBTRACE_F_THRESHOLD);
257
+ instance->settings->use_tracing = true;
258
+ return LCB_SUCCESS;
259
+ } else {
260
+ if (instance->settings->use_tracing) {
261
+ lcbtrace_destroy(instance->settings->tracer);
262
+ instance->settings->tracer = nullptr;
263
+ instance->settings->use_tracing = false;
264
+ }
265
+ return LCB_SUCCESS;
266
+ }
267
+ } else {
268
+ return LCB_ERR_CONTROL_UNSUPPORTED_MODE;
269
+ }
270
+ }
242
271
 
243
272
  HANDLER(enable_errmap_handler){RETURN_GET_SET(int, LCBT_SETTING(instance, use_errmap))}
244
273
 
@@ -858,14 +887,19 @@ typedef struct {
858
887
 
859
888
  static lcb_STATUS convert_timevalue(const char *arg, u_STRCONVERT *u)
860
889
  {
861
- double dtmp;
862
- char *end = nullptr;
863
- errno = 0;
864
- dtmp = std::strtod(arg, &end);
865
- if (errno == ERANGE || end == arg) {
866
- return LCB_ERR_CONTROL_INVALID_ARGUMENT;
890
+ try {
891
+ auto tmo_ns = lcb_parse_golang_duration(arg);
892
+ u->u32 = static_cast<std::uint32_t>(std::chrono::duration_cast<std::chrono::microseconds>(tmo_ns).count());
893
+ } catch (const lcb_duration_parse_error &) {
894
+ double dtmp;
895
+ char *end = nullptr;
896
+ errno = 0;
897
+ dtmp = std::strtod(arg, &end);
898
+ if (errno == ERANGE || end == arg) {
899
+ return LCB_ERR_CONTROL_INVALID_ARGUMENT;
900
+ }
901
+ u->u32 = static_cast<std::uint32_t>(dtmp * (double)1000000);
867
902
  }
868
- u->u32 = static_cast<std::uint32_t>(dtmp * (double)1000000);
869
903
  return LCB_SUCCESS;
870
904
  }
871
905
 
@@ -105,9 +105,11 @@ lcb_STATUS lcb::dnssrv_query(const char *addr, Hostlist &hs)
105
105
  }
106
106
 
107
107
  for (cur = root; cur; cur = cur->pNext) {
108
- // Use the ASCII version of the DNS lookup structure
109
- const DNS_SRV_DATAA *srv = &cur->Data.SRV;
110
- hs.add(srv->pNameTarget, srv->wPort);
108
+ if(cur->wType == DNS_TYPE_SRV) {
109
+ // Use the ASCII version of the DNS lookup structure
110
+ const DNS_SRV_DATAA *srv = &cur->Data.SRV;
111
+ hs.add(srv->pNameTarget, srv->wPort);
112
+ }
111
113
  }
112
114
  DnsRecordListFree(root, DnsFreeRecordList);
113
115
  return LCB_SUCCESS;
@@ -131,8 +131,7 @@ ErrorMap::ParseStatus ErrorMap::parse(const char *s, size_t n, std::string &errm
131
131
  return PARSE_ERROR;
132
132
  }
133
133
 
134
- Json::Value::const_iterator ii = errsJson.begin();
135
- for (; ii != errsJson.end(); ++ii) {
134
+ for (Json::Value::const_iterator ii = errsJson.begin(); ii != errsJson.end(); ++ii) {
136
135
  // Key is the version in hex
137
136
  unsigned ec = 0;
138
137
  if (sscanf(ii.key().asCString(), "%x", &ec) != 1) {
@@ -155,14 +154,11 @@ ErrorMap::ParseStatus ErrorMap::parse(const char *s, size_t n, std::string &errm
155
154
  return PARSE_ERROR;
156
155
  }
157
156
 
158
- Json::Value::const_iterator jj = attrs.begin();
159
- for (; jj != attrs.end(); ++jj) {
160
- ErrorAttribute attr = getAttribute(jj->asString());
161
- if (attr == INVALID_ATTRIBUTE) {
162
- errmsg = "unknown attribute received";
163
- return UNKNOWN_VERSION;
157
+ for (const auto &jj : attrs) {
158
+ ErrorAttribute attr = getAttribute(jj.asString());
159
+ if (attr != INVALID_ATTRIBUTE) {
160
+ error.attributes.insert(attr);
164
161
  }
165
- error.attributes.insert(attr);
166
162
  }
167
163
  if (error.hasAttribute(AUTO_RETRY)) {
168
164
  const Json::Value &retryJson = errorJson["retry"];
@@ -124,7 +124,11 @@ enum ErrorAttribute {
124
124
  * This attribute means that the error is related to operating on \
125
125
  * a soft-deleted document. \
126
126
  */ \
127
- X(ITEM_DELETED, "item-deleted")
127
+ X(ITEM_DELETED, "item-deleted") \
128
+ /** \
129
+ * The error is related to rate limitation for the client (version 2) \
130
+ */ \
131
+ X(ITEM_RATE_LIMIT, "rate-limit")
128
132
 
129
133
  #define X(c, s) c,
130
134
  LCB_XERRMAP_ATTRIBUTES(X)
@@ -221,7 +225,7 @@ struct Error {
221
225
  uint16_t code;
222
226
  std::string shortname;
223
227
  std::string description;
224
- std::set< ErrorAttribute > attributes;
228
+ std::set<ErrorAttribute> attributes;
225
229
  SpecWrapper retry;
226
230
 
227
231
  Error() : code(-1) {}
@@ -280,7 +284,7 @@ class ErrorMap
280
284
  private:
281
285
  static const uint32_t MAX_VERSION;
282
286
  ErrorMap(const ErrorMap &);
283
- typedef std::map< uint16_t, Error > MapType;
287
+ typedef std::map<uint16_t, Error> MapType;
284
288
  MapType errors;
285
289
  uint32_t revision{0};
286
290
  uint32_t version{0};
@@ -157,6 +157,13 @@ lcb_STATUS lcb_map_error(lcb_INSTANCE *instance, int in)
157
157
  return LCB_ERR_DURABILITY_AMBIGUOUS;
158
158
  case PROTOCOL_BINARY_RESPONSE_LOCKED:
159
159
  return LCB_ERR_DOCUMENT_LOCKED;
160
+ case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_INGRESS:
161
+ case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_EGRESS:
162
+ case PROTOCOL_BINARY_RATE_LIMITED_MAX_CONNECTIONS:
163
+ case PROTOCOL_BINARY_RATE_LIMITED_MAX_COMMANDS:
164
+ return LCB_ERR_RATE_LIMITED;
165
+ case PROTOCOL_BINARY_SCOPE_SIZE_LIMIT_EXCEEDED:
166
+ return LCB_ERR_QUOTA_LIMITED;
160
167
  default:
161
168
  if (instance != nullptr) {
162
169
  return instance->callbacks.errmap(instance, in);
@@ -269,20 +276,19 @@ void init_resp(lcb_INSTANCE *instance, mc_PIPELINE *pipeline, const MemcachedRes
269
276
  resp->ctx.key.assign(key, key_len);
270
277
  }
271
278
 
272
- auto *server = static_cast<lcb::Server *>(pipeline);
279
+ const auto *server = static_cast<lcb::Server *>(pipeline);
273
280
  const lcb_host_t *remote = server->curhost;
274
281
  if (remote) {
275
- std::stringstream ss;
282
+ resp->ctx.endpoint.reserve(sizeof(remote->host) + sizeof(remote->port) + 3);
276
283
  if (remote->ipv6) {
277
- ss << '[';
284
+ resp->ctx.endpoint.append("[");
278
285
  }
279
- ss << remote->host;
286
+ resp->ctx.endpoint.append(remote->host);
280
287
  if (remote->ipv6) {
281
- ss << ']';
288
+ resp->ctx.endpoint.append("]");
282
289
  }
283
- ss << ':';
284
- ss << remote->port;
285
- resp->ctx.endpoint = ss.str();
290
+ resp->ctx.endpoint.append(":");
291
+ resp->ctx.endpoint.append(remote->port);
286
292
  }
287
293
  }
288
294
 
@@ -421,7 +427,7 @@ static void H_get(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse *
421
427
 
422
428
  void *freeptr = nullptr;
423
429
  maybe_decompress(o, response, &resp, &freeptr);
424
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
430
+ lcb::trace::finish_kv_span(pipeline, request, response);
425
431
  TRACE_GET_END(o, request, response, &resp);
426
432
  record_kv_op_latency("get", o, request);
427
433
  if (request->flags & MCREQ_F_REQEXT) {
@@ -455,7 +461,7 @@ static void H_exists(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedRespons
455
461
  resp.seqno = lcb_ntohll(resp.seqno);
456
462
  }
457
463
  }
458
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
464
+ lcb::trace::finish_kv_span(pipeline, request, response);
459
465
  TRACE_EXISTS_END(root, request, response, &resp);
460
466
  record_kv_op_latency("exists", root, request);
461
467
  invoke_callback(request, root, &resp, LCB_CALLBACK_EXISTS);
@@ -555,7 +561,7 @@ static void H_subdoc(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedRespons
555
561
  handle_error_info(response, resp);
556
562
  }
557
563
  }
558
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
564
+ lcb::trace::finish_kv_span(pipeline, request, response);
559
565
 
560
566
  if (cbtype == LCB_CALLBACK_SDLOOKUP) {
561
567
  record_kv_op_latency("lookup_in", o, request);
@@ -689,7 +695,7 @@ static void H_delete(mc_PIPELINE *pipeline, mc_PACKET *packet, MemcachedResponse
689
695
  init_resp(root, pipeline, response, packet, immerr, &resp);
690
696
  handle_error_info(response, resp);
691
697
  handle_mutation_token(root, response, packet, &resp.mt);
692
- LCBTRACE_KV_FINISH(pipeline, packet, resp, response->duration());
698
+ lcb::trace::finish_kv_span(pipeline, packet, response);
693
699
  TRACE_REMOVE_END(root, packet, response, &resp);
694
700
  record_kv_op_latency("remove", root, packet);
695
701
  invoke_callback(packet, root, &resp, LCB_CALLBACK_REMOVE);
@@ -797,7 +803,7 @@ static void H_observe_seqno(mc_PIPELINE *pipeline, mc_PACKET *request, Memcached
797
803
  /* Get the server for this command. Note that since this is a successful
798
804
  * operation, the server is never a dummy */
799
805
  }
800
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
806
+ lcb::trace::finish_kv_span(pipeline, request, response);
801
807
  invoke_callback(request, root, &resp, LCB_CALLBACK_OBSEQNO);
802
808
  }
803
809
 
@@ -829,7 +835,7 @@ static void H_store(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse
829
835
  resp.rflags |= LCB_RESP_F_EXTDATA | LCB_RESP_F_FINAL;
830
836
  handle_mutation_token(root, response, request, &resp.mt);
831
837
  TRACE_STORE_END(root, request, response, &resp);
832
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
838
+ lcb::trace::finish_kv_span(pipeline, request, response);
833
839
  record_kv_op_latency_store(root, request, &resp);
834
840
  if (request->flags & MCREQ_F_REQEXT) {
835
841
  request->u_rdata.exdata->procs->handler(pipeline, request, LCB_CALLBACK_STORE, immerr, &resp);
@@ -854,7 +860,7 @@ static void H_arithmetic(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedRes
854
860
  }
855
861
  resp.rflags |= LCB_RESP_F_FINAL;
856
862
  resp.ctx.cas = response->cas();
857
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
863
+ lcb::trace::finish_kv_span(pipeline, request, response);
858
864
  TRACE_ARITHMETIC_END(root, request, response, &resp);
859
865
  record_kv_op_latency("arithmetic", root, request);
860
866
  invoke_callback(request, root, &resp, LCB_CALLBACK_COUNTER);
@@ -941,7 +947,7 @@ static void H_noop(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse
941
947
  {
942
948
  lcb_INSTANCE *root = get_instance(pipeline);
943
949
  lcb_RESPNOOP resp{};
944
- mc_REQDATAEX *exdata = request->u_rdata.exdata;
950
+ const mc_REQDATAEX *exdata = request->u_rdata.exdata;
945
951
 
946
952
  make_error(root, &resp, response, immerr, request);
947
953
 
@@ -955,7 +961,7 @@ static void H_touch(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse
955
961
  init_resp(root, pipeline, response, request, immerr, &resp);
956
962
  handle_error_info(response, resp);
957
963
  resp.rflags |= LCB_RESP_F_FINAL;
958
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
964
+ lcb::trace::finish_kv_span(pipeline, request, response);
959
965
  TRACE_TOUCH_END(root, request, response, &resp);
960
966
  record_kv_op_latency("touch", root, request);
961
967
  invoke_callback(request, root, &resp, LCB_CALLBACK_TOUCH);
@@ -968,7 +974,7 @@ static void H_unlock(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedRespons
968
974
  init_resp(root, pipeline, response, request, immerr, &resp);
969
975
  handle_error_info(response, resp);
970
976
  resp.rflags |= LCB_RESP_F_FINAL;
971
- LCBTRACE_KV_FINISH(pipeline, request, resp, response->duration());
977
+ lcb::trace::finish_kv_span(pipeline, request, response);
972
978
  TRACE_UNLOCK_END(root, request, response, &resp);
973
979
  record_kv_op_latency("unlock", root, request);
974
980
  invoke_callback(request, root, &resp, LCB_CALLBACK_UNLOCK);
@@ -136,8 +136,10 @@ void lcbio_ctx_close_ex(lcbio_CTX *ctx, lcbio_CTXCLOSE_cb cb, void *arg, lcbio_C
136
136
  }
137
137
 
138
138
  oldrc = ctx->sock->refcount;
139
- lcb_log(LOGARGS(ctx, DEBUG), CTX_LOGFMT "Destroying context. Pending Writes=%d, Entered=%s, Socket Refcount=%d",
140
- CTX_LOGID(ctx), (int)ctx->npending, (int)ctx->entered ? "true" : "false", oldrc);
139
+
140
+ lcb_log(LOGARGS(ctx, DEBUG),
141
+ CTX_LOGFMT "Destroying context for SOCK=%016" PRIx64 ". Pending Writes=%d, Entered=%s, Socket Refcount=%d",
142
+ CTX_LOGID(ctx), ctx->sock->id, (int)ctx->npending, (int)ctx->entered ? "true" : "false", oldrc);
141
143
 
142
144
  if (cb) {
143
145
  int reusable = ctx->npending == 0 && /* no pending events */
@@ -341,6 +341,11 @@ static bool is_fastpath_error(uint16_t rc)
341
341
  case PROTOCOL_BINARY_RESPONSE_SYNC_WRITE_IN_PROGRESS:
342
342
  case PROTOCOL_BINARY_RESPONSE_SYNC_WRITE_AMBIGUOUS:
343
343
  case PROTOCOL_BINARY_RESPONSE_LOCKED:
344
+ case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_INGRESS:
345
+ case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_EGRESS:
346
+ case PROTOCOL_BINARY_RATE_LIMITED_MAX_CONNECTIONS:
347
+ case PROTOCOL_BINARY_RATE_LIMITED_MAX_COMMANDS:
348
+ case PROTOCOL_BINARY_SCOPE_SIZE_LIMIT_EXCEEDED:
344
349
  return true;
345
350
  default:
346
351
  if (rc >= 0xc0 && rc <= 0xcc) {
@@ -395,10 +400,6 @@ int Server::handle_unknown_error(const mc_PACKET *request, const MemcachedRespon
395
400
  newerr = LCB_ERR_TEMPORARY_FAILURE;
396
401
  }
397
402
 
398
- if (err.hasAttribute(errmap::CONSTRAINT_FAILURE)) {
399
- newerr = LCB_ERR_CAS_MISMATCH;
400
- }
401
-
402
403
  if (err.hasAttribute(errmap::AUTH)) {
403
404
  newerr = LCB_ERR_AUTHENTICATION_FAILURE;
404
405
  }
@@ -754,6 +755,8 @@ static const char *opcode_name(uint8_t code)
754
755
  return "subdoc_get_count";
755
756
  case PROTOCOL_BINARY_CMD_GET_ERROR_MAP:
756
757
  return "get_error_map";
758
+ case PROTOCOL_BINARY_CMD_GET_META:
759
+ return "exists";
757
760
  default:
758
761
  return "unknown";
759
762
  }
@@ -816,7 +819,7 @@ void Server::purge_single(mc_PACKET *pkt, lcb_STATUS err)
816
819
  std::string msg(Json::FastWriter().write(info));
817
820
  if (msg.size() > 1) {
818
821
  lcb_log(LOGARGS(instance, WARN), "Failing command with error %s: %.*s", lcb_strerror_short(err),
819
- (int)(msg.size() - 1), msg.c_str());
822
+ (int)msg.size(), msg.c_str());
820
823
  }
821
824
  } else {
822
825
  lcb_log(LOGARGS_T(WARN), LOGFMT "Failing command (pkt=%p, opaque=%lu, opcode=0x%x) with error %s", LOGID_T(),