libcouchbase 1.3.0 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|