libcouchbase 1.3.0 → 1.3.2
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.
- checksums.yaml +5 -5
- data/.travis.yml +2 -2
- data/ext/libcouchbase/CMakeLists.txt +51 -25
- data/ext/libcouchbase/CONTRIBUTING.md +46 -65
- data/ext/libcouchbase/RELEASE_NOTES.markdown +163 -0
- data/ext/libcouchbase/cmake/Modules/DownloadLcbDep.cmake +9 -11
- data/ext/libcouchbase/cmake/Modules/FindProfiler.cmake +16 -0
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +6 -6
- data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
- data/ext/libcouchbase/cmake/configure +16 -0
- data/ext/libcouchbase/example/CMakeLists.txt +17 -2
- data/ext/libcouchbase/example/analytics/.gitignore +1 -0
- data/ext/libcouchbase/example/analytics/analytics.c +158 -0
- data/ext/libcouchbase/example/analytics/build-queries.rb +34 -0
- data/ext/libcouchbase/example/analytics/cJSON.c +1 -0
- data/ext/libcouchbase/example/analytics/cJSON.h +1 -0
- data/ext/libcouchbase/example/analytics/queries.h +113 -0
- data/ext/libcouchbase/example/analytics/queries/00-show-dataverse.json +5 -0
- data/ext/libcouchbase/example/analytics/queries/01-setup-dataset-breweries.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/02-setup-dataset-beers.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/03-initiate-shadow.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/04-list-datasets.json +7 -0
- data/ext/libcouchbase/example/analytics/queries/05-count-breweries.json +5 -0
- data/ext/libcouchbase/example/analytics/queries/06-first-brewery.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/07-key-based-lookup.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/08-exact-match-lookup.json +7 -0
- data/ext/libcouchbase/example/analytics/queries/09-exact-match-lookup-different-shape.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/10-other-query-filters.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/11-equijoin.json +9 -0
- data/ext/libcouchbase/example/analytics/queries/12-equijoin-select-star.json +10 -0
- data/ext/libcouchbase/example/analytics/queries/13-ansi-join.json +8 -0
- data/ext/libcouchbase/example/analytics/queries/14-join-select-values.json +8 -0
- data/ext/libcouchbase/example/analytics/queries/15-nested-outer-join.json +7 -0
- data/ext/libcouchbase/example/analytics/queries/16-theta-join.json +8 -0
- data/ext/libcouchbase/example/analytics/queries/17-existential-quantification.json +9 -0
- data/ext/libcouchbase/example/analytics/queries/18-universal-quantification.json +7 -0
- data/ext/libcouchbase/example/analytics/queries/19-simple-aggregation.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/20-simple-aggregation-unwrapped-value.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/21-simple-aggregation-explicit.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/22-grouping-and-aggregation.json +6 -0
- data/ext/libcouchbase/example/analytics/queries/23-grouping-and-aggregation-with-hint.json +7 -0
- data/ext/libcouchbase/example/analytics/queries/24-grouping-and-limits.json +7 -0
- data/ext/libcouchbase/example/analytics/queries/25-named-parameters.json +7 -0
- data/ext/libcouchbase/example/analytics/queries/26-positional-parameters.json +7 -0
- data/ext/libcouchbase/example/crypto/common_provider.c +2 -0
- data/ext/libcouchbase/example/crypto/common_provider.h +2 -0
- data/ext/libcouchbase/example/crypto/openssl_symmetric_decrypt.c +5 -0
- data/ext/libcouchbase/example/crypto/openssl_symmetric_encrypt.c +0 -1
- data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.c +16 -26
- data/ext/libcouchbase/example/db/db.c +10 -6
- data/ext/libcouchbase/example/fts/.gitignore +1 -0
- data/ext/libcouchbase/example/fts/build-queries.rb +33 -0
- data/ext/libcouchbase/example/fts/fts.c +142 -0
- data/ext/libcouchbase/example/fts/queries.h +61 -0
- data/ext/libcouchbase/example/fts/queries/00-simple-text-query.json +12 -0
- data/ext/libcouchbase/example/fts/queries/01-simple-text-query-on-non-default-index.json +9 -0
- data/ext/libcouchbase/example/fts/queries/02-simple-text-query-on-stored-field.json +13 -0
- data/ext/libcouchbase/example/fts/queries/03-match-query-with-facet.json +19 -0
- data/ext/libcouchbase/example/fts/queries/04-docid-query.json +11 -0
- data/ext/libcouchbase/example/fts/queries/05-unanalyzed-term-query-with-fuzziness-level-of-0.json +13 -0
- data/ext/libcouchbase/example/fts/queries/06-unanalyzed-term-query-with-fuzziness-level-of-2.json +14 -0
- data/ext/libcouchbase/example/fts/queries/07-match-phrase-query.json +13 -0
- data/ext/libcouchbase/example/fts/queries/08-phrase-query.json +16 -0
- data/ext/libcouchbase/example/fts/queries/09-query-string-query.json +9 -0
- data/ext/libcouchbase/example/fts/queries/10-conjunction-query.json +21 -0
- data/ext/libcouchbase/example/fts/queries/11-wild-card-query.json +13 -0
- data/ext/libcouchbase/example/fts/queries/12-numeric-range-query.json +11 -0
- data/ext/libcouchbase/example/fts/queries/13-regexp-query.json +13 -0
- data/ext/libcouchbase/example/minimal/.gitignore +1 -0
- data/ext/libcouchbase/example/minimal/query.c +185 -0
- data/ext/libcouchbase/example/subdoc/subdoc-xattrs.c +2 -2
- data/ext/libcouchbase/example/tracing/cJSON.c +1 -1
- data/ext/libcouchbase/example/tracing/cJSON.h +1 -1
- data/ext/libcouchbase/include/libcouchbase/cbft.h +38 -4
- data/ext/libcouchbase/include/libcouchbase/cntl-private.h +8 -97
- data/ext/libcouchbase/include/libcouchbase/cntl.h +288 -8
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +47 -10
- data/ext/libcouchbase/include/libcouchbase/crypto.h +214 -48
- data/ext/libcouchbase/include/libcouchbase/deprecated.h +12 -0
- data/ext/libcouchbase/include/libcouchbase/error.h +33 -2
- data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +1 -1
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +87 -13
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +3 -7
- data/ext/libcouchbase/include/libcouchbase/tracing.h +174 -56
- data/ext/libcouchbase/include/libcouchbase/vbucket.h +21 -1
- data/ext/libcouchbase/include/libcouchbase/views.h +49 -4
- data/ext/libcouchbase/packaging/deb/control +2 -3
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/CMakeLists.txt +7 -5
- data/ext/libcouchbase/plugins/io/libevent/CMakeLists.txt +7 -5
- data/ext/libcouchbase/plugins/io/libuv/CMakeLists.txt +14 -12
- data/ext/libcouchbase/plugins/io/libuv/libuv_compat.h +3 -0
- data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +14 -6
- data/ext/libcouchbase/plugins/io/select/CMakeLists.txt +7 -5
- data/ext/libcouchbase/src/bootstrap.cc +6 -1
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +2 -7
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +1 -1
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +4 -11
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +29 -36
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +4 -2
- data/ext/libcouchbase/src/cntl.cc +181 -151
- data/ext/libcouchbase/src/config_static.h +1 -1
- data/ext/libcouchbase/src/connspec.cc +5 -1
- data/ext/libcouchbase/src/connspec.h +3 -1
- data/ext/libcouchbase/src/crypto.cc +93 -80
- data/ext/libcouchbase/src/dns-srv.cc +1 -1
- data/ext/libcouchbase/src/handler.cc +0 -1
- data/ext/libcouchbase/src/http/http-priv.h +1 -0
- data/ext/libcouchbase/src/http/http.cc +1 -2
- data/ext/libcouchbase/src/instance.cc +21 -2
- data/ext/libcouchbase/src/internal.h +1 -0
- data/ext/libcouchbase/src/lcbio/ctx.c +24 -3
- data/ext/libcouchbase/src/lcbio/ioutils.cc +1 -1
- data/ext/libcouchbase/src/lcbio/rw-inl.h +22 -1
- data/ext/libcouchbase/src/lcbio/ssl.h +2 -0
- data/ext/libcouchbase/src/mc/compress.cc +18 -11
- data/ext/libcouchbase/src/mc/mcreq.c +2 -0
- data/ext/libcouchbase/src/mc/mcreq.h +1 -1
- data/ext/libcouchbase/src/mcserver/mcserver.cc +163 -6
- data/ext/libcouchbase/src/mcserver/negotiate.cc +17 -7
- data/ext/libcouchbase/src/n1ql/n1ql.cc +12 -3
- data/ext/libcouchbase/src/newconfig.cc +4 -3
- data/ext/libcouchbase/src/nodeinfo.cc +1 -7
- data/ext/libcouchbase/src/operations/observe.cc +1 -0
- data/ext/libcouchbase/src/operations/ping.cc +5 -3
- data/ext/libcouchbase/src/retryq.cc +22 -0
- data/ext/libcouchbase/src/retryq.h +2 -1
- data/ext/libcouchbase/src/rnd.cc +5 -12
- data/ext/libcouchbase/src/settings.c +4 -7
- data/ext/libcouchbase/src/settings.h +6 -2
- data/ext/libcouchbase/src/strcodecs/base64.c +59 -0
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +2 -0
- data/ext/libcouchbase/src/trace.h +2 -2
- data/ext/libcouchbase/src/tracing/span.cc +177 -45
- data/ext/libcouchbase/src/tracing/threshold_logging_tracer.cc +70 -28
- data/ext/libcouchbase/src/tracing/tracing-internal.h +33 -48
- data/ext/libcouchbase/src/vbucket/vbucket.c +146 -30
- data/ext/libcouchbase/src/wait.cc +1 -1
- data/ext/libcouchbase/tests/CMakeLists.txt +13 -4
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_misc.cc +2 -2
- data/ext/libcouchbase/tests/iotests/t_views.cc +1 -1
- data/ext/libcouchbase/tests/iotests/testutil.cc +3 -2
- data/ext/libcouchbase/tests/vbucket/confdata/map_node_present_nodesext_missing_nodes.json +94 -0
- data/ext/libcouchbase/tests/vbucket/t_config.cc +15 -0
- data/ext/libcouchbase/tools/CMakeLists.txt +11 -6
- data/ext/libcouchbase/tools/cbc-handlers.h +9 -0
- data/ext/libcouchbase/tools/cbc-proxy.cc +1 -1
- data/ext/libcouchbase/tools/cbc.cc +33 -5
- data/ext/libcouchbase/tools/common/options.cc +1 -1
- data/ext/libcouchbase/tools/extract-packets.rb +110 -0
- data/lib/libcouchbase/connection.rb +13 -5
- data/lib/libcouchbase/ext/tasks.rb +1 -1
- data/lib/libcouchbase/version.rb +1 -1
- 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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
86
|
+
QueueEntry ThresholdLoggingTracer::convert(lcbtrace_SPAN *span)
|
|
81
87
|
{
|
|
82
|
-
|
|
88
|
+
QueueEntry orphan;
|
|
83
89
|
orphan.duration = span->duration();
|
|
84
90
|
Json::Value entry;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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(
|
|
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)
|
|
140
|
+
entries["count"] = (Json::UInt)queue.size();
|
|
114
141
|
Json::Value top;
|
|
115
|
-
|
|
142
|
+
while (!queue.empty())
|
|
143
|
+
{
|
|
116
144
|
Json::Value entry;
|
|
117
|
-
if (Json::Reader().parse(
|
|
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
|
-
|
|
127
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
75
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
118
|
-
|
|
98
|
+
FixedSpanQueue m_orphans;
|
|
99
|
+
FixedSpanQueue m_threshold;
|
|
119
100
|
|
|
120
|
-
void flush_queue(
|
|
121
|
-
|
|
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
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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,
|
|
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,
|
|
1449
|
+
snprintf(buf, sizeof(buf), "%s://%s:%d%s", prefix, hostname, port, path);
|
|
1334
1450
|
}
|
|
1335
1451
|
*strp = strdup(buf);
|
|
1336
1452
|
}
|