libcouchbase 1.3.0 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +2 -2
  3. data/ext/libcouchbase/CMakeLists.txt +51 -25
  4. data/ext/libcouchbase/CONTRIBUTING.md +46 -65
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +163 -0
  6. data/ext/libcouchbase/cmake/Modules/DownloadLcbDep.cmake +9 -11
  7. data/ext/libcouchbase/cmake/Modules/FindProfiler.cmake +16 -0
  8. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +6 -6
  9. data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
  10. data/ext/libcouchbase/cmake/configure +16 -0
  11. data/ext/libcouchbase/example/CMakeLists.txt +17 -2
  12. data/ext/libcouchbase/example/analytics/.gitignore +1 -0
  13. data/ext/libcouchbase/example/analytics/analytics.c +158 -0
  14. data/ext/libcouchbase/example/analytics/build-queries.rb +34 -0
  15. data/ext/libcouchbase/example/analytics/cJSON.c +1 -0
  16. data/ext/libcouchbase/example/analytics/cJSON.h +1 -0
  17. data/ext/libcouchbase/example/analytics/queries.h +113 -0
  18. data/ext/libcouchbase/example/analytics/queries/00-show-dataverse.json +5 -0
  19. data/ext/libcouchbase/example/analytics/queries/01-setup-dataset-breweries.json +6 -0
  20. data/ext/libcouchbase/example/analytics/queries/02-setup-dataset-beers.json +6 -0
  21. data/ext/libcouchbase/example/analytics/queries/03-initiate-shadow.json +6 -0
  22. data/ext/libcouchbase/example/analytics/queries/04-list-datasets.json +7 -0
  23. data/ext/libcouchbase/example/analytics/queries/05-count-breweries.json +5 -0
  24. data/ext/libcouchbase/example/analytics/queries/06-first-brewery.json +6 -0
  25. data/ext/libcouchbase/example/analytics/queries/07-key-based-lookup.json +6 -0
  26. data/ext/libcouchbase/example/analytics/queries/08-exact-match-lookup.json +7 -0
  27. data/ext/libcouchbase/example/analytics/queries/09-exact-match-lookup-different-shape.json +6 -0
  28. data/ext/libcouchbase/example/analytics/queries/10-other-query-filters.json +6 -0
  29. data/ext/libcouchbase/example/analytics/queries/11-equijoin.json +9 -0
  30. data/ext/libcouchbase/example/analytics/queries/12-equijoin-select-star.json +10 -0
  31. data/ext/libcouchbase/example/analytics/queries/13-ansi-join.json +8 -0
  32. data/ext/libcouchbase/example/analytics/queries/14-join-select-values.json +8 -0
  33. data/ext/libcouchbase/example/analytics/queries/15-nested-outer-join.json +7 -0
  34. data/ext/libcouchbase/example/analytics/queries/16-theta-join.json +8 -0
  35. data/ext/libcouchbase/example/analytics/queries/17-existential-quantification.json +9 -0
  36. data/ext/libcouchbase/example/analytics/queries/18-universal-quantification.json +7 -0
  37. data/ext/libcouchbase/example/analytics/queries/19-simple-aggregation.json +6 -0
  38. data/ext/libcouchbase/example/analytics/queries/20-simple-aggregation-unwrapped-value.json +6 -0
  39. data/ext/libcouchbase/example/analytics/queries/21-simple-aggregation-explicit.json +6 -0
  40. data/ext/libcouchbase/example/analytics/queries/22-grouping-and-aggregation.json +6 -0
  41. data/ext/libcouchbase/example/analytics/queries/23-grouping-and-aggregation-with-hint.json +7 -0
  42. data/ext/libcouchbase/example/analytics/queries/24-grouping-and-limits.json +7 -0
  43. data/ext/libcouchbase/example/analytics/queries/25-named-parameters.json +7 -0
  44. data/ext/libcouchbase/example/analytics/queries/26-positional-parameters.json +7 -0
  45. data/ext/libcouchbase/example/crypto/common_provider.c +2 -0
  46. data/ext/libcouchbase/example/crypto/common_provider.h +2 -0
  47. data/ext/libcouchbase/example/crypto/openssl_symmetric_decrypt.c +5 -0
  48. data/ext/libcouchbase/example/crypto/openssl_symmetric_encrypt.c +0 -1
  49. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.c +16 -26
  50. data/ext/libcouchbase/example/db/db.c +10 -6
  51. data/ext/libcouchbase/example/fts/.gitignore +1 -0
  52. data/ext/libcouchbase/example/fts/build-queries.rb +33 -0
  53. data/ext/libcouchbase/example/fts/fts.c +142 -0
  54. data/ext/libcouchbase/example/fts/queries.h +61 -0
  55. data/ext/libcouchbase/example/fts/queries/00-simple-text-query.json +12 -0
  56. data/ext/libcouchbase/example/fts/queries/01-simple-text-query-on-non-default-index.json +9 -0
  57. data/ext/libcouchbase/example/fts/queries/02-simple-text-query-on-stored-field.json +13 -0
  58. data/ext/libcouchbase/example/fts/queries/03-match-query-with-facet.json +19 -0
  59. data/ext/libcouchbase/example/fts/queries/04-docid-query.json +11 -0
  60. data/ext/libcouchbase/example/fts/queries/05-unanalyzed-term-query-with-fuzziness-level-of-0.json +13 -0
  61. data/ext/libcouchbase/example/fts/queries/06-unanalyzed-term-query-with-fuzziness-level-of-2.json +14 -0
  62. data/ext/libcouchbase/example/fts/queries/07-match-phrase-query.json +13 -0
  63. data/ext/libcouchbase/example/fts/queries/08-phrase-query.json +16 -0
  64. data/ext/libcouchbase/example/fts/queries/09-query-string-query.json +9 -0
  65. data/ext/libcouchbase/example/fts/queries/10-conjunction-query.json +21 -0
  66. data/ext/libcouchbase/example/fts/queries/11-wild-card-query.json +13 -0
  67. data/ext/libcouchbase/example/fts/queries/12-numeric-range-query.json +11 -0
  68. data/ext/libcouchbase/example/fts/queries/13-regexp-query.json +13 -0
  69. data/ext/libcouchbase/example/minimal/.gitignore +1 -0
  70. data/ext/libcouchbase/example/minimal/query.c +185 -0
  71. data/ext/libcouchbase/example/subdoc/subdoc-xattrs.c +2 -2
  72. data/ext/libcouchbase/example/tracing/cJSON.c +1 -1
  73. data/ext/libcouchbase/example/tracing/cJSON.h +1 -1
  74. data/ext/libcouchbase/include/libcouchbase/cbft.h +38 -4
  75. data/ext/libcouchbase/include/libcouchbase/cntl-private.h +8 -97
  76. data/ext/libcouchbase/include/libcouchbase/cntl.h +288 -8
  77. data/ext/libcouchbase/include/libcouchbase/couchbase.h +47 -10
  78. data/ext/libcouchbase/include/libcouchbase/crypto.h +214 -48
  79. data/ext/libcouchbase/include/libcouchbase/deprecated.h +12 -0
  80. data/ext/libcouchbase/include/libcouchbase/error.h +33 -2
  81. data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +1 -1
  82. data/ext/libcouchbase/include/libcouchbase/n1ql.h +87 -13
  83. data/ext/libcouchbase/include/libcouchbase/subdoc.h +3 -7
  84. data/ext/libcouchbase/include/libcouchbase/tracing.h +174 -56
  85. data/ext/libcouchbase/include/libcouchbase/vbucket.h +21 -1
  86. data/ext/libcouchbase/include/libcouchbase/views.h +49 -4
  87. data/ext/libcouchbase/packaging/deb/control +2 -3
  88. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  89. data/ext/libcouchbase/plugins/io/libev/CMakeLists.txt +7 -5
  90. data/ext/libcouchbase/plugins/io/libevent/CMakeLists.txt +7 -5
  91. data/ext/libcouchbase/plugins/io/libuv/CMakeLists.txt +14 -12
  92. data/ext/libcouchbase/plugins/io/libuv/libuv_compat.h +3 -0
  93. data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +14 -6
  94. data/ext/libcouchbase/plugins/io/select/CMakeLists.txt +7 -5
  95. data/ext/libcouchbase/src/bootstrap.cc +6 -1
  96. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +2 -7
  97. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +1 -1
  98. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +4 -11
  99. data/ext/libcouchbase/src/bucketconfig/clconfig.h +29 -36
  100. data/ext/libcouchbase/src/bucketconfig/confmon.cc +4 -2
  101. data/ext/libcouchbase/src/cntl.cc +181 -151
  102. data/ext/libcouchbase/src/config_static.h +1 -1
  103. data/ext/libcouchbase/src/connspec.cc +5 -1
  104. data/ext/libcouchbase/src/connspec.h +3 -1
  105. data/ext/libcouchbase/src/crypto.cc +93 -80
  106. data/ext/libcouchbase/src/dns-srv.cc +1 -1
  107. data/ext/libcouchbase/src/handler.cc +0 -1
  108. data/ext/libcouchbase/src/http/http-priv.h +1 -0
  109. data/ext/libcouchbase/src/http/http.cc +1 -2
  110. data/ext/libcouchbase/src/instance.cc +21 -2
  111. data/ext/libcouchbase/src/internal.h +1 -0
  112. data/ext/libcouchbase/src/lcbio/ctx.c +24 -3
  113. data/ext/libcouchbase/src/lcbio/ioutils.cc +1 -1
  114. data/ext/libcouchbase/src/lcbio/rw-inl.h +22 -1
  115. data/ext/libcouchbase/src/lcbio/ssl.h +2 -0
  116. data/ext/libcouchbase/src/mc/compress.cc +18 -11
  117. data/ext/libcouchbase/src/mc/mcreq.c +2 -0
  118. data/ext/libcouchbase/src/mc/mcreq.h +1 -1
  119. data/ext/libcouchbase/src/mcserver/mcserver.cc +163 -6
  120. data/ext/libcouchbase/src/mcserver/negotiate.cc +17 -7
  121. data/ext/libcouchbase/src/n1ql/n1ql.cc +12 -3
  122. data/ext/libcouchbase/src/newconfig.cc +4 -3
  123. data/ext/libcouchbase/src/nodeinfo.cc +1 -7
  124. data/ext/libcouchbase/src/operations/observe.cc +1 -0
  125. data/ext/libcouchbase/src/operations/ping.cc +5 -3
  126. data/ext/libcouchbase/src/retryq.cc +22 -0
  127. data/ext/libcouchbase/src/retryq.h +2 -1
  128. data/ext/libcouchbase/src/rnd.cc +5 -12
  129. data/ext/libcouchbase/src/settings.c +4 -7
  130. data/ext/libcouchbase/src/settings.h +6 -2
  131. data/ext/libcouchbase/src/strcodecs/base64.c +59 -0
  132. data/ext/libcouchbase/src/strcodecs/strcodecs.h +2 -0
  133. data/ext/libcouchbase/src/trace.h +2 -2
  134. data/ext/libcouchbase/src/tracing/span.cc +177 -45
  135. data/ext/libcouchbase/src/tracing/threshold_logging_tracer.cc +70 -28
  136. data/ext/libcouchbase/src/tracing/tracing-internal.h +33 -48
  137. data/ext/libcouchbase/src/vbucket/vbucket.c +146 -30
  138. data/ext/libcouchbase/src/wait.cc +1 -1
  139. data/ext/libcouchbase/tests/CMakeLists.txt +13 -4
  140. data/ext/libcouchbase/tests/iotests/mock-environment.cc +1 -1
  141. data/ext/libcouchbase/tests/iotests/t_misc.cc +2 -2
  142. data/ext/libcouchbase/tests/iotests/t_views.cc +1 -1
  143. data/ext/libcouchbase/tests/iotests/testutil.cc +3 -2
  144. data/ext/libcouchbase/tests/vbucket/confdata/map_node_present_nodesext_missing_nodes.json +94 -0
  145. data/ext/libcouchbase/tests/vbucket/t_config.cc +15 -0
  146. data/ext/libcouchbase/tools/CMakeLists.txt +11 -6
  147. data/ext/libcouchbase/tools/cbc-handlers.h +9 -0
  148. data/ext/libcouchbase/tools/cbc-proxy.cc +1 -1
  149. data/ext/libcouchbase/tools/cbc.cc +33 -5
  150. data/ext/libcouchbase/tools/common/options.cc +1 -1
  151. data/ext/libcouchbase/tools/extract-packets.rb +110 -0
  152. data/lib/libcouchbase/connection.rb +13 -5
  153. data/lib/libcouchbase/ext/tasks.rb +1 -1
  154. data/lib/libcouchbase/version.rb +1 -1
  155. metadata +62 -7
