libcouchbase 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/.gitignore +2 -0
  3. data/ext/libcouchbase/CMakeLists.txt +5 -7
  4. data/ext/libcouchbase/README.markdown +2 -2
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +49 -0
  6. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  7. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
  8. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +2 -1
  9. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  10. data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
  11. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  12. data/ext/libcouchbase/cmake/source_files.cmake +34 -14
  13. data/ext/libcouchbase/configure.pl +1 -1
  14. data/ext/libcouchbase/contrib/genhash/genhash.h +6 -0
  15. data/ext/libcouchbase/include/libcouchbase/auth.h +10 -0
  16. data/ext/libcouchbase/include/libcouchbase/couchbase.h +10 -0
  17. data/ext/libcouchbase/include/libcouchbase/error.h +7 -0
  18. data/ext/libcouchbase/include/libcouchbase/n1ql.h +13 -1
  19. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
  20. data/ext/libcouchbase/include/libcouchbase/subdoc.h +9 -0
  21. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  22. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  23. data/ext/libcouchbase/include/memcached/protocol_binary.h +21 -1132
  24. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  25. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  26. data/ext/libcouchbase/src/README.md +0 -2
  27. data/ext/libcouchbase/src/auth-priv.h +1 -0
  28. data/ext/libcouchbase/src/auth.cc +10 -0
  29. data/ext/libcouchbase/src/bootstrap.cc +216 -0
  30. data/ext/libcouchbase/src/bootstrap.h +50 -39
  31. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +455 -0
  32. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  33. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +528 -0
  34. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  35. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +115 -0
  36. data/ext/libcouchbase/src/bucketconfig/clconfig.h +407 -386
  37. data/ext/libcouchbase/src/bucketconfig/confmon.cc +378 -0
  38. data/ext/libcouchbase/src/cbft.cc +22 -27
  39. data/ext/libcouchbase/src/cntl.cc +24 -24
  40. data/ext/libcouchbase/src/connspec.cc +30 -1
  41. data/ext/libcouchbase/src/connspec.h +17 -0
  42. data/ext/libcouchbase/src/dns-srv.cc +143 -0
  43. data/ext/libcouchbase/src/{dump.c → dump.cc} +8 -11
  44. data/ext/libcouchbase/src/getconfig.cc +73 -0
  45. data/ext/libcouchbase/src/handler.cc +84 -85
  46. data/ext/libcouchbase/src/hostlist.cc +0 -1
  47. data/ext/libcouchbase/src/hostlist.h +6 -1
  48. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  49. data/ext/libcouchbase/src/http/http.cc +9 -29
  50. data/ext/libcouchbase/src/http/http.h +1 -34
  51. data/ext/libcouchbase/src/http/http_io.cc +22 -26
  52. data/ext/libcouchbase/src/instance.cc +102 -28
  53. data/ext/libcouchbase/src/internal.h +47 -29
  54. data/ext/libcouchbase/src/jsparse/parser.cc +146 -202
  55. data/ext/libcouchbase/src/jsparse/parser.h +91 -98
  56. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  57. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  58. data/ext/libcouchbase/src/lcbio/connect.cc +562 -0
  59. data/ext/libcouchbase/src/lcbio/connect.h +9 -2
  60. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  61. data/ext/libcouchbase/src/lcbio/iotable.h +61 -16
  62. data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
  63. data/ext/libcouchbase/src/lcbio/manager.c +2 -2
  64. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  65. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  66. data/ext/libcouchbase/src/mcserver/mcserver.cc +723 -0
  67. data/ext/libcouchbase/src/mcserver/mcserver.h +160 -70
  68. data/ext/libcouchbase/src/mcserver/negotiate.cc +118 -152
  69. data/ext/libcouchbase/src/mcserver/negotiate.h +85 -74
  70. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  71. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  72. data/ext/libcouchbase/src/n1ql/n1ql.cc +56 -32
  73. data/ext/libcouchbase/src/{newconfig.c → newconfig.cc} +42 -70
  74. data/ext/libcouchbase/src/nodeinfo.cc +4 -8
  75. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  76. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  77. data/ext/libcouchbase/src/operations/{durability-cas.c → durability-cas.cc} +92 -76
  78. data/ext/libcouchbase/src/operations/{durability-seqno.c → durability-seqno.cc} +55 -49
  79. data/ext/libcouchbase/src/operations/durability.cc +643 -0
  80. data/ext/libcouchbase/src/operations/durability_internal.h +212 -124
  81. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  82. data/ext/libcouchbase/src/operations/{observe-seqno.c → observe-seqno.cc} +5 -8
  83. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +69 -94
  84. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  85. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  86. data/ext/libcouchbase/src/operations/{stats.c → stats.cc} +66 -78
  87. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  88. data/ext/libcouchbase/src/operations/subdoc.cc +38 -18
  89. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  90. data/ext/libcouchbase/src/packetutils.h +200 -137
  91. data/ext/libcouchbase/src/probes.d +1 -1
  92. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +3 -4
  93. data/ext/libcouchbase/src/retryq.cc +394 -0
  94. data/ext/libcouchbase/src/retryq.h +116 -104
  95. data/ext/libcouchbase/src/settings.h +2 -1
  96. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  97. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  98. data/ext/libcouchbase/src/trace.h +8 -8
  99. data/ext/libcouchbase/src/vbucket/vbucket.c +0 -1
  100. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  101. data/ext/libcouchbase/src/views/docreq.h +24 -30
  102. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  103. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  104. data/ext/libcouchbase/src/{wait.c → wait.cc} +12 -17
  105. data/ext/libcouchbase/tests/basic/t_connstr.cc +89 -50
  106. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -78
  107. data/ext/libcouchbase/tests/basic/t_packet.cc +35 -42
  108. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  109. data/ext/libcouchbase/tests/iotests/t_confmon.cc +94 -111
  110. data/ext/libcouchbase/tests/iotests/t_sched.cc +1 -2
  111. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  112. data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
  113. data/lib/libcouchbase/version.rb +1 -1
  114. metadata +36 -39
  115. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  116. data/ext/libcouchbase/src/bootstrap.c +0 -269
  117. data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +0 -495
  118. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  119. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  120. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  121. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  122. data/ext/libcouchbase/src/getconfig.c +0 -100
  123. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  124. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  125. data/ext/libcouchbase/src/mcserver/mcserver.c +0 -784
  126. data/ext/libcouchbase/src/operations/durability.c +0 -668
  127. data/ext/libcouchbase/src/packetutils.c +0 -60
  128. data/ext/libcouchbase/src/retryq.c +0 -424
  129. data/ext/libcouchbase/src/simplestring.c +0 -211
  130. data/ext/libcouchbase/src/simplestring.h +0 -228
  131. data/ext/libcouchbase/src/ssobuf.h +0 -82
  132. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  133. 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
- }