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.
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
- }