@@ -40,6 +40,8 @@ static void tlt_destructor(lcbtrace_TRACER *wrapper)
40
40
  }
41
41
  if (wrapper->cookie) {
42
42
  ThresholdLoggingTracer *tracer = reinterpret_cast< ThresholdLoggingTracer * >(wrapper->cookie);
43
+ tracer->do_flush_orphans();
44
+ tracer->do_flush_threshold();
43
45
  delete tracer;
44
46
  wrapper->cookie = NULL;
45
47
  }
@@ -53,11 +55,15 @@ static void tlt_report(lcbtrace_TRACER *wrapper, lcbtrace_SPAN *span)
53
55
  }
54
56
 
55
57
  ThresholdLoggingTracer *tracer = reinterpret_cast< ThresholdLoggingTracer * >(wrapper->cookie);
56
- if (span->tags[LCBTRACE_TAG_SERVICE] == LCBTRACE_TAG_SERVICE_KV) {
57
- if (lcbtrace_span_is_orphaned(span)) {
58
- tracer->add_orphan(span);
59
- } else {
60
- tracer->check_threshold(span);
58
+ char *value = NULL;
59
+ size_t nvalue;
60
+ if (lcbtrace_span_get_tag_str(span, LCBTRACE_TAG_SERVICE, &value, &nvalue) == LCB_SUCCESS) {
61
+ if (strncmp(value, LCBTRACE_TAG_SERVICE_KV, nvalue) == 0) {
62
+ if (lcbtrace_span_is_orphaned(span)) {
63
+ tracer->add_orphan(span);
64
+ } else {
65
+ tracer->check_threshold(span);
66
+ }
61
67
  }
62
68
  }
63
69
  }
@@ -77,17 +83,39 @@ lcbtrace_TRACER *ThresholdLoggingTracer::wrap()
77
83
  return m_wrapper;
78
84
  }
