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
|
@@ -395,7 +395,7 @@ dump_ropebuf(const rdb_ROPEBUF *buf, FILE *fp)
|
|
|
395
395
|
rdb_ROPESEG *seg = LCB_LIST_ITEM(llcur, rdb_ROPESEG, llnode);
|
|
396
396
|
fprintf(fp, "%sSEG=%p\n", indent, (void*)seg);
|
|
397
397
|
fprintf(fp, "%sALLOCATOR=%p [%u]\n", indent, (void*)seg->allocator, seg->allocid);
|
|
398
|
-
fprintf(fp, "%sBUFROOT=%p\n", indent, seg->root);
|
|
398
|
+
fprintf(fp, "%sBUFROOT=%p\n", indent, (void *)seg->root);
|
|
399
399
|
fprintf(fp, "%sALLOC SIZE: %u\n", indent, seg->nalloc);
|
|
400
400
|
fprintf(fp, "%sDATA SIZE: %u\n", indent, seg->nused);
|
|
401
401
|
fprintf(fp, "%sDATS OFFSET: %u\n", indent, seg->start);
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
int
|
|
21
21
|
lcb_should_retry(const lcb_settings *settings, const mc_PACKET *pkt, lcb_error_t err)
|
|
22
22
|
{
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
unsigned policy;
|
|
24
|
+
unsigned mode;
|
|
25
25
|
protocol_binary_request_header hdr;
|
|
26
26
|
|
|
27
27
|
mcreq_read_hdr(pkt, &hdr);
|
|
@@ -70,7 +70,6 @@ lcb_should_retry(const lcb_settings *settings, const mc_PACKET *pkt, lcb_error_t
|
|
|
70
70
|
|
|
71
71
|
/* get is a safe operation which may be retried */
|
|
72
72
|
case PROTOCOL_BINARY_CMD_GET:
|
|
73
|
-
case PROTOCOL_BINARY_CMD_GETKQ:
|
|
74
73
|
case PROTOCOL_BINARY_CMD_SUBDOC_GET:
|
|
75
74
|
case PROTOCOL_BINARY_CMD_SUBDOC_EXISTS:
|
|
76
75
|
case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_LOOKUP:
|
|
@@ -37,7 +37,13 @@ struct lcb::RetryOp : mc_EPKTDATUM, SchedNode, TmoNode {
|
|
|
37
37
|
hrtime_t trytime; /**< Next retry time */
|
|
38
38
|
mc_PACKET *pkt;
|
|
39
39
|
lcb_error_t origerr;
|
|
40
|
-
|
|
40
|
+
errmap::RetrySpec *spec;
|
|
41
|
+
RetryOp(errmap::RetrySpec *spec);
|
|
42
|
+
~RetryOp() {
|
|
43
|
+
if (spec != NULL) {
|
|
44
|
+
spec->unref();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
41
47
|
};
|
|
42
48
|
|
|
43
49
|
static RetryOp *from_schednode(lcb_list_t *ll) {
|
|
@@ -79,10 +85,24 @@ RetryQueue::update_trytime(RetryOp *op, hrtime_t now)
|
|
|
79
85
|
if (!now) {
|
|
80
86
|
now = gethrtime();
|
|
81
87
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
88
|
+
|
|
89
|
+
if (op->spec) {
|
|
90
|
+
uint32_t us_trytime = op->spec->get_next_interval(op->pkt->retries - 1);
|
|
91
|
+
if (op->pkt->retries == 1) {
|
|
92
|
+
us_trytime += op->spec->after;
|
|
93
|
+
}
|
|
94
|
+
if (!us_trytime) {
|
|
95
|
+
goto GT_DEFAULT;
|
|
96
|
+
}
|
|
97
|
+
op->trytime = now + (LCB_US2NS(us_trytime));
|
|
98
|
+
} else {
|
|
99
|
+
GT_DEFAULT:
|
|
100
|
+
op->trytime = now + (hrtime_t) (
|
|
101
|
+
(float)get_retry_interval() *
|
|
102
|
+
(float)op->pkt->retries *
|
|
103
|
+
(float)settings->retry_backoff);
|
|
104
|
+
|
|
105
|
+
}
|
|
86
106
|
}
|
|
87
107
|
|
|
88
108
|
/** Comparison routine for sorting by timeout */
|
|
@@ -139,7 +159,7 @@ RetryQueue::fail(RetryOp *op, lcb_error_t err)
|
|
|
139
159
|
PROTOCOL_BINARY_RESPONSE_EINVAL);
|
|
140
160
|
|
|
141
161
|
assign_error(op, err);
|
|
142
|
-
lcb_log(LOGARGS(this, WARN), "Failing command (seq=%u) from retry queue
|
|
162
|
+
lcb_log(LOGARGS(this, WARN), "Failing command (seq=%u) from retry queue: %s", op->pkt->opaque, lcb_strerror_short(op->origerr));
|
|
143
163
|
|
|
144
164
|
mcreq_dispatch_response(&tmpsrv, op->pkt, &resp, op->origerr);
|
|
145
165
|
op->pkt->flags |= MCREQ_F_FLUSHED|MCREQ_F_INVOKED;
|
|
@@ -231,8 +251,8 @@ RetryQueue::flush(bool throttle)
|
|
|
231
251
|
* configuration (i.e. the attempt has not been throttled) then
|
|
232
252
|
* keep the command in there until it has a chance to be scheduled.
|
|
233
253
|
*/
|
|
234
|
-
|
|
235
|
-
if (
|
|
254
|
+
get_instance()->bootstrap(lcb::BS_REFRESH_THROTTLE);
|
|
255
|
+
if (get_instance()->confmon->is_refreshing() ||
|
|
236
256
|
settings->retry[LCB_RETRY_ON_MISSINGNODE]) {
|
|
237
257
|
|
|
238
258
|
lcb_list_delete(static_cast<SchedNode*>(op));
|
|
@@ -276,22 +296,40 @@ static void op_dtorfn(mc_EPKTDATUM *d) {
|
|
|
276
296
|
delete static_cast<RetryOp*>(d);
|
|
277
297
|
}
|
|
278
298
|
|
|
279
|
-
RetryOp::RetryOp()
|
|
280
|
-
|
|
299
|
+
RetryOp::RetryOp(errmap::RetrySpec *spec_)
|
|
300
|
+
: mc_EPKTDATUM(), start(0), trytime(0), pkt(NULL), origerr(LCB_SUCCESS),
|
|
301
|
+
spec(spec_) {
|
|
281
302
|
mc_EPKTDATUM::dtorfn = op_dtorfn;
|
|
282
303
|
mc_EPKTDATUM::key = RETRY_PKT_KEY;
|
|
304
|
+
|
|
305
|
+
if (spec != NULL) {
|
|
306
|
+
spec->ref();
|
|
307
|
+
}
|
|
283
308
|
}
|
|
284
309
|
|
|
285
310
|
void
|
|
286
|
-
RetryQueue::add(mc_EXPACKET *pkt, const lcb_error_t err,
|
|
311
|
+
RetryQueue::add(mc_EXPACKET *pkt, const lcb_error_t err,
|
|
312
|
+
errmap::RetrySpec *spec, int options)
|
|
287
313
|
{
|
|
288
314
|
RetryOp *op;
|
|
289
315
|
mc_EPKTDATUM *d = mcreq_epkt_find(pkt, RETRY_PKT_KEY);
|
|
290
316
|
if (d) {
|
|
291
317
|
op = static_cast<RetryOp *>(d);
|
|
292
318
|
} else {
|
|
293
|
-
op = new RetryOp();
|
|
319
|
+
op = new RetryOp(NULL);
|
|
294
320
|
op->start = MCREQ_PKT_RDATA(&pkt->base)->start;
|
|
321
|
+
if (spec) {
|
|
322
|
+
op->spec = spec;
|
|
323
|
+
spec->ref();
|
|
324
|
+
|
|
325
|
+
if (spec->max_duration && spec->max_duration < settings->operation_timeout) {
|
|
326
|
+
// Offset the start by the difference between the duration and
|
|
327
|
+
// the timeout. We really use this number only for calculating
|
|
328
|
+
// the timeout, so it shouldn't hurt to fake it.
|
|
329
|
+
uint32_t diff = settings->operation_timeout - op->spec->max_duration;
|
|
330
|
+
op->start -= LCB_US2NS(diff);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
295
333
|
mcreq_epkt_insert(pkt, op);
|
|
296
334
|
}
|
|
297
335
|
|
|
@@ -320,7 +358,7 @@ RetryQueue::nmvadd(mc_EXPACKET *detchpkt)
|
|
|
320
358
|
if (settings->nmv_retry_imm) {
|
|
321
359
|
flags = RETRY_SCHED_IMM;
|
|
322
360
|
}
|
|
323
|
-
add(detchpkt, LCB_NOT_MY_VBUCKET, flags);
|
|
361
|
+
add(detchpkt, LCB_NOT_MY_VBUCKET, NULL, flags);
|
|
324
362
|
}
|
|
325
363
|
|
|
326
364
|
static void
|
|
@@ -332,7 +370,7 @@ fallback_handler(mc_CMDQUEUE *cq, mc_PACKET *pkt)
|
|
|
332
370
|
|
|
333
371
|
void RetryQueue::add_fallback(mc_PACKET *pkt) {
|
|
334
372
|
mc_PACKET *copy = mcreq_renew_packet(pkt);
|
|
335
|
-
add((mc_EXPACKET*)copy, LCB_NO_MATCHING_SERVER, RETRY_SCHED_IMM);
|
|
373
|
+
add((mc_EXPACKET*)copy, LCB_NO_MATCHING_SERVER, NULL, RETRY_SCHED_IMM);
|
|
336
374
|
}
|
|
337
375
|
|
|
338
376
|
void
|
|
@@ -72,8 +72,8 @@ public:
|
|
|
72
72
|
* it may _not_ be used for memcached buckets (which is typically OK, as we only
|
|
73
73
|
* map things here as a response for a not-my-vbucket).
|
|
74
74
|
*/
|
|
75
|
-
void add(mc_EXPACKET *detchpkt, lcb_error_t err) {
|
|
76
|
-
add(detchpkt, err, 0);
|
|
75
|
+
void add(mc_EXPACKET *detchpkt, lcb_error_t err, errmap::RetrySpec *spec) {
|
|
76
|
+
add(detchpkt, err, spec, 0);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/**
|
|
@@ -151,7 +151,7 @@ private:
|
|
|
151
151
|
enum AddOptions {
|
|
152
152
|
RETRY_SCHED_IMM = 0x01
|
|
153
153
|
};
|
|
154
|
-
void add(mc_EXPACKET *pkt, lcb_error_t, int options);
|
|
154
|
+
void add(mc_EXPACKET *pkt, lcb_error_t, errmap::RetrySpec*, int options);
|
|
155
155
|
|
|
156
156
|
/** List of operations in retry ordering. Sorted by 'crtime' */
|
|
157
157
|
lcb_list_t schedops;
|
|
@@ -57,6 +57,9 @@ void lcb_default_settings(lcb_settings *settings)
|
|
|
57
57
|
settings->tcp_nodelay = LCB_DEFAULT_TCP_NODELAY;
|
|
58
58
|
settings->retry_nmv_interval = LCB_DEFAULT_RETRY_NMV_INTERVAL;
|
|
59
59
|
settings->vb_noguess = LCB_DEFAULT_VB_NOGUESS;
|
|
60
|
+
settings->select_bucket = LCB_DEFAULT_SELECT_BUCKET;
|
|
61
|
+
settings->tcp_keepalive = LCB_DEFAULT_TCP_KEEPALIVE;
|
|
62
|
+
settings->send_hello = 1;
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
LCB_INTERNAL_API
|
|
@@ -67,6 +70,7 @@ lcb_settings_new(void)
|
|
|
67
70
|
lcb_default_settings(settings);
|
|
68
71
|
settings->refcount = 1;
|
|
69
72
|
settings->auth = lcbauth_new();
|
|
73
|
+
settings->errmap = lcb_errmap_new();
|
|
70
74
|
return settings;
|
|
71
75
|
}
|
|
72
76
|
|
|
@@ -83,6 +87,7 @@ lcb_settings_unref(lcb_settings *settings)
|
|
|
83
87
|
free(settings->client_string);
|
|
84
88
|
|
|
85
89
|
lcbauth_unref(settings->auth);
|
|
90
|
+
lcb_errmap_free(settings->errmap);
|
|
86
91
|
|
|
87
92
|
if (settings->ssl_ctx) {
|
|
88
93
|
lcbio_ssl_free(settings->ssl_ctx);
|
|
@@ -84,9 +84,12 @@
|
|
|
84
84
|
#define LCB_DEFAULT_RETRY_NMV_INTERVAL LCB_MS2US(100)
|
|
85
85
|
#define LCB_DEFAULT_VB_NOGUESS 1
|
|
86
86
|
#define LCB_DEFAULT_TCP_NODELAY 1
|
|
87
|
+
#define LCB_DEFAULT_SELECT_BUCKET 1
|
|
88
|
+
#define LCB_DEFAULT_TCP_KEEPALIVE 1
|
|
87
89
|
|
|
88
90
|
#include "config.h"
|
|
89
91
|
#include <libcouchbase/couchbase.h>
|
|
92
|
+
#include "errmap.h"
|
|
90
93
|
|
|
91
94
|
#ifdef __cplusplus
|
|
92
95
|
extern "C" {
|
|
@@ -128,6 +131,9 @@ typedef struct lcb_settings_st {
|
|
|
128
131
|
* updates. */
|
|
129
132
|
lcb_U32 bc_http_stream_time;
|
|
130
133
|
|
|
134
|
+
/** Time to wait in between background config polls. 0 disables this */
|
|
135
|
+
lcb_U32 config_poll_interval;
|
|
136
|
+
|
|
131
137
|
unsigned bc_http_urltype : 4;
|
|
132
138
|
|
|
133
139
|
/** Don't guess next vbucket server. Mainly for testing */
|
|
@@ -148,6 +154,10 @@ typedef struct lcb_settings_st {
|
|
|
148
154
|
unsigned ipv6 : 2;
|
|
149
155
|
unsigned tcp_nodelay : 1;
|
|
150
156
|
unsigned readj_ts_wait : 1;
|
|
157
|
+
unsigned use_errmap : 1;
|
|
158
|
+
unsigned select_bucket : 1;
|
|
159
|
+
unsigned tcp_keepalive : 1;
|
|
160
|
+
unsigned send_hello : 1;
|
|
151
161
|
|
|
152
162
|
short max_redir;
|
|
153
163
|
unsigned refcount;
|
|
@@ -165,6 +175,7 @@ typedef struct lcb_settings_st {
|
|
|
165
175
|
void (*dtorcb)(const void *);
|
|
166
176
|
void *dtorarg;
|
|
167
177
|
char *client_string;
|
|
178
|
+
lcb_pERRMAP errmap;
|
|
168
179
|
lcb_U32 retry_nmv_interval;
|
|
169
180
|
} lcb_settings;
|
|
170
181
|
|
|
@@ -156,7 +156,9 @@ iotssl_log_errors(lcbio_XSSL *xs)
|
|
|
156
156
|
if (ERR_GET_LIB(curerr) == ERR_LIB_SSL) {
|
|
157
157
|
switch (ERR_GET_REASON(curerr)) {
|
|
158
158
|
case SSL_R_CERTIFICATE_VERIFY_FAILED:
|
|
159
|
+
#ifdef SSL_R_MISSING_VERIFY_MESSAGE
|
|
159
160
|
case SSL_R_MISSING_VERIFY_MESSAGE:
|
|
161
|
+
#endif
|
|
160
162
|
xs->errcode = LCB_SSL_CANTVERIFY;
|
|
161
163
|
break;
|
|
162
164
|
|
|
@@ -105,7 +105,7 @@ bool urldecode(Ti first, Ti last, To out, size_t& nout) {
|
|
|
105
105
|
|
|
106
106
|
inline bool
|
|
107
107
|
urldecode(const char *input, char *output) {
|
|
108
|
-
const char *endp =
|
|
108
|
+
const char *endp = input + strlen(input);
|
|
109
109
|
size_t nout = 0;
|
|
110
110
|
if (urldecode(input, endp, output, nout)) {
|
|
111
111
|
output[nout] = '\0';
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
|
|
41
41
|
#define TRACE_BEGIN_COMMON(TGT, req, cmd, ...) \
|
|
42
42
|
TGT((req)->request.opaque, ntohs((req)->request.vbucket), (req)->request.opcode, \
|
|
43
|
-
(cmd)->key.contig.bytes, (cmd)->key.contig.nbytes, ## __VA_ARGS__)
|
|
43
|
+
(const char *)((cmd)->key.contig.bytes), (cmd)->key.contig.nbytes, ## __VA_ARGS__)
|
|
44
44
|
|
|
45
45
|
#define TRACE_BEGIN_SIMPLE(TGT, req, cmd) \
|
|
46
46
|
TGT((req)->request.opaque, ntohs((req)->request.vbucket), (req)->request.opcode, \
|
|
47
|
-
(cmd)->key.contig.bytes, (cmd)->key.contig.nbytes)
|
|
47
|
+
(const char *)(cmd)->key.contig.bytes, (cmd)->key.contig.nbytes)
|
|
48
48
|
|
|
49
49
|
#define TRACE_END_COMMON(TGT, mcresp, resp, ...) \
|
|
50
50
|
TGT(mcresp->opaque(), 0, mcresp->opcode(), (resp)->rc, (const char *)(resp)->key, (resp)->nkey, \
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
|
|
59
59
|
#define TRACE_GET_END(mcresp, resp) \
|
|
60
60
|
TRACE(TRACE_END_COMMON(LIBCOUCHBASE_GET_END, mcresp, resp, \
|
|
61
|
-
(char*)(resp)->value, (resp)->nvalue, (resp)->itmflags, (resp)->cas, \
|
|
61
|
+
(const char*)(resp)->value, (resp)->nvalue, (resp)->itmflags, (resp)->cas, \
|
|
62
62
|
mcresp->datatype()))
|
|
63
63
|
|
|
64
64
|
#define TRACE_UNLOCK_BEGIN(req, cmd) TRACE(TRACE_BEGIN_SIMPLE(LIBCOUCHBASE_UNLOCK_BEGIN, req, cmd))
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
|
|
67
67
|
#define TRACE_STORE_BEGIN(req, cmd) \
|
|
68
68
|
TRACE(TRACE_BEGIN_COMMON(LIBCOUCHBASE_STORE_BEGIN, req, cmd, \
|
|
69
|
-
( (cmd)->value.vtype == LCB_KV_IOV ? NULL : (cmd)->value.u_buf.contig.bytes ),\
|
|
69
|
+
(const char *)( (cmd)->value.vtype == LCB_KV_IOV ? NULL : (cmd)->value.u_buf.contig.bytes ),\
|
|
70
70
|
( (cmd)->value.vtype == LCB_KV_IOV ? 0 : (cmd)->value.u_buf.contig.nbytes ),\
|
|
71
71
|
(cmd)->flags, (cmd)->cas, (req)->request.datatype, (cmd)->exptime))
|
|
72
72
|
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
#include "json-inl.h"
|
|
27
27
|
#include "hash.h"
|
|
28
28
|
#include "crc32.h"
|
|
29
|
-
#include "simplestring.h"
|
|
30
29
|
|
|
31
30
|
#define STRINGIFY_(X) #X
|
|
32
31
|
#define STRINGIFY(X) STRINGIFY_(X)
|
|
@@ -1367,15 +1366,12 @@ lcbvb_genconfig_ex(lcbvb_CONFIG *vb,
|
|
|
1367
1366
|
}
|
|
1368
1367
|
}
|
|
1369
1368
|
|
|
1370
|
-
if (
|
|
1371
|
-
vb->
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
if (!vb->vbuckets) {
|
|
1377
|
-
vb->errstr = "Couldn't allocate vbucket array";
|
|
1378
|
-
return -1;
|
|
1369
|
+
if (vb->nvb) {
|
|
1370
|
+
vb->vbuckets = malloc(vb->nvb * sizeof(*vb->vbuckets));
|
|
1371
|
+
if (!vb->vbuckets) {
|
|
1372
|
+
vb->errstr = "Couldn't allocate vbucket array";
|
|
1373
|
+
return -1;
|
|
1374
|
+
}
|
|
1379
1375
|
}
|
|
1380
1376
|
|
|
1381
1377
|
for (ii = 0; ii < vb->nvb; ii++) {
|
|
@@ -2,56 +2,53 @@
|
|
|
2
2
|
#include "internal.h"
|
|
3
3
|
#include "sllist-inl.h"
|
|
4
4
|
|
|
5
|
+
using namespace lcb::docreq;
|
|
6
|
+
|
|
5
7
|
static void docreq_handler(void *arg);
|
|
6
|
-
static void invoke_pending(
|
|
8
|
+
static void invoke_pending(Queue*);
|
|
7
9
|
static void doc_callback(lcb_t,int, const lcb_RESPBASE *);
|
|
8
10
|
|
|
9
11
|
#define MAX_PENDING_DOCREQ 10
|
|
10
12
|
#define MIN_SCHED_SIZE 5
|
|
11
13
|
#define DOCQ_DELAY_US 200000
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
Queue::Queue(lcb_t instance_)
|
|
16
|
+
: instance(instance_),
|
|
17
|
+
parent(NULL),
|
|
18
|
+
timer(lcbio_timer_new(instance->iotable, this, docreq_handler)),
|
|
19
|
+
cb_ready(NULL), cb_throttle(NULL),
|
|
20
|
+
n_awaiting_schedule(0),
|
|
21
|
+
n_awaiting_response(0),
|
|
22
|
+
max_pending_response(MAX_PENDING_DOCREQ),
|
|
23
|
+
min_batch_size(MIN_SCHED_SIZE),
|
|
24
|
+
cancelled(false),
|
|
25
|
+
refcount(1)
|
|
26
|
+
{
|
|
27
|
+
|
|
28
|
+
memset(&pending_gets, 0, sizeof pending_gets);
|
|
29
|
+
memset(&cb_queue, 0, sizeof cb_queue);
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
lcbdocq_cancel(q);
|
|
32
|
-
lcbio_timer_destroy(q->timer);
|
|
33
|
-
free(q);
|
|
32
|
+
Queue::~Queue() {
|
|
33
|
+
cancel();
|
|
34
|
+
lcbio_timer_destroy(timer);
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
void
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
void Queue::unref() {
|
|
38
|
+
if (!--refcount) {
|
|
39
|
+
delete this;
|
|
40
|
+
}
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
void
|
|
43
|
-
|
|
44
|
-
{
|
|
45
|
-
if (!q->cancelled) {
|
|
46
|
-
q->cancelled = 1;
|
|
47
|
-
}
|
|
43
|
+
void Queue::cancel() {
|
|
44
|
+
cancelled = true;
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
/* Calling this function ensures that the request will be scheduled in due
|
|
51
48
|
* time. This may be done at the next event loop iteration, or after a delay
|
|
52
49
|
* depending on how many items are actually found within the queue. */
|
|
53
50
|
static void
|
|
54
|
-
docq_poke(
|
|
51
|
+
docq_poke(Queue *q)
|
|
55
52
|
{
|
|
56
53
|
if (q->n_awaiting_response < q->max_pending_response) {
|
|
57
54
|
if (q->n_awaiting_schedule > q->min_batch_size) {
|
|
@@ -65,27 +62,26 @@ docq_poke(lcb_DOCQUEUE *q)
|
|
|
65
62
|
}
|
|
66
63
|
}
|
|
67
64
|
|
|
68
|
-
void
|
|
69
|
-
lcbdocq_add(lcb_DOCQUEUE *q, lcb_DOCQREQ *req)
|
|
65
|
+
void Queue::add(DocRequest *req)
|
|
70
66
|
{
|
|
71
|
-
sllist_append(&
|
|
72
|
-
|
|
73
|
-
req->parent =
|
|
67
|
+
sllist_append(&pending_gets, &req->slnode);
|
|
68
|
+
n_awaiting_schedule++;
|
|
69
|
+
req->parent = this;
|
|
74
70
|
req->ready = 0;
|
|
75
|
-
|
|
76
|
-
docq_poke(
|
|
71
|
+
ref();
|
|
72
|
+
docq_poke(this);
|
|
77
73
|
}
|
|
78
74
|
|
|
79
75
|
static void
|
|
80
76
|
docreq_handler(void *arg)
|
|
81
77
|
{
|
|
82
|
-
|
|
78
|
+
Queue *q = reinterpret_cast<Queue*>(arg);
|
|
83
79
|
sllist_iterator iter;
|
|
84
80
|
lcb_t instance = q->instance;
|
|
85
81
|
|
|
86
82
|
lcb_sched_enter(instance);
|
|
87
83
|
SLLIST_ITERFOR(&q->pending_gets, &iter) {
|
|
88
|
-
|
|
84
|
+
DocRequest *cont = SLLIST_ITEM(iter.cur, DocRequest, slnode);
|
|
89
85
|
|
|
90
86
|
if (q->n_awaiting_response > q->max_pending_response) {
|
|
91
87
|
lcbio_timer_rearm(q->timer, DOCQ_DELAY_US);
|
|
@@ -136,13 +132,12 @@ docreq_handler(void *arg)
|
|
|
136
132
|
/* Invokes the callback on all requests which are ready, until a request which
|
|
137
133
|
* is not yet ready is reached. */
|
|
138
134
|
static void
|
|
139
|
-
invoke_pending(
|
|
135
|
+
invoke_pending(Queue *q)
|
|
140
136
|
{
|
|
141
137
|
sllist_iterator iter = { NULL };
|
|
142
|
-
|
|
143
|
-
DOCQ_REF(q);
|
|
138
|
+
q->ref();
|
|
144
139
|
SLLIST_ITERFOR(&q->cb_queue, &iter) {
|
|
145
|
-
|
|
140
|
+
DocRequest *dreq = SLLIST_ITEM(iter.cur, DocRequest, slnode);
|
|
146
141
|
void *bufh = NULL;
|
|
147
142
|
|
|
148
143
|
if (dreq->ready == 0) {
|
|
@@ -157,21 +152,21 @@ invoke_pending(lcb_DOCQUEUE *q)
|
|
|
157
152
|
|
|
158
153
|
q->cb_ready(q, dreq);
|
|
159
154
|
if (bufh) {
|
|
160
|
-
lcb_backbuf_unref(bufh);
|
|
155
|
+
lcb_backbuf_unref(reinterpret_cast<lcb_BACKBUF>(bufh));
|
|
161
156
|
}
|
|
162
|
-
|
|
157
|
+
q->unref();
|
|
163
158
|
}
|
|
164
|
-
|
|
159
|
+
q->unref();
|
|
165
160
|
}
|
|
166
161
|
|
|
167
162
|
static void
|
|
168
|
-
doc_callback(lcb_t
|
|
163
|
+
doc_callback(lcb_t, int, const lcb_RESPBASE *rb)
|
|
169
164
|
{
|
|
170
165
|
const lcb_RESPGET *rg = (const lcb_RESPGET *)rb;
|
|
171
|
-
|
|
172
|
-
|
|
166
|
+
DocRequest *dreq = reinterpret_cast<DocRequest*>(rb->cookie);
|
|
167
|
+
Queue *q = dreq->parent;
|
|
173
168
|
|
|
174
|
-
|
|
169
|
+
q->ref();
|
|
175
170
|
|
|
176
171
|
q->n_awaiting_response--;
|
|
177
172
|
dreq->docresp = *rg;
|
|
@@ -182,13 +177,12 @@ doc_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
|
|
|
182
177
|
/* Reference the response data, since we might not be invoking this right
|
|
183
178
|
* away */
|
|
184
179
|
if (rg->rc == LCB_SUCCESS) {
|
|
185
|
-
lcb_backbuf_ref(dreq->docresp.bufh);
|
|
180
|
+
lcb_backbuf_ref(reinterpret_cast<lcb_BACKBUF>(dreq->docresp.bufh));
|
|
186
181
|
}
|
|
187
182
|
|
|
188
183
|
/* Ensure the invoke_pending doesn't destroy us */
|
|
189
184
|
invoke_pending(q);
|
|
190
185
|
docq_poke(q);
|
|
191
186
|
|
|
192
|
-
|
|
193
|
-
(void)instance; (void)cbtype;
|
|
187
|
+
q->unref();
|
|
194
188
|
}
|