libcouchbase 0.0.7 → 0.0.8
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/.gitignore +2 -0
- data/ext/libcouchbase/CMakeLists.txt +5 -7
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +49 -0
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +2 -1
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +34 -14
- data/ext/libcouchbase/configure.pl +1 -1
- data/ext/libcouchbase/contrib/genhash/genhash.h +6 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +10 -0
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +10 -0
- data/ext/libcouchbase/include/libcouchbase/error.h +7 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +13 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +9 -0
- 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 +21 -1132
- 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 +1 -0
- data/ext/libcouchbase/src/auth.cc +10 -0
- data/ext/libcouchbase/src/bootstrap.cc +216 -0
- data/ext/libcouchbase/src/bootstrap.h +50 -39
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +455 -0
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +528 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +115 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +407 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +378 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +24 -24
- data/ext/libcouchbase/src/connspec.cc +30 -1
- data/ext/libcouchbase/src/connspec.h +17 -0
- data/ext/libcouchbase/src/dns-srv.cc +143 -0
- data/ext/libcouchbase/src/{dump.c → dump.cc} +8 -11
- data/ext/libcouchbase/src/getconfig.cc +73 -0
- data/ext/libcouchbase/src/handler.cc +84 -85
- data/ext/libcouchbase/src/hostlist.cc +0 -1
- data/ext/libcouchbase/src/hostlist.h +6 -1
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +9 -29
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +22 -26
- data/ext/libcouchbase/src/instance.cc +102 -28
- data/ext/libcouchbase/src/internal.h +47 -29
- data/ext/libcouchbase/src/jsparse/parser.cc +146 -202
- data/ext/libcouchbase/src/jsparse/parser.h +91 -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 +562 -0
- data/ext/libcouchbase/src/lcbio/connect.h +9 -2
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +61 -16
- data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
- data/ext/libcouchbase/src/lcbio/manager.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +723 -0
- data/ext/libcouchbase/src/mcserver/mcserver.h +160 -70
- data/ext/libcouchbase/src/mcserver/negotiate.cc +118 -152
- data/ext/libcouchbase/src/mcserver/negotiate.h +85 -74
- 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 +56 -32
- data/ext/libcouchbase/src/{newconfig.c → newconfig.cc} +42 -70
- data/ext/libcouchbase/src/nodeinfo.cc +4 -8
- 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-cas.c → durability-cas.cc} +92 -76
- data/ext/libcouchbase/src/operations/{durability-seqno.c → durability-seqno.cc} +55 -49
- data/ext/libcouchbase/src/operations/durability.cc +643 -0
- data/ext/libcouchbase/src/operations/durability_internal.h +212 -124
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe-seqno.c → observe-seqno.cc} +5 -8
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +69 -94
- 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.c → stats.cc} +66 -78
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +38 -18
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +200 -137
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +3 -4
- data/ext/libcouchbase/src/retryq.cc +394 -0
- data/ext/libcouchbase/src/retryq.h +116 -104
- data/ext/libcouchbase/src/settings.h +2 -1
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/trace.h +8 -8
- data/ext/libcouchbase/src/vbucket/vbucket.c +0 -1
- 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/src/{wait.c → wait.cc} +12 -17
- data/ext/libcouchbase/tests/basic/t_connstr.cc +89 -50
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -78
- data/ext/libcouchbase/tests/basic/t_packet.cc +35 -42
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +94 -111
- data/ext/libcouchbase/tests/iotests/t_sched.cc +1 -2
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
- data/lib/libcouchbase/version.rb +1 -1
- metadata +36 -39
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +0 -495
- 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/getconfig.c +0 -100
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/mcserver/mcserver.c +0 -784
- data/ext/libcouchbase/src/operations/durability.c +0 -668
- data/ext/libcouchbase/src/packetutils.c +0 -60
- data/ext/libcouchbase/src/retryq.c +0 -424
- 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
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2014 Couchbase, Inc.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
#include "packetutils.h"
|
|
19
|
-
#include "rdb/rope.h"
|
|
20
|
-
|
|
21
|
-
#ifndef _WIN32 /* for win32 this is inside winsock, included in sysdefs.h */
|
|
22
|
-
#include <arpa/inet.h>
|
|
23
|
-
#endif
|
|
24
|
-
|
|
25
|
-
int
|
|
26
|
-
lcb_pktinfo_ior_get(packet_info *info, rdb_IOROPE *ior, unsigned *required)
|
|
27
|
-
{
|
|
28
|
-
unsigned total = rdb_get_nused(ior);
|
|
29
|
-
unsigned wanted = sizeof(info->res.bytes);
|
|
30
|
-
|
|
31
|
-
if (total < wanted) {
|
|
32
|
-
*required = wanted;
|
|
33
|
-
return 0;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
rdb_copyread(ior, info->res.bytes, sizeof(info->res.bytes));
|
|
37
|
-
if (!PACKET_NBODY(info)) {
|
|
38
|
-
rdb_consumed(ior, sizeof(info->res.bytes));
|
|
39
|
-
return 1;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
wanted += PACKET_NBODY(info);
|
|
43
|
-
if (total < wanted) {
|
|
44
|
-
*required = wanted;
|
|
45
|
-
return 0;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
rdb_consumed(ior, sizeof(info->res.bytes));
|
|
49
|
-
info->payload = rdb_get_consolidated(ior, PACKET_NBODY(info));
|
|
50
|
-
return 1;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
void
|
|
54
|
-
lcb_pktinfo_ior_done(packet_info *info, rdb_IOROPE *ior)
|
|
55
|
-
{
|
|
56
|
-
if (!PACKET_NBODY(info)) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
rdb_consumed(ior, PACKET_NBODY(info));
|
|
60
|
-
}
|
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2014 Couchbase, Inc.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
#include "packetutils.h"
|
|
19
|
-
#include "retryq.h"
|
|
20
|
-
#include "config.h"
|
|
21
|
-
#include "logging.h"
|
|
22
|
-
#include "internal.h"
|
|
23
|
-
#include "bucketconfig/clconfig.h"
|
|
24
|
-
|
|
25
|
-
#define LOGARGS(rq, lvl) (rq)->settings, "retryq", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
26
|
-
#define RETRY_PKT_KEY "retry_queue"
|
|
27
|
-
|
|
28
|
-
typedef struct {
|
|
29
|
-
mc_EPKTDATUM epd;
|
|
30
|
-
lcb_list_t ll_sched;
|
|
31
|
-
lcb_list_t ll_tmo;
|
|
32
|
-
|
|
33
|
-
/**Cache the actual start time of the command. Since the start time may
|
|
34
|
-
* change if read_ts_wait is enabled, and we don't want to end up looping
|
|
35
|
-
* on a command forever. */
|
|
36
|
-
hrtime_t start;
|
|
37
|
-
hrtime_t trytime; /**< Next retry time */
|
|
38
|
-
mc_PACKET *pkt;
|
|
39
|
-
lcb_error_t origerr;
|
|
40
|
-
} lcb_RETRYOP;
|
|
41
|
-
|
|
42
|
-
#define RETRY_INTERVAL_NS(q) LCB_US2NS((q)->settings->retry_interval)
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Fuzz offset. When callback is received to schedule an operation, we may
|
|
46
|
-
* retry commands whose expiry is up to this many seconds in the future. This
|
|
47
|
-
* is to avoid excessive callbacks into the timer function
|
|
48
|
-
*/
|
|
49
|
-
#define TIMEFUZZ_NS LCB_US2NS(LCB_MS2US(5))
|
|
50
|
-
|
|
51
|
-
static void
|
|
52
|
-
update_trytime(lcb_RETRYQ *rq, lcb_RETRYOP *op, hrtime_t now)
|
|
53
|
-
{
|
|
54
|
-
/**
|
|
55
|
-
* Estimate the next retry timestamp. This is:
|
|
56
|
-
* Base interval + (Number of retries x Backoff factor)
|
|
57
|
-
*/
|
|
58
|
-
if (!now) {
|
|
59
|
-
now = gethrtime();
|
|
60
|
-
}
|
|
61
|
-
op->trytime = now + (hrtime_t) (
|
|
62
|
-
(float)RETRY_INTERVAL_NS(rq) *
|
|
63
|
-
(float)op->pkt->retries *
|
|
64
|
-
(float)rq->settings->retry_backoff);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** Comparison routine for sorting by timeout */
|
|
68
|
-
static int
|
|
69
|
-
cmpfn_tmo(lcb_list_t *ll_a, lcb_list_t *ll_b)
|
|
70
|
-
{
|
|
71
|
-
lcb_RETRYOP *a = LCB_LIST_ITEM(ll_a, lcb_RETRYOP, ll_tmo);
|
|
72
|
-
lcb_RETRYOP *b = LCB_LIST_ITEM(ll_b, lcb_RETRYOP, ll_tmo);
|
|
73
|
-
|
|
74
|
-
if (a->start == b->start) {
|
|
75
|
-
return 0;
|
|
76
|
-
} else if (a->start> b->start) {
|
|
77
|
-
return 1;
|
|
78
|
-
} else {
|
|
79
|
-
return -1;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
static int
|
|
84
|
-
cmpfn_retry(lcb_list_t *ll_a, lcb_list_t *ll_b)
|
|
85
|
-
{
|
|
86
|
-
lcb_RETRYOP *a = LCB_LIST_ITEM(ll_a, lcb_RETRYOP, ll_sched);
|
|
87
|
-
lcb_RETRYOP *b = LCB_LIST_ITEM(ll_b, lcb_RETRYOP, ll_sched);
|
|
88
|
-
if (a->trytime == b->trytime) {
|
|
89
|
-
return 0;
|
|
90
|
-
} else if (a->trytime > b->trytime) {
|
|
91
|
-
return 1;
|
|
92
|
-
} else {
|
|
93
|
-
return -1;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
static void
|
|
98
|
-
assign_error(lcb_RETRYOP *op, lcb_error_t err)
|
|
99
|
-
{
|
|
100
|
-
if (err == LCB_NOT_MY_VBUCKET) {
|
|
101
|
-
err = LCB_ETIMEDOUT; /* :( */
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (op->origerr == LCB_SUCCESS) {
|
|
105
|
-
op->origerr = err;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (err == LCB_ETIMEDOUT) {
|
|
109
|
-
return; /* Ignore timeout errors */
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (LCB_EIFNET(op->origerr) && op->origerr != LCB_ETIMEDOUT &&
|
|
113
|
-
(err == LCB_NETWORK_ERROR || err == LCB_CONNECT_ERROR)) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
op->origerr = err;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
static void
|
|
121
|
-
clean_op(lcb_RETRYOP *op)
|
|
122
|
-
{
|
|
123
|
-
lcb_list_delete(&op->ll_sched);
|
|
124
|
-
lcb_list_delete(&op->ll_tmo);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
static void
|
|
128
|
-
bail_op(lcb_RETRYQ *rq, lcb_RETRYOP *op, lcb_error_t err)
|
|
129
|
-
{
|
|
130
|
-
packet_info info;
|
|
131
|
-
protocol_binary_request_header hdr;
|
|
132
|
-
protocol_binary_response_header *res = &info.res;
|
|
133
|
-
mc_SERVER tmpsrv; /** Temporary pipeline */
|
|
134
|
-
mc_PIPELINE *pltmp = &tmpsrv.pipeline;
|
|
135
|
-
|
|
136
|
-
memset(&tmpsrv, 0, sizeof tmpsrv);
|
|
137
|
-
tmpsrv.instance = rq->cq->cqdata;
|
|
138
|
-
tmpsrv.pipeline.parent = rq->cq;
|
|
139
|
-
|
|
140
|
-
memset(&info, 0, sizeof(info));
|
|
141
|
-
mcreq_read_hdr(op->pkt, &hdr);
|
|
142
|
-
res->response.opcode = hdr.request.opcode;
|
|
143
|
-
res->response.status = ntohs(PROTOCOL_BINARY_RESPONSE_EINVAL);
|
|
144
|
-
res->response.opaque = hdr.request.opaque;
|
|
145
|
-
|
|
146
|
-
assign_error(op, err);
|
|
147
|
-
lcb_log(LOGARGS(rq, WARN), "Failing command (seq=%u) from retry queue with error code 0x%x", op->pkt->opaque, op->origerr);
|
|
148
|
-
mcreq_dispatch_response(pltmp, op->pkt, &info, op->origerr);
|
|
149
|
-
op->pkt->flags |= MCREQ_F_FLUSHED|MCREQ_F_INVOKED;
|
|
150
|
-
clean_op(op);
|
|
151
|
-
mcreq_packet_done(pltmp, op->pkt);
|
|
152
|
-
lcb_maybe_breakout(rq->cq->cqdata);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
static void
|
|
156
|
-
do_schedule(lcb_RETRYQ *q, hrtime_t now)
|
|
157
|
-
{
|
|
158
|
-
hrtime_t tmonext, schednext, diff, selected;
|
|
159
|
-
uint32_t us_interval;
|
|
160
|
-
lcb_RETRYOP *first_tmo, *first_sched;
|
|
161
|
-
|
|
162
|
-
if (!now) {
|
|
163
|
-
now = gethrtime();
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (LCB_LIST_IS_EMPTY(&q->schedops)) {
|
|
167
|
-
lcbio_timer_disarm(q->timer);
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/** Figure out which is first */
|
|
172
|
-
first_tmo = LCB_LIST_ITEM(LCB_LIST_HEAD(&q->tmoops), lcb_RETRYOP, ll_tmo);
|
|
173
|
-
first_sched = LCB_LIST_ITEM(LCB_LIST_HEAD(&q->schedops), lcb_RETRYOP, ll_sched);
|
|
174
|
-
|
|
175
|
-
schednext = first_sched->trytime;
|
|
176
|
-
tmonext = first_tmo->start;
|
|
177
|
-
tmonext += LCB_US2NS(q->settings->operation_timeout);
|
|
178
|
-
selected = schednext > tmonext ? tmonext : schednext;
|
|
179
|
-
|
|
180
|
-
if (selected <= now) {
|
|
181
|
-
diff = 0;
|
|
182
|
-
} else {
|
|
183
|
-
diff = selected - now;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
us_interval = LCB_NS2US(diff);
|
|
187
|
-
lcb_log(LOGARGS(q, TRACE), "Next tick in %u ms", (unsigned)us_interval/1000);
|
|
188
|
-
lcbio_timer_rearm(q->timer, us_interval);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Flush the queue
|
|
193
|
-
* @param rq The queue to flush
|
|
194
|
-
* @param throttle Whether to throttle operations to be retried. If this is
|
|
195
|
-
* set to false then all operations will be attempted (assuming they have
|
|
196
|
-
* not timed out)
|
|
197
|
-
*/
|
|
198
|
-
static void
|
|
199
|
-
rq_flush(lcb_RETRYQ *rq, int throttle)
|
|
200
|
-
{
|
|
201
|
-
hrtime_t now = gethrtime();
|
|
202
|
-
lcb_list_t *ll, *ll_next;
|
|
203
|
-
lcb_list_t resched_next;
|
|
204
|
-
|
|
205
|
-
/** Check timeouts first */
|
|
206
|
-
LCB_LIST_SAFE_FOR(ll, ll_next, &rq->tmoops) {
|
|
207
|
-
lcb_RETRYOP *op = LCB_LIST_ITEM(ll, lcb_RETRYOP, ll_tmo);
|
|
208
|
-
hrtime_t curtmo = op->start + LCB_US2NS(rq->settings->operation_timeout);
|
|
209
|
-
|
|
210
|
-
if (curtmo <= now) {
|
|
211
|
-
bail_op(rq, op, LCB_ETIMEDOUT);
|
|
212
|
-
} else {
|
|
213
|
-
break;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
lcb_list_init(&resched_next);
|
|
218
|
-
LCB_LIST_SAFE_FOR(ll, ll_next, &rq->schedops) {
|
|
219
|
-
protocol_binary_request_header hdr;
|
|
220
|
-
int vbid, srvix;
|
|
221
|
-
hrtime_t curnext;
|
|
222
|
-
|
|
223
|
-
lcb_RETRYOP *op = LCB_LIST_ITEM(ll, lcb_RETRYOP, ll_sched);
|
|
224
|
-
curnext = op->trytime - TIMEFUZZ_NS;
|
|
225
|
-
|
|
226
|
-
if (curnext > now && throttle) {
|
|
227
|
-
break;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
mcreq_read_hdr(op->pkt, &hdr);
|
|
231
|
-
vbid = ntohs(hdr.request.vbucket);
|
|
232
|
-
srvix = lcbvb_vbmaster(rq->cq->config, vbid);
|
|
233
|
-
|
|
234
|
-
if (srvix < 0 || (unsigned)srvix >= rq->cq->npipelines) {
|
|
235
|
-
/* No server found to map to */
|
|
236
|
-
lcb_t instance = rq->cq->cqdata;
|
|
237
|
-
|
|
238
|
-
assign_error(op, LCB_NO_MATCHING_SERVER);
|
|
239
|
-
|
|
240
|
-
/* Request a new configuration. If it's time to request a new
|
|
241
|
-
* configuration (i.e. the attempt has not been throttled) then
|
|
242
|
-
* keep the command in there until it has a chance to be scheduled.
|
|
243
|
-
*/
|
|
244
|
-
lcb_bootstrap_common(instance, LCB_BS_REFRESH_THROTTLE);
|
|
245
|
-
if (lcb_confmon_is_refreshing(instance->confmon) ||
|
|
246
|
-
rq->settings->retry[LCB_RETRY_ON_MISSINGNODE]) {
|
|
247
|
-
|
|
248
|
-
lcb_list_delete(&op->ll_sched);
|
|
249
|
-
lcb_list_delete(&op->ll_tmo);
|
|
250
|
-
lcb_list_append(&resched_next, &op->ll_sched);
|
|
251
|
-
op->pkt->retries++;
|
|
252
|
-
update_trytime(rq, op, now);
|
|
253
|
-
} else {
|
|
254
|
-
bail_op(rq, op, LCB_NO_MATCHING_SERVER);
|
|
255
|
-
}
|
|
256
|
-
} else {
|
|
257
|
-
mc_PIPELINE *newpl = rq->cq->pipelines[srvix];
|
|
258
|
-
mcreq_enqueue_packet(newpl, op->pkt);
|
|
259
|
-
newpl->flush_start(newpl);
|
|
260
|
-
clean_op(op);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
LCB_LIST_SAFE_FOR(ll, ll_next, &resched_next) {
|
|
265
|
-
lcb_RETRYOP *op = LCB_LIST_ITEM(ll, lcb_RETRYOP, ll_sched);
|
|
266
|
-
lcb_list_add_sorted(&rq->schedops, &op->ll_sched, cmpfn_retry);
|
|
267
|
-
lcb_list_add_sorted(&rq->tmoops, &op->ll_tmo, cmpfn_tmo);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
do_schedule(rq, now);
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
static void
|
|
275
|
-
rq_tick(void *arg)
|
|
276
|
-
{
|
|
277
|
-
rq_flush(arg, 1);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
void
|
|
281
|
-
lcb_retryq_signal(lcb_RETRYQ *rq)
|
|
282
|
-
{
|
|
283
|
-
rq_flush(rq, 0);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
static void
|
|
287
|
-
op_dtorfn(mc_EPKTDATUM *d)
|
|
288
|
-
{
|
|
289
|
-
free(d);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
#define RETRY_SCHED_IMM 0x01
|
|
294
|
-
|
|
295
|
-
static void
|
|
296
|
-
add_op(lcb_RETRYQ *rq, mc_EXPACKET *pkt, const lcb_error_t err, int options)
|
|
297
|
-
{
|
|
298
|
-
lcb_RETRYOP *op;
|
|
299
|
-
mc_EPKTDATUM *d;
|
|
300
|
-
|
|
301
|
-
d = mcreq_epkt_find(pkt, RETRY_PKT_KEY);
|
|
302
|
-
if (d) {
|
|
303
|
-
op = (lcb_RETRYOP *)d;
|
|
304
|
-
} else {
|
|
305
|
-
op = calloc(1, sizeof *op);
|
|
306
|
-
op->epd.dtorfn = op_dtorfn;
|
|
307
|
-
op->epd.key = RETRY_PKT_KEY;
|
|
308
|
-
op->start = MCREQ_PKT_RDATA(&pkt->base)->start;
|
|
309
|
-
mcreq_epkt_insert(pkt, &op->epd);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
op->pkt = &pkt->base;
|
|
313
|
-
pkt->base.retries++;
|
|
314
|
-
assign_error(op, err);
|
|
315
|
-
if (options & RETRY_SCHED_IMM) {
|
|
316
|
-
op->trytime = gethrtime(); /* now */
|
|
317
|
-
} else if (err == LCB_NOT_MY_VBUCKET) {
|
|
318
|
-
op->trytime = gethrtime() + LCB_US2NS(rq->settings->retry_nmv_interval);
|
|
319
|
-
} else {
|
|
320
|
-
update_trytime(rq, op, 0);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
lcb_list_add_sorted(&rq->schedops, &op->ll_sched, cmpfn_retry);
|
|
324
|
-
lcb_list_add_sorted(&rq->tmoops, &op->ll_tmo, cmpfn_tmo);
|
|
325
|
-
|
|
326
|
-
lcb_log(LOGARGS(rq, DEBUG), "Adding PKT=%p to retry queue. Try count=%u", (void*)pkt, pkt->base.retries);
|
|
327
|
-
do_schedule(rq, 0);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
void
|
|
331
|
-
lcb_retryq_add(lcb_RETRYQ *rq, mc_EXPACKET *pkt, lcb_error_t err)
|
|
332
|
-
{
|
|
333
|
-
add_op(rq, pkt, err, 0);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
void
|
|
337
|
-
lcb_retryq_nmvadd(lcb_RETRYQ *rq, mc_EXPACKET *detchpkt)
|
|
338
|
-
{
|
|
339
|
-
int flags = 0;
|
|
340
|
-
if (rq->settings->nmv_retry_imm) {
|
|
341
|
-
flags = RETRY_SCHED_IMM;
|
|
342
|
-
}
|
|
343
|
-
add_op(rq, detchpkt, LCB_NOT_MY_VBUCKET, flags);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
static void
|
|
347
|
-
fallback_handler(mc_CMDQUEUE *cq, mc_PACKET *pkt)
|
|
348
|
-
{
|
|
349
|
-
lcb_t instance = cq->cqdata;
|
|
350
|
-
mc_PACKET *copy = mcreq_renew_packet(pkt);
|
|
351
|
-
add_op(instance->retryq, (mc_EXPACKET*)copy,
|
|
352
|
-
LCB_NO_MATCHING_SERVER, RETRY_SCHED_IMM);
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
void
|
|
356
|
-
lcb_retryq_reset_timeouts(lcb_RETRYQ *rq, lcb_U64 now)
|
|
357
|
-
{
|
|
358
|
-
lcb_list_t *ll;
|
|
359
|
-
LCB_LIST_FOR(ll, &rq->schedops) {
|
|
360
|
-
lcb_RETRYOP *op = LCB_LIST_ITEM(ll, lcb_RETRYOP, ll_sched);
|
|
361
|
-
op->start = now;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
lcb_RETRYQ *
|
|
366
|
-
lcb_retryq_new(mc_CMDQUEUE *cq, lcbio_pTABLE table, lcb_settings *settings)
|
|
367
|
-
{
|
|
368
|
-
lcb_RETRYQ *rq = calloc(1, sizeof(*rq));
|
|
369
|
-
|
|
370
|
-
rq->settings = settings;
|
|
371
|
-
rq->cq = cq;
|
|
372
|
-
rq->timer = lcbio_timer_new(table, rq, rq_tick);
|
|
373
|
-
|
|
374
|
-
lcb_settings_ref(settings);
|
|
375
|
-
lcb_list_init(&rq->tmoops);
|
|
376
|
-
lcb_list_init(&rq->schedops);
|
|
377
|
-
mcreq_set_fallback_handler(cq, fallback_handler);
|
|
378
|
-
return rq;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
void
|
|
382
|
-
lcb_retryq_destroy(lcb_RETRYQ *rq)
|
|
383
|
-
{
|
|
384
|
-
lcb_list_t *llcur, *llnext;
|
|
385
|
-
|
|
386
|
-
LCB_LIST_SAFE_FOR(llcur, llnext, &rq->schedops) {
|
|
387
|
-
lcb_RETRYOP *op = LCB_LIST_ITEM(llcur, lcb_RETRYOP, ll_sched);
|
|
388
|
-
bail_op(rq, op, LCB_ERROR);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
lcbio_timer_destroy(rq->timer);
|
|
392
|
-
lcb_settings_unref(rq->settings);
|
|
393
|
-
free(rq);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
lcb_error_t
|
|
397
|
-
lcb_retryq_origerr(const mc_PACKET *packet)
|
|
398
|
-
{
|
|
399
|
-
mc_EPKTDATUM *d;
|
|
400
|
-
lcb_RETRYOP *op;
|
|
401
|
-
|
|
402
|
-
if (! (packet->flags & MCREQ_F_DETACHED)) {
|
|
403
|
-
return LCB_SUCCESS; /* Not detached */
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
d = mcreq_epkt_find((mc_EXPACKET*)packet, RETRY_PKT_KEY);
|
|
407
|
-
if (!d) {
|
|
408
|
-
return LCB_SUCCESS;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
op = (lcb_RETRYOP *)d;
|
|
412
|
-
return op->origerr;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
void
|
|
416
|
-
lcb_retryq_dump(lcb_RETRYQ *rq, FILE *fp, mcreq_payload_dump_fn dumpfn)
|
|
417
|
-
{
|
|
418
|
-
lcb_list_t *cur;
|
|
419
|
-
LCB_LIST_FOR(cur, &rq->schedops) {
|
|
420
|
-
lcb_RETRYOP *op = LCB_LIST_ITEM(cur, lcb_RETRYOP, ll_sched);
|
|
421
|
-
mcreq_dump_packet(op->pkt, fp, dumpfn);
|
|
422
|
-
}
|
|
423
|
-
(void)fp;
|
|
424
|
-
}
|