79
85
 
80
- ReportedSpan ThresholdLoggingTracer::convert(lcbtrace_SPAN *span)
86
+ QueueEntry ThresholdLoggingTracer::convert(lcbtrace_SPAN *span)
81
87
  {
82
- ReportedSpan orphan;
88
+ QueueEntry orphan;
83
89
  orphan.duration = span->duration();
84
90
  Json::Value entry;
85
- entry["operation_name"] = span->m_opname;
86
- entry["operation_id"] = span->tags[LCBTRACE_TAG_OPERATION_ID];
87
- entry["last_local_id"] = span->tags[LCBTRACE_TAG_LOCAL_ID];
88
- entry["last_local_address"] = span->tags[LCBTRACE_TAG_LOCAL_ADDRESS];
89
- entry["last_remote_address"] = span->tags[LCBTRACE_TAG_PEER_ADDRESS];
90
- entry["server_us"] = span->tags[LCBTRACE_TAG_PEER_LATENCY];
91
+ char *value;
92
+ size_t nvalue;
93
+
94
+ if (lcbtrace_span_get_tag_str(
95
+ span, LCBTRACE_TAG_OPERATION_ID, &value, &nvalue) ==
96
+ LCB_SUCCESS) {
97
+ entry["last_operation_id"] = std::string(span->m_opname) + ":" +
98
+ std::string(value, value + nvalue);
99
+ }
100
+ if (lcbtrace_span_get_tag_str(
101
+ span, LCBTRACE_TAG_LOCAL_ID, &value, &nvalue) == LCB_SUCCESS) {
102
+ entry["last_local_id"] = std::string(value, value + nvalue);
103
+ }
104
+ if (lcbtrace_span_get_tag_str(
105
+ span, LCBTRACE_TAG_LOCAL_ADDRESS, &value, &nvalue) ==
106
+ LCB_SUCCESS) {
107
+ entry["last_local_address"] = std::string(value, value + nvalue);
108
+ }
109
+ if (lcbtrace_span_get_tag_str(
110
+ span, LCBTRACE_TAG_PEER_ADDRESS, &value, &nvalue) ==
111
+ LCB_SUCCESS) {
112
+ entry["last_remote_address"] = std::string(value, value + nvalue);
113
+ }
114
+ uint64_t num;
115
+ if (lcbtrace_span_get_tag_uint64(span, LCBTRACE_TAG_PEER_LATENCY, &num) ==
116
+ LCB_SUCCESS) {
117
+ entry["server_us"] = (Json::UInt64)num;
118
+ }
91
119
  entry["total_us"] = (Json::UInt64)orphan.duration;
92
120
  orphan.payload = Json::FastWriter().write(entry);
93
121
  return orphan;
@@ -105,26 +133,46 @@ void ThresholdLoggingTracer::check_threshold(lcbtrace_SPAN *span)
105
133
  }
