libcouchbase 0.3.3 → 1.0.0
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 +4 -4
- data/ext/libcouchbase/CMakeLists.txt +6 -8
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +21 -5
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
- data/ext/libcouchbase/example/users/README +48 -0
- data/ext/libcouchbase/example/users/users.c +147 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
- data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
- data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
- data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
- data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
- data/ext/libcouchbase/src/README.md +0 -2
- data/ext/libcouchbase/src/auth-priv.h +23 -4
- data/ext/libcouchbase/src/auth.cc +51 -43
- data/ext/libcouchbase/src/bootstrap.cc +244 -0
- data/ext/libcouchbase/src/bootstrap.h +58 -38
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +56 -22
- data/ext/libcouchbase/src/connspec.cc +47 -6
- data/ext/libcouchbase/src/connspec.h +27 -0
- data/ext/libcouchbase/src/dns-srv.cc +147 -0
- data/ext/libcouchbase/src/dump.cc +3 -3
- data/ext/libcouchbase/src/errmap.cc +173 -0
- data/ext/libcouchbase/src/errmap.h +198 -0
- data/ext/libcouchbase/src/getconfig.cc +7 -33
- data/ext/libcouchbase/src/handler.cc +118 -7
- data/ext/libcouchbase/src/hostlist.cc +0 -36
- data/ext/libcouchbase/src/hostlist.h +44 -62
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +27 -35
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +28 -36
- data/ext/libcouchbase/src/instance.cc +131 -34
- data/ext/libcouchbase/src/internal.h +58 -26
- data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
- data/ext/libcouchbase/src/jsparse/parser.h +84 -98
- data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
- data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
- data/ext/libcouchbase/src/lcbio/connect.h +16 -7
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
- data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
- data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
- data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
- data/ext/libcouchbase/src/lcbio/manager.h +133 -96
- data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.c +11 -2
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
- data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
- data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
- data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
- data/ext/libcouchbase/src/mctx-helper.h +51 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
- data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
- data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
- data/ext/libcouchbase/src/newconfig.cc +6 -6
- data/ext/libcouchbase/src/nodeinfo.cc +2 -2
- data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
- data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
- data/ext/libcouchbase/src/operations/durability.cc +6 -26
- data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
- data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
- data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
- data/ext/libcouchbase/src/operations/stats.cc +3 -8
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +30 -2
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/rdb/rope.c +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
- data/ext/libcouchbase/src/retryq.cc +52 -14
- data/ext/libcouchbase/src/retryq.h +3 -3
- data/ext/libcouchbase/src/settings.c +5 -0
- data/ext/libcouchbase/src/settings.h +11 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
- data/ext/libcouchbase/src/trace.h +4 -4
- data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
- data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
- data/ext/libcouchbase/src/views/docreq.h +24 -30
- data/ext/libcouchbase/src/views/viewreq.cc +318 -0
- data/ext/libcouchbase/src/views/viewreq.h +43 -13
- data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
- data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
- data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
- data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
- data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
- data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
- data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
- data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
- data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
- data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
- data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
- data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
- data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
- data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
- data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
- data/ext/libcouchbase/tools/cbc.cc +143 -10
- data/ext/libcouchbase/tools/docgen/loc.h +1 -1
- data/lib/libcouchbase/connection.rb +4 -3
- data/lib/libcouchbase/version.rb +1 -1
- metadata +37 -28
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
- data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/lcbio/manager.c +0 -584
- data/ext/libcouchbase/src/packetutils.c +0 -37
- data/ext/libcouchbase/src/simplestring.c +0 -211
- data/ext/libcouchbase/src/simplestring.h +0 -228
- data/ext/libcouchbase/src/ssobuf.h +0 -82
- data/ext/libcouchbase/src/views/viewreq.c +0 -358
- data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
|
@@ -34,7 +34,7 @@ lcb_dump(lcb_t instance, FILE *fp, lcb_U32 flags)
|
|
|
34
34
|
fprintf(fp, "Settings=%p\n", (void*)instance->settings);
|
|
35
35
|
|
|
36
36
|
if (instance->cur_configinfo) {
|
|
37
|
-
|
|
37
|
+
lcb::clconfig::ConfigInfo *cfg = instance->cur_configinfo;
|
|
38
38
|
fprintf(fp, "Current VBC=%p\n", (void*)cfg->vbc);
|
|
39
39
|
fprintf(fp, "Config RevID=%d\n", cfg->vbc->revid);
|
|
40
40
|
if (flags & LCB_DUMP_VBCONFIG) {
|
|
@@ -67,7 +67,7 @@ lcb_dump(lcb_t instance, FILE *fp, lcb_U32 flags)
|
|
|
67
67
|
fprintf(fp, "** == BEGIN SOCKET INFO\n");
|
|
68
68
|
lcbio_ctx_dump(server->connctx, fp);
|
|
69
69
|
fprintf(fp, "** == END SOCKET INFO\n");
|
|
70
|
-
} else if (server->connreq
|
|
70
|
+
} else if (server->connreq) {
|
|
71
71
|
fprintf(fp, "** == STILL CONNECTING\n");
|
|
72
72
|
} else {
|
|
73
73
|
fprintf(fp, "** == NOT CONNECTED\n");
|
|
@@ -90,6 +90,6 @@ lcb_dump(lcb_t instance, FILE *fp, lcb_U32 flags)
|
|
|
90
90
|
fprintf(fp, "=== END PIPELINE DUMP ===\n");
|
|
91
91
|
|
|
92
92
|
fprintf(fp, "=== BEGIN CONFMON DUMP ===\n");
|
|
93
|
-
|
|
93
|
+
instance->confmon->dump(fp);
|
|
94
94
|
fprintf(fp, "=== END CONFMON DUMP ===\n");
|
|
95
95
|
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#include "internal.h"
|
|
2
|
+
#include "errmap.h"
|
|
3
|
+
#include "contrib/lcb-jsoncpp/lcb-jsoncpp.h"
|
|
4
|
+
|
|
5
|
+
using namespace lcb::errmap;
|
|
6
|
+
|
|
7
|
+
ErrorMap::ErrorMap() : revision(0), version(0) {
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
static ErrorAttribute getAttribute(const std::string& s) {
|
|
11
|
+
#define X(c, s_) if (s == s_) { return c; }
|
|
12
|
+
LCB_XERRMAP_ATTRIBUTES(X)
|
|
13
|
+
#undef X
|
|
14
|
+
return INVALID_ATTRIBUTE;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
RetrySpec *Error::getRetrySpec() const {
|
|
18
|
+
return retry.specptr;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
RetrySpec* RetrySpec::parse(const Json::Value& retryJson, std::string& emsg) {
|
|
22
|
+
|
|
23
|
+
RetrySpec *spec = new RetrySpec();
|
|
24
|
+
spec->refcount = 1;
|
|
25
|
+
|
|
26
|
+
#define FAIL_RETRY(s) \
|
|
27
|
+
emsg = s; \
|
|
28
|
+
delete spec; \
|
|
29
|
+
return NULL;
|
|
30
|
+
|
|
31
|
+
if (!retryJson.isObject()) {
|
|
32
|
+
FAIL_RETRY("Missing retry specification");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const Json::Value& strategyJson = retryJson["strategy"];
|
|
36
|
+
if (!strategyJson.isString()) {
|
|
37
|
+
FAIL_RETRY("Missing `strategy`");
|
|
38
|
+
}
|
|
39
|
+
const char* strategy = strategyJson.asCString();
|
|
40
|
+
if (!strcasecmp(strategy, "constant")) {
|
|
41
|
+
spec->strategy = CONSTANT;
|
|
42
|
+
} else if (!strcasecmp(strategy, "linear")) {
|
|
43
|
+
spec->strategy = LINEAR;
|
|
44
|
+
} else if (!strcasecmp(strategy, "exponential")) {
|
|
45
|
+
spec->strategy = EXPONENTIAL;
|
|
46
|
+
} else {
|
|
47
|
+
FAIL_RETRY("Unknown strategy");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#define GET_TIMEFLD(srcname, dstname, required) { \
|
|
51
|
+
Json::Value dstname##Json = retryJson[srcname]; \
|
|
52
|
+
if (dstname##Json.isNumeric()) { \
|
|
53
|
+
spec->dstname = (dstname##Json).asUInt() * 1000; \
|
|
54
|
+
} else if (required) { \
|
|
55
|
+
FAIL_RETRY("Missing " # srcname); \
|
|
56
|
+
} else { \
|
|
57
|
+
spec->dstname = 0; \
|
|
58
|
+
} \
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
GET_TIMEFLD("interval", interval, true);
|
|
62
|
+
GET_TIMEFLD("after", after, true);
|
|
63
|
+
GET_TIMEFLD("ceil", ceil, false);
|
|
64
|
+
GET_TIMEFLD("max-duration", max_duration, false);
|
|
65
|
+
|
|
66
|
+
return spec;
|
|
67
|
+
|
|
68
|
+
#undef FAIL_RETRY
|
|
69
|
+
#undef GET_TIMEFLD
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const uint32_t ErrorMap::MAX_VERSION = 1;
|
|
74
|
+
|
|
75
|
+
ErrorMap::ParseStatus
|
|
76
|
+
ErrorMap::parse(const char *s, size_t n, std::string& errmsg) {
|
|
77
|
+
Json::Value root_nonconst;
|
|
78
|
+
Json::Reader reader;
|
|
79
|
+
if (!reader.parse(s, s + n, root_nonconst)) {
|
|
80
|
+
errmsg = "Invalid JSON";
|
|
81
|
+
return PARSE_ERROR;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const Json::Value& root = root_nonconst;
|
|
85
|
+
const Json::Value& verJson = root["version"];
|
|
86
|
+
if (!verJson.isNumeric()) {
|
|
87
|
+
errmsg = "'version' is not a number";
|
|
88
|
+
return PARSE_ERROR;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (verJson.asUInt() > MAX_VERSION) {
|
|
92
|
+
errmsg = "'version' is unreasonably high";
|
|
93
|
+
return UNKNOWN_VERSION;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const Json::Value& revJson = root["revision"];
|
|
97
|
+
if (!revJson.isNumeric()) {
|
|
98
|
+
errmsg = "'revision' is not a number";
|
|
99
|
+
return PARSE_ERROR;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (revJson.asUInt() <= revision) {
|
|
103
|
+
return NOT_UPDATED;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const Json::Value& errsJson = root["errors"];
|
|
107
|
+
if (!errsJson.isObject()) {
|
|
108
|
+
errmsg = "'errors' is not an object";
|
|
109
|
+
return PARSE_ERROR;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
Json::Value::const_iterator ii = errsJson.begin();
|
|
113
|
+
for (; ii != errsJson.end(); ++ii) {
|
|
114
|
+
// Key is the version in hex
|
|
115
|
+
unsigned ec = 0;
|
|
116
|
+
if (sscanf(ii.key().asCString(), "%x", &ec) != 1) {
|
|
117
|
+
errmsg = "key " + ii.key().asString() + " is not a hex number";
|
|
118
|
+
return PARSE_ERROR;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const Json::Value& errorJson = *ii;
|
|
122
|
+
|
|
123
|
+
// Descend into the error attributes
|
|
124
|
+
Error error;
|
|
125
|
+
error.code = static_cast<uint16_t>(ec);
|
|
126
|
+
|
|
127
|
+
error.shortname = errorJson["name"].asString();
|
|
128
|
+
error.description = errorJson["desc"].asString();
|
|
129
|
+
|
|
130
|
+
const Json::Value& attrs = errorJson["attrs"];
|
|
131
|
+
if (!attrs.isArray()) {
|
|
132
|
+
errmsg = "'attrs' is not an array";
|
|
133
|
+
return PARSE_ERROR;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
Json::Value::const_iterator jj = attrs.begin();
|
|
137
|
+
for (; jj != attrs.end(); ++jj) {
|
|
138
|
+
ErrorAttribute attr = getAttribute(jj->asString());
|
|
139
|
+
if (attr == INVALID_ATTRIBUTE) {
|
|
140
|
+
errmsg = "unknown attribute received";
|
|
141
|
+
return UNKNOWN_VERSION;
|
|
142
|
+
}
|
|
143
|
+
error.attributes.insert(attr);
|
|
144
|
+
}
|
|
145
|
+
if (error.hasAttribute(AUTO_RETRY)) {
|
|
146
|
+
const Json::Value& retryJson = errorJson["retry"];
|
|
147
|
+
if (!retryJson.isObject()) {
|
|
148
|
+
errmsg = "Need `retry` specification for `auto-retry` attribute";
|
|
149
|
+
return PARSE_ERROR;
|
|
150
|
+
}
|
|
151
|
+
if ((error.retry.specptr = RetrySpec::parse(retryJson, errmsg)) == NULL) {
|
|
152
|
+
return PARSE_ERROR;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
errors.insert(MapType::value_type(ec, error));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return UPDATED;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const Error& ErrorMap::getError(uint16_t code) const {
|
|
162
|
+
static const Error invalid;
|
|
163
|
+
MapType::const_iterator it = errors.find(code);
|
|
164
|
+
|
|
165
|
+
if (it != errors.end()) {
|
|
166
|
+
return it->second;
|
|
167
|
+
} else {
|
|
168
|
+
return invalid;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
ErrorMap *lcb_errmap_new() { return new ErrorMap(); }
|
|
173
|
+
void lcb_errmap_free(ErrorMap* m) { delete m; }
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#ifndef LCB_ERRMAP_H
|
|
2
|
+
#define LCB_ERRMAP_H
|
|
3
|
+
|
|
4
|
+
#ifdef __cplusplus
|
|
5
|
+
#include <map>
|
|
6
|
+
#include <set>
|
|
7
|
+
#include <string>
|
|
8
|
+
#include <cmath>
|
|
9
|
+
|
|
10
|
+
namespace Json { class Value; }
|
|
11
|
+
|
|
12
|
+
namespace lcb {
|
|
13
|
+
namespace errmap {
|
|
14
|
+
|
|
15
|
+
enum ErrorAttribute {
|
|
16
|
+
#define LCB_XERRMAP_ATTRIBUTES(X) \
|
|
17
|
+
X(TEMPORARY, "temp") \
|
|
18
|
+
X(SUBDOC, "subdoc") \
|
|
19
|
+
X(RETRY_NOW, "retry-now") \
|
|
20
|
+
X(RETRY_LATER, "retry-later") \
|
|
21
|
+
X(INVALID_INPUT, "invalid-input") \
|
|
22
|
+
X(NOT_ENABLED, "support") \
|
|
23
|
+
X(AUTH, "auth") \
|
|
24
|
+
X(CONN_STATE_INVALIDATED, "conn-state-invalidated") \
|
|
25
|
+
X(CONSTRAINT_FAILURE, "item-only") \
|
|
26
|
+
X(RETRY_EXP_BACKOFF, "retry-exp-backoff") \
|
|
27
|
+
X(RETRY_LINEAR_BACKOFF, "retry-linear-backoff") \
|
|
28
|
+
X(INTERNAL, "internal") \
|
|
29
|
+
X(DCP, "dcp") \
|
|
30
|
+
X(FETCH_CONFIG, "fetch-config") \
|
|
31
|
+
X(SPECIAL_HANDLING, "special-handling") \
|
|
32
|
+
X(AUTO_RETRY, "auto-retry")
|
|
33
|
+
|
|
34
|
+
#define X(c, s) c,
|
|
35
|
+
LCB_XERRMAP_ATTRIBUTES(X)
|
|
36
|
+
#undef X
|
|
37
|
+
|
|
38
|
+
INVALID_ATTRIBUTE
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
class RetrySpec {
|
|
42
|
+
public:
|
|
43
|
+
enum Strategy { CONSTANT, LINEAR, EXPONENTIAL };
|
|
44
|
+
// Grace time
|
|
45
|
+
uint32_t after;
|
|
46
|
+
|
|
47
|
+
// Maximum duration for retry.
|
|
48
|
+
uint32_t max_duration;
|
|
49
|
+
|
|
50
|
+
uint32_t get_next_interval(size_t num_attempts) const {
|
|
51
|
+
uint32_t cur_interval = 0; // 50ms is a safe bet.
|
|
52
|
+
if (strategy == CONSTANT) {
|
|
53
|
+
return interval;
|
|
54
|
+
} else if (strategy == LINEAR) {
|
|
55
|
+
cur_interval = num_attempts * interval;
|
|
56
|
+
} else if (strategy == EXPONENTIAL) {
|
|
57
|
+
// Convert to ms for pow(), convert result back to us.
|
|
58
|
+
cur_interval = std::pow((double)(interval / 1000), (int)num_attempts) * 1000;
|
|
59
|
+
}
|
|
60
|
+
if (ceil != 0) {
|
|
61
|
+
// Note, I *could* use std::min here, but this file gets
|
|
62
|
+
// included by other files, and Windows is giving a hard time
|
|
63
|
+
// because it defines std::min as a macro. NOMINMAX is a possible
|
|
64
|
+
// definition, but I'd rather not touch all including files
|
|
65
|
+
// to contain that macro, and I don't want to add additional
|
|
66
|
+
// preprocessor defs at this time.
|
|
67
|
+
cur_interval = ceil > cur_interval ? cur_interval : ceil;
|
|
68
|
+
}
|
|
69
|
+
return cur_interval;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
void ref() {
|
|
73
|
+
refcount++;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
void unref() {
|
|
77
|
+
if (!--refcount) {
|
|
78
|
+
delete this;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static inline RetrySpec* parse(const Json::Value& specJson,
|
|
83
|
+
std::string& errmsg);
|
|
84
|
+
|
|
85
|
+
private:
|
|
86
|
+
Strategy strategy;
|
|
87
|
+
|
|
88
|
+
// Base interval
|
|
89
|
+
uint32_t interval;
|
|
90
|
+
|
|
91
|
+
// Max interval
|
|
92
|
+
uint32_t ceil;
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
size_t refcount;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
class SpecWrapper {
|
|
99
|
+
private:
|
|
100
|
+
friend class RetrySpec;
|
|
101
|
+
friend struct Error;
|
|
102
|
+
friend class ErrorMap;
|
|
103
|
+
|
|
104
|
+
RetrySpec *specptr;
|
|
105
|
+
SpecWrapper() : specptr(NULL) {}
|
|
106
|
+
SpecWrapper(const SpecWrapper& other) {
|
|
107
|
+
specptr = other.specptr;
|
|
108
|
+
if (specptr != NULL) {
|
|
109
|
+
specptr->ref();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
~SpecWrapper() {
|
|
113
|
+
if (specptr) {
|
|
114
|
+
specptr->unref();
|
|
115
|
+
}
|
|
116
|
+
specptr = NULL;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
struct Error {
|
|
121
|
+
uint16_t code;
|
|
122
|
+
std::string shortname;
|
|
123
|
+
std::string description;
|
|
124
|
+
std::set<ErrorAttribute> attributes;
|
|
125
|
+
SpecWrapper retry;
|
|
126
|
+
|
|
127
|
+
Error() : code(-1) {
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
bool isValid() const {
|
|
131
|
+
return code != uint16_t(-1);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
bool hasAttribute(ErrorAttribute attr) const {
|
|
135
|
+
return attributes.find(attr) != attributes.end();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
RetrySpec *getRetrySpec() const;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
class ErrorMap {
|
|
142
|
+
public:
|
|
143
|
+
enum ParseStatus {
|
|
144
|
+
/** Couldn't parse JSON!*/
|
|
145
|
+
PARSE_ERROR,
|
|
146
|
+
|
|
147
|
+
/** Version is too high */
|
|
148
|
+
UNKNOWN_VERSION,
|
|
149
|
+
|
|
150
|
+
/** Current version/revision is higher or equal */
|
|
151
|
+
NOT_UPDATED,
|
|
152
|
+
|
|
153
|
+
/** Updated */
|
|
154
|
+
UPDATED
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
ErrorMap();
|
|
158
|
+
ParseStatus parse(const char *s, size_t n, std::string& errmsg);
|
|
159
|
+
ParseStatus parse(const char *s, size_t n) {
|
|
160
|
+
std::string tmp;
|
|
161
|
+
return parse(s, n, tmp);
|
|
162
|
+
}
|
|
163
|
+
size_t getVersion() const { return version; }
|
|
164
|
+
size_t getRevision() const { return revision; };
|
|
165
|
+
const Error& getError(uint16_t code) const;
|
|
166
|
+
bool isLoaded() const {
|
|
167
|
+
return !errors.empty();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private:
|
|
171
|
+
static const uint32_t MAX_VERSION;
|
|
172
|
+
ErrorMap(const ErrorMap&);
|
|
173
|
+
typedef std::map<uint16_t, Error> MapType;
|
|
174
|
+
MapType errors;
|
|
175
|
+
uint32_t revision;
|
|
176
|
+
uint32_t version;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
} // namespace
|
|
180
|
+
} // namespace
|
|
181
|
+
|
|
182
|
+
typedef lcb::errmap::ErrorMap* lcb_pERRMAP;
|
|
183
|
+
#else
|
|
184
|
+
typedef struct lcb_ERRMAP* lcb_pERRMAP;
|
|
185
|
+
#endif /* __cplusplus */
|
|
186
|
+
|
|
187
|
+
#ifdef __cplusplus
|
|
188
|
+
extern "C" {
|
|
189
|
+
#endif
|
|
190
|
+
|
|
191
|
+
lcb_pERRMAP lcb_errmap_new(void);
|
|
192
|
+
void lcb_errmap_free(lcb_pERRMAP);
|
|
193
|
+
|
|
194
|
+
#ifdef __cplusplus
|
|
195
|
+
}
|
|
196
|
+
#endif
|
|
197
|
+
|
|
198
|
+
#endif /* LCB_ERRMAP_H */
|
|
@@ -18,31 +18,6 @@
|
|
|
18
18
|
#include "internal.h"
|
|
19
19
|
#include "packetutils.h"
|
|
20
20
|
#include <bucketconfig/clconfig.h>
|
|
21
|
-
LCB_INTERNAL_API
|
|
22
|
-
lcb::Server *
|
|
23
|
-
lcb_find_server_by_host(lcb_t instance, const lcb_host_t *host)
|
|
24
|
-
{
|
|
25
|
-
mc_CMDQUEUE *cq = &instance->cmdq;
|
|
26
|
-
unsigned ii;
|
|
27
|
-
for (ii = 0; ii < cq->npipelines; ii++) {
|
|
28
|
-
lcb::Server *server = static_cast<lcb::Server*>(cq->pipelines[ii]);
|
|
29
|
-
if (lcb_host_equals(&server->get_host(), host)) {
|
|
30
|
-
return server;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return NULL;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
LCB_INTERNAL_API
|
|
37
|
-
lcb::Server *
|
|
38
|
-
lcb_find_server_by_index(lcb_t instance, int ix)
|
|
39
|
-
{
|
|
40
|
-
mc_CMDQUEUE *cq = &instance->cmdq;
|
|
41
|
-
if (ix < 0 || ix >= static_cast<int>(cq->npipelines)) {
|
|
42
|
-
return NULL;
|
|
43
|
-
}
|
|
44
|
-
return static_cast<lcb::Server*>(cq->pipelines[ix]);
|
|
45
|
-
}
|
|
46
21
|
|
|
47
22
|
static void
|
|
48
23
|
ext_callback_proxy(mc_PIPELINE *pl, mc_PACKET *req, lcb_error_t rc,
|
|
@@ -53,19 +28,18 @@ ext_callback_proxy(mc_PIPELINE *pl, mc_PACKET *req, lcb_error_t rc,
|
|
|
53
28
|
const lcb::MemcachedResponse *res =
|
|
54
29
|
reinterpret_cast<const lcb::MemcachedResponse*>(resdata);
|
|
55
30
|
|
|
56
|
-
|
|
57
|
-
|
|
31
|
+
lcb::clconfig::cccp_update(
|
|
32
|
+
rd->cookie, rc, res->body<const char*>(), res->bodylen(),
|
|
33
|
+
&server->get_host());
|
|
58
34
|
free(rd);
|
|
59
35
|
}
|
|
60
36
|
|
|
61
37
|
static mc_REQDATAPROCS procs = { ext_callback_proxy };
|
|
62
38
|
|
|
63
|
-
LCB_INTERNAL_API
|
|
64
39
|
lcb_error_t
|
|
65
|
-
|
|
40
|
+
lcb_st::request_config(const void *cookie_, lcb::Server *server)
|
|
66
41
|
{
|
|
67
42
|
lcb_error_t err;
|
|
68
|
-
mc_CMDQUEUE *cq = &instance->cmdq;
|
|
69
43
|
mc_PACKET *packet;
|
|
70
44
|
mc_REQDATAEX *rd;
|
|
71
45
|
|
|
@@ -82,7 +56,7 @@ lcb_getconfig(lcb_t instance, const void *cookie, lcb::Server *server)
|
|
|
82
56
|
|
|
83
57
|
rd = reinterpret_cast<mc_REQDATAEX*>(calloc(1, sizeof(*rd)));
|
|
84
58
|
rd->procs = &procs;
|
|
85
|
-
rd->cookie =
|
|
59
|
+
rd->cookie = cookie_;
|
|
86
60
|
rd->start = gethrtime();
|
|
87
61
|
packet->u_rdata.exdata = rd;
|
|
88
62
|
packet->flags |= MCREQ_F_REQEXT;
|
|
@@ -92,8 +66,8 @@ lcb_getconfig(lcb_t instance, const void *cookie, lcb::Server *server)
|
|
|
92
66
|
hdr.opaque(packet->opaque);
|
|
93
67
|
memcpy(SPAN_BUFFER(&packet->kh_span), hdr.data(), hdr.size());
|
|
94
68
|
|
|
95
|
-
mcreq_sched_enter(
|
|
69
|
+
mcreq_sched_enter(&cmdq);
|
|
96
70
|
mcreq_sched_add(server, packet);
|
|
97
|
-
mcreq_sched_leave(
|
|
71
|
+
mcreq_sched_leave(&cmdq, 1);
|
|
98
72
|
return LCB_SUCCESS;
|
|
99
73
|
}
|