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