106
134
  }
107
135
 
108
- void ThresholdLoggingTracer::flush_queue(FixedQueue< ReportedSpan > &queue, const char *message)
136
+ void ThresholdLoggingTracer::flush_queue(FixedSpanQueue &queue, const char *message, bool warn = false)
109
137
  {
110
- std::vector< ReportedSpan > &slice = queue.get_sorted();
111
138
  Json::Value entries;
112
139
  entries["service"] = "kv";
113
- entries["count"] = (Json::UInt)slice.size();
140
+ entries["count"] = (Json::UInt)queue.size();
114
141
  Json::Value top;
115
- for (size_t ii = 0; ii < slice.size(); ii++) {
142
+ while (!queue.empty())
143
+ {
116
144
  Json::Value entry;
117
- if (Json::Reader().parse(slice[ii].payload, entry)) {
145
+ if (Json::Reader().parse(queue.top().payload, entry)) {
118
146
  top.append(entry);
119
147
  }
148
+ queue.pop();
120
149
  }
121
150
  entries["top"] = top;
122
151
  std::string doc = Json::FastWriter().write(entries);
123
152
  if (doc.size() > 0 && doc[doc.size() - 1] == '\n') {
124
153
  doc[doc.size() - 1] = '\0';
125
154
  }
126
- lcb_log(LOGARGS(this, WARN), "%s: %s", message, doc.c_str());
127
- queue.clear();
155
+ if (warn) {
156
+ lcb_log(LOGARGS(this, WARN), "%s: %s", message, doc.c_str());
157
+ } else {
158
+ lcb_log(LOGARGS(this, INFO), "%s: %s", message, doc.c_str());
159
+ }
160
+ }
161
+
162
+ void ThresholdLoggingTracer::do_flush_orphans()
163
+ {
164
+ if (m_orphans.empty()) {
165
+ return;
166
+ }
167
+ flush_queue(m_orphans, "Orphan responses observed", true);
168
+ }
169
+
170
+ void ThresholdLoggingTracer::do_flush_threshold()
171
+ {
172
+ if (m_threshold.empty()) {
173
+ return;
174
+ }
175
+ flush_queue(m_threshold, "Operations over threshold");
128
176
  }
129
177
 
130
178
  void ThresholdLoggingTracer::flush_orphans()
@@ -135,10 +183,7 @@ void ThresholdLoggingTracer::flush_orphans()
135
183
  } else {
136
184
  m_oflush.rearm(tv);
137
185
  }
138
- if (m_orphans.empty()) {
139
- return;
140
- }
141
- flush_queue(m_orphans, "Orphan responses observed");
186
+ do_flush_orphans();
142
187
  }
143
188
 
144
189
  void ThresholdLoggingTracer::flush_threshold()
@@ -149,10 +194,7 @@ void ThresholdLoggingTracer::flush_threshold()
149
194
  } else {
150
195
  m_tflush.rearm(tv);
151
196
  }
152
- if (m_threshold.empty()) {
153
- return;
154
- }
155
- flush_queue(m_threshold, "Operations over threshold");
197
+ do_flush_threshold();
156
198
  }
157
199
 
158
200
  ThresholdLoggingTracer::ThresholdLoggingTracer(lcb_t instance)
@@ -35,6 +35,7 @@ class Span
35
35
  {
36
36
  public:
37
37
  Span(lcbtrace_TRACER *tracer, const char *opname, uint64_t start, lcbtrace_REF_TYPE ref, lcbtrace_SPAN *other);
38
+ ~Span();
38
39
 
39
40
  void finish(uint64_t finish);
40
41
  uint64_t duration()
@@ -42,7 +43,11 @@ class Span
42
43
  return m_finish - m_start;
43
44
  }
44
45
 
