couchbase 3.2.3 → 3.2.4

Sign up to get free protection for your applications and to get access to all the features.
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(),