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