45
- template < typename T > void add_tag(const char *name, T value);
46
+ void add_tag(const char *name, int copy, const char *value);
47
+ void add_tag(const char *name, int copy, const char *value, size_t value_len);
48
+ void add_tag(const char *name, int copy, uint64_t value);
49
+ void add_tag(const char *name, int copy, double value);
50
+ void add_tag(const char *name, int copy, bool value);
46
51
 
47
52
  lcbtrace_TRACER *m_tracer;
48
53
  std::string m_opname;
@@ -50,8 +55,8 @@ class Span
50
55
  uint64_t m_start;
51
56
  uint64_t m_finish;
52
57
  bool m_orphaned;
53
- Json::Value tags;
54
58
  Span *m_parent;
59
+ sllist_root m_tags;
55
60
  };
56
61
 
57
62
  struct ReportedSpan {
@@ -64,61 +69,37 @@ struct ReportedSpan {
64
69
  }
65
70
  };
66
71
 
67
- template < typename T > class FixedQueue
72
+ template < typename T > class FixedQueue: private std::priority_queue<T>
68
73
  {
69
74
  public:
70
75
  explicit FixedQueue(size_t capacity) : m_capacity(capacity) {}
71
76
 
72
- void push(T item)
73
- {
74
- if (m_items.size() < m_capacity) {
75
- m_items.push_back(item);
76
- std::push_heap(m_items.begin(), m_items.end());
77
- } else {
78
- std::sort_heap(m_items.begin(), m_items.end());
79
- if (m_items.front() < item) {
80
- m_items[0] = item;
81
- }
82
- std::make_heap(m_items.begin(), m_items.end());
77
+ void push(const T& item) {
78
+ std::priority_queue<T>::push(item);
79
+ if (this->size() > m_capacity) {
80
+ this->c.pop_back();
83
81
  }
84
82
  }
85
-
86
- size_t size()
87
- {
88
- return m_items.size();
89
- }
90
-
91
- bool empty()
92
- {
93
- return m_items.empty();
94
- }
95
-
96
- void clear()
97
- {
98
- m_items.clear();
99
- }
100
-
101
- std::vector< T > &get_sorted()
102
- {
103
- std::sort_heap(m_items.begin(), m_items.end());
104
- return m_items;
105
- }
106
-
83
+ using std::priority_queue<T>::empty;
84
+ using std::priority_queue<T>::top;
85
+ using std::priority_queue<T>::pop;
86
+ using std::priority_queue<T>::size;
107
87
  private:
108
88
  size_t m_capacity;
109
- std::vector< T > m_items;
110
89
  };
111
90
 
91
+ typedef ReportedSpan QueueEntry;
92
+ typedef FixedQueue<QueueEntry> FixedSpanQueue;
112
93
  class ThresholdLoggingTracer
113
94
  {
114
95
  lcbtrace_TRACER *m_wrapper;
115
96
  lcb_settings *m_settings;
116
97
 
117
- FixedQueue< ReportedSpan > m_orphans;
118
- FixedQueue< ReportedSpan > m_threshold;
98
+ FixedSpanQueue m_orphans;
99
+ FixedSpanQueue m_threshold;
119
100
 
120
- void flush_queue(FixedQueue< ReportedSpan > &queue, const char *message);
121
- ReportedSpan convert(lcbtrace_SPAN *span);
101
+ void flush_queue(FixedSpanQueue &queue, const char *message, bool warn);
102
+ QueueEntry convert(lcbtrace_SPAN *span);
122
103
 
123
104
  public:
124
105
  ThresholdLoggingTracer(lcb_t instance);
@@ -129,6 +110,8 @@ class ThresholdLoggingTracer
129
110
 
130
111
  void flush_orphans();
131
112
  void flush_threshold();
113
+ void do_flush_orphans();
114
+ void do_flush_threshold();
132
115
 
133
116
  lcb::io::Timer< ThresholdLoggingTracer, &ThresholdLoggingTracer::flush_orphans > m_oflush;
134
117
  lcb::io::Timer< ThresholdLoggingTracer, &ThresholdLoggingTracer::flush_threshold > m_tflush;
@@ -164,14 +147,16 @@ void lcbtrace_span_set_orphaned(lcbtrace_SPAN *span, int val);
164
147
  if (span) { \
165
148
  lcbtrace_span_add_tag_uint64(span, LCBTRACE_TAG_PEER_LATENCY, (response)->duration()); \
166
149
  lcb::Server *server = static_cast< lcb::Server * >(pipeline); \
167
- const lcb_host_t &remote = server->get_host(); \
168
- std::string hh; \
169
- if (remote.ipv6) { \
170
- hh.append("[").append(remote.host).append("]:").append(remote.port); \
171
- } else { \
172
- hh.append(remote.host).append(":").append(remote.port); \
150
+ const lcb_host_t *remote = server->curhost; \
151
+ if (remote) { \
152
+ std::string hh; \
153
+ if (remote->ipv6) { \
154
+ hh.append("[").append(remote->host).append("]:").append(remote->port); \
155
+ } else { \
156
+ hh.append(remote->host).append(":").append(remote->port); \
157
+ } \
158
+ lcbtrace_span_add_tag_str(span, LCBTRACE_TAG_PEER_ADDRESS, hh.c_str()); \
173
159
  } \
174
- lcbtrace_span_add_tag_str(span, LCBTRACE_TAG_PEER_ADDRESS, hh.c_str()); \
175
160
  lcbio_CTX *ctx = server->connctx; \
176
161
  if (ctx) { \
177
162
  char local_id[34] = {}; \
@@ -385,7 +385,7 @@ build_server_strings(lcbvb_CONFIG *cfg, lcbvb_SERVER *server)
385
385
  * @return
386
386
  */
387
387
  static int
388
- build_server_3x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js)
388
+ build_server_3x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js, char **network)
389
389
  {
390
390
  cJSON *jsvcs;
391
391
  char *htmp;
@@ -414,6 +414,37 @@ build_server_3x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js)
414
414
  goto GT_ERR;
415
415
  }
416
416
 
417
+ if (network && *network && strcmp(*network, "default") != 0) {
418
+ cJSON *jaltaddr = cJSON_GetObjectItem(js, "alternateAddresses");
419
+ if (jaltaddr && jaltaddr->type == cJSON_Object) {
420
+ cJSON *jnetwork = cJSON_GetObjectItem(jaltaddr, *network);
421
+ if (jnetwork && get_jstr(jnetwork, "hostname", &htmp)) {
422
+ cJSON *jports;
423
+ server->alt_hostname = strdup(htmp);
424
+ jports = cJSON_GetObjectItem(jnetwork, "ports");
425
+ if (jports && jports->type == cJSON_Object) {
426
+ extract_services(cfg, jports, &server->alt_svc, 0);
427
+ extract_services(cfg, jports, &server->alt_svc_ssl, 1);
428
+ }
429
+
430
+ #define COPY_SERVICE(src, dst) \
431
+ if ((dst)->data == 0) (dst)->data = (src)->data; \
432
+ if ((dst)->mgmt == 0) (dst)->mgmt = (src)->mgmt; \
433
+ if ((dst)->views == 0) (dst)->views = (src)->views; \
434
+ if ((dst)->n1ql == 0) (dst)->n1ql = (src)->n1ql; \
435
+ if ((dst)->fts == 0) (dst)->fts = (src)->fts; \
436
+ if ((dst)->ixadmin == 0) (dst)->ixadmin = (src)->ixadmin; \
437
+ if ((dst)->ixquery == 0) (dst)->ixquery = (src)->ixquery; \
438
+ if ((dst)->cbas == 0) (dst)->cbas = (src)->cbas;
439
+
440
+ COPY_SERVICE(&server->svc, &server->alt_svc);
441
+ COPY_SERVICE(&server->svc_ssl, &server->alt_svc_ssl);
442
+
443
+ #undef COPY_SERVICE
444
+ }
445
+ }
446
+ }
447
+
417
448
  return 1;
418
449
 
419
450
  GT_ERR:
@@ -427,7 +458,7 @@ build_server_3x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js)
427
458
  * @return nonzero on success, 0 on failure.
428
459
  */
429
460
  static int
430
- build_server_2x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js)
461
+ build_server_2x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js, char **network)
431
462
  {
432
463
  char *tmp = NULL, *colon;
433
464
  int itmp;
@@ -508,12 +539,49 @@ build_server_2x(lcbvb_CONFIG *cfg, lcbvb_SERVER *server, cJSON *js)
508
539
  return 0;
509
540
  }
510
541
 
542
+ static void
543
+ guess_network(cJSON *jnodes, int nsrv, const char *source, char **network)
544
+ {
545
+ int ii;
546
+ for (ii = 0; ii < nsrv; ii++) {
547
+ cJSON *jsrv = cJSON_GetArrayItem(jnodes, ii);
548
+ {
549
+ cJSON *jhostname = cJSON_GetObjectItem(jsrv, "hostname");
550
+ if (jhostname && jhostname->type == cJSON_String) {
551
+ if (strcmp(jhostname->valuestring, source) == 0) {
552
+ *network = strdup("default");
553
+ return;
554
+ }
555
+ }
556
+ }
557
+ {
558
+ cJSON *jaltaddr = cJSON_GetObjectItem(jsrv, "alternateAddresses");
559
+ if (jaltaddr && jaltaddr->type == cJSON_Object) {
560
+ cJSON *cur;
561
+ for (cur = jaltaddr->child; cur != NULL; cur = cur->next) {
562
+ if (cur->type == cJSON_Object) {
563
+ cJSON *jhostname = cJSON_GetObjectItem(cur, "hostname");
564
+ if (jhostname && jhostname->type == cJSON_String) {
565
+ if (strcmp(jhostname->valuestring, source) == 0) {
566
+ *network = strdup(cur->string);
567
+ return;
568
+ }
569
+ }
570
+ }
571
+ }
572
+ }
573
+ }
574
+ }
575
+ *network = strdup("default");
576
+ }
577
+
511
578
  int
512
- lcbvb_load_json(lcbvb_CONFIG *cfg, const char *data)
579
+ lcbvb_load_json_ex(lcbvb_CONFIG *cfg, const char *data, const char *source, char **network)
513
580
  {
514
- cJSON *cj = NULL, *jnodes = NULL;
581
+ cJSON *cj = NULL, *jnodes_ext = NULL, *jnodes = NULL;
515
582
  char *tmp = NULL;
516
- unsigned ii;
583
+ unsigned ii, jnodes_size = 0;
584
+ int jnodes_defined = 0;
517
585
 
518
586
  if ((cj = cJSON_Parse(data)) == NULL) {
519
587
  SET_ERRSTR(cfg, "Couldn't parse JSON");
@@ -531,9 +599,16 @@ lcbvb_load_json(lcbvb_CONFIG *cfg, const char *data)
531
599
  goto GT_ERROR;
532
600
  }
533
601
 
534
- if (get_jarray(cj, "nodesExt", &jnodes)) {
602
+ get_jarray(cj, "nodes", &jnodes);
603
+ if (jnodes) {
604
+ jnodes_defined = 1;
605
+ jnodes_size = cJSON_GetArraySize(jnodes);
606
+ }
607
+ if (get_jarray(cj, "nodesExt", &jnodes_ext)) {
535
608
  cfg->is3x = 1;
536
- } else if (!get_jarray(cj, "nodes", &jnodes)) {
609
+ cfg->nsrv = cJSON_GetArraySize(jnodes_ext);
610
+ jnodes = jnodes_ext;
611
+ } else if (jnodes == NULL) {
537
612
  SET_ERRSTR(cfg, "expected 'nodesExt' or 'nodes' array");
538
613
  goto GT_ERROR;
539
614
  }
@@ -585,6 +660,10 @@ lcbvb_load_json(lcbvb_CONFIG *cfg, const char *data)
585
660
  /** Get the number of nodes. This traverses the list. Yuck */
586
661
  cfg->nsrv = cJSON_GetArraySize(jnodes);
587
662
 
663
+ if (network && *network == NULL) {
664
+ guess_network(jnodes, cfg->nsrv, source, network);
665
+ }
666
+
588
667
  /** Allocate a temporary one on the heap */
589
668
  cfg->servers = calloc(cfg->nsrv, sizeof(*cfg->servers));
590
669
  for (ii = 0; ii < cfg->nsrv; ii++) {
@@ -592,9 +671,15 @@ lcbvb_load_json(lcbvb_CONFIG *cfg, const char *data)
592
671
  cJSON *jsrv = cJSON_GetArrayItem(jnodes, ii);
593
672
 
594
673
  if (cfg->is3x) {
595
- rv = build_server_3x(cfg, cfg->servers + ii, jsrv);
674
+ rv = build_server_3x(cfg, cfg->servers + ii, jsrv, network);
675
+ if (jnodes_defined && rv && ii >= jnodes_size) {
676
+ cfg->servers[ii].svc.data = 0;
677
+ cfg->servers[ii].svc_ssl.data = 0;
678
+ cfg->servers[ii].alt_svc.data = 0;
679
+ cfg->servers[ii].alt_svc_ssl.data = 0;
680
+ }
596
681
  } else {
597
- rv = build_server_2x(cfg, cfg->servers + ii, jsrv);
682
+ rv = build_server_2x(cfg, cfg->servers + ii, jsrv, network);
598
683
  }
599
684
 
600
685
  if (!rv) {
@@ -638,6 +723,12 @@ lcbvb_load_json(lcbvb_CONFIG *cfg, const char *data)
638
723
  return -1;
639
724
  }
640
725
 
726
+ int
727
+ lcbvb_load_json(lcbvb_CONFIG *cfg, const char *data)
728
+ {
729
+ return lcbvb_load_json_ex(cfg, data, NULL, NULL);
730
+ }
731
+
641
732
  static void
642
733
  replace_hoststr(char **orig, const char *replacement)
643
734
  {
@@ -754,6 +845,9 @@ lcbvb_destroy(lcbvb_CONFIG *conf)
754
845
  free_service_strs(&srv->svc);
755
846
  free_service_strs(&srv->svc_ssl);
756
847
  free(srv->authority);
848
+ free(srv->alt_hostname);
849
+ free_service_strs(&srv->alt_svc);
850
+ free_service_strs(&srv->alt_svc_ssl);
757
851
  }
758
852
  free(conf->servers);
759
853
  free(conf->continuum);
@@ -783,6 +877,9 @@ svcs_to_json(lcbvb_SERVICES *svc, cJSON *jsvc, int is_ssl)
783
877
  EXTRACT_SERVICE("n1ql", n1ql);
784
878
  EXTRACT_SERVICE("indexScan", ixquery);
785
879
  EXTRACT_SERVICE("indexAdmin", ixadmin);
880
+ EXTRACT_SERVICE("fts", fts);
881
+ EXTRACT_SERVICE("cbas", cbas);
882
+
786
883
  #undef EXTRACT_SERVICE
787
884
  }
788
885
 
@@ -1139,12 +1236,41 @@ lcbvb_get_changetype(lcbvb_CONFIGDIFF *diff)
1139
1236
  ** String/Port Getters **
1140
1237
  ******************************************************************************
1141
1238
  ******************************************************************************/
1239
+
1240
+ static const lcbvb_SERVICES *
1241
+ get_svc(const lcbvb_SERVER *srv, lcbvb_SVCMODE mode)
1242
+ {
1243
+ if (srv->alt_hostname) {
1244
+ if (mode == LCBVB_SVCMODE_PLAIN) {
1245
+ return &srv->alt_svc;
1246
+ } else {
1247
+ return &srv->alt_svc_ssl;
1248
+ }
1249
+ } else {
1250
+ if (mode == LCBVB_SVCMODE_PLAIN) {
1251
+ return &srv->svc;
1252
+ } else {
1253
+ return &srv->svc_ssl;
1254
+ }
1255
+ }
1256
+ }
1257
+
1258
+ static const char *
1259
+ get_hostname(const lcbvb_SERVER *srv)
1260
+ {
1261
+ if (srv->alt_hostname) {
1262
+ return srv->alt_hostname;
1263
+ } else {
1264
+ return srv->hostname;
1265
+ }
1266
+ }
1267
+
1142
1268
  LIBCOUCHBASE_API
1143
1269
  unsigned
1144
1270
  lcbvb_get_port(lcbvb_CONFIG *cfg,
1145
1271
  unsigned ix, lcbvb_SVCTYPE type, lcbvb_SVCMODE mode)
1146
1272
  {
1147
- lcbvb_SERVICES *svc;
1273
+ const lcbvb_SERVICES *svc;
1148
1274
  lcbvb_SERVER *srv;
1149
1275
  if (type >= LCBVB_SVCTYPE__MAX || mode >= LCBVB_SVCMODE__MAX) {
1150
1276
  return 0;
@@ -1154,12 +1280,7 @@ lcbvb_get_port(lcbvb_CONFIG *cfg,
1154
1280
  }
1155
1281
 
1156
1282
  srv = cfg->servers + ix;
1157
-
1158
- if (mode == LCBVB_SVCMODE_PLAIN) {
1159
- svc = &srv->svc;
1160
- } else {
1161
- svc = &srv->svc_ssl;
1162
- }
1283
+ svc = get_svc(srv, mode);
1163
1284
 
1164
1285
  if (type == LCBVB_SVCTYPE_DATA) {
1165
1286
  return svc->data;
@@ -1197,17 +1318,13 @@ lcbvb_get_hostport(lcbvb_CONFIG *cfg,
1197
1318
  }
1198
1319
 
1199
1320
  srv = cfg->servers + ix;
1200
- if (mode == LCBVB_SVCMODE_PLAIN) {
1201
- svc = &srv->svc;
1202
- } else {
1203
- svc = &srv->svc_ssl;
1204
- }
1321
+ svc = (lcbvb_SERVICES *)get_svc(srv, mode);
1205
1322
 
1206
1323
  strp = &svc->hoststrs[type];
1207
1324
  if (*strp == NULL) {
1208
1325
  size_t strn = strlen(srv->hostname) + 20;
1209
1326
  *strp = calloc(strn, sizeof(char));
1210
- copy_address(*strp, strn, srv->hostname, port);
1327
+ copy_address(*strp, strn, get_hostname(srv), port);
1211
1328
  }
1212
1329
  return *strp;
1213
1330
  }
@@ -1217,7 +1334,7 @@ const char *
1217
1334
  lcbvb_get_hostname(const lcbvb_CONFIG *cfg, unsigned ix)
1218
1335
  {
1219
1336
  if (cfg->nsrv > ix) {
1220
- return cfg->servers[ix].hostname;
1337
+ return get_hostname(cfg->servers + ix);
1221
1338
  } else {
1222
1339
  return NULL;
1223
1340
  }
@@ -1237,8 +1354,7 @@ lcbvb_get_randhost_ex(const lcbvb_CONFIG *cfg,
1237
1354
  */
1238
1355
  for (nn = 0; nn < cfg->nsrv; nn++) {
1239
1356
  const lcbvb_SERVER *server = cfg->servers + nn;
1240
- const lcbvb_SERVICES *svcs = mode == LCBVB_SVCMODE_PLAIN ?
1241
- &server->svc : &server->svc_ssl;
1357
+ const lcbvb_SERVICES *svcs = get_svc(server, mode);
1242
1358
  int has_svc = 0;
1243
1359
 
1244
1360
  // Check if this node is in the exclude list
@@ -1299,11 +1415,10 @@ lcbvb_get_resturl(lcbvb_CONFIG *cfg, unsigned ix,
1299
1415
  srv = cfg->servers + ix;
1300
1416
  if (mode == LCBVB_SVCMODE_PLAIN) {
1301
1417
  prefix = "http";
1302
- svcs = &srv->svc;
1303
1418
  } else {
1304
1419
  prefix = "https";
1305
- svcs = &srv->svc_ssl;
1306
1420
  }
1421
+ svcs = (lcbvb_SERVICES *)get_svc(srv, mode);
1307
1422
 
1308
1423
  if (svc == LCBVB_SVCTYPE_VIEWS) {
1309
1424
  path = srv->viewpath;
@@ -1326,11 +1441,12 @@ lcbvb_get_resturl(lcbvb_CONFIG *cfg, unsigned ix,
1326
1441
  return NULL;
1327
1442
  } else if (!*strp) {
1328
1443
  char buf[4096];
1329
- if (strchr(srv->hostname, ':')) {
1444
+ const char *hostname = get_hostname(srv);
1445
+ if (strchr(hostname, ':')) {
1330
1446
  // IPv6 and should be bracketed
1331
- snprintf(buf, sizeof(buf), "%s://[%s]:%d%s", prefix, srv->hostname, port, path);
1447
+ snprintf(buf, sizeof(buf), "%s://[%s]:%d%s", prefix, hostname, port, path);
1332
1448
  } else {
1333
- snprintf(buf, sizeof(buf), "%s://%s:%d%s", prefix, srv->hostname, port, path);
1449
+ snprintf(buf, sizeof(buf), "%s://%s:%d%s", prefix, hostname, port, path);
1334
1450
  }
1335
1451
  *strp = strdup(buf);
1336
1452
  }