libcouchbase 0.3.3 → 1.0.0

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/CMakeLists.txt +6 -8
  3. data/ext/libcouchbase/README.markdown +2 -2
  4. data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
  5. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  6. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
  7. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
  8. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  9. data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
  10. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  11. data/ext/libcouchbase/cmake/source_files.cmake +21 -5
  12. data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
  13. data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
  14. data/ext/libcouchbase/example/users/README +48 -0
  15. data/ext/libcouchbase/example/users/users.c +147 -0
  16. data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
  17. data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
  18. data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
  19. data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
  20. data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
  21. data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
  22. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
  23. data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
  24. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  25. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  26. data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
  27. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  28. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  29. data/ext/libcouchbase/src/README.md +0 -2
  30. data/ext/libcouchbase/src/auth-priv.h +23 -4
  31. data/ext/libcouchbase/src/auth.cc +51 -43
  32. data/ext/libcouchbase/src/bootstrap.cc +244 -0
  33. data/ext/libcouchbase/src/bootstrap.h +58 -38
  34. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
  35. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  36. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
  37. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  38. data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
  39. data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
  40. data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
  41. data/ext/libcouchbase/src/cbft.cc +22 -27
  42. data/ext/libcouchbase/src/cntl.cc +56 -22
  43. data/ext/libcouchbase/src/connspec.cc +47 -6
  44. data/ext/libcouchbase/src/connspec.h +27 -0
  45. data/ext/libcouchbase/src/dns-srv.cc +147 -0
  46. data/ext/libcouchbase/src/dump.cc +3 -3
  47. data/ext/libcouchbase/src/errmap.cc +173 -0
  48. data/ext/libcouchbase/src/errmap.h +198 -0
  49. data/ext/libcouchbase/src/getconfig.cc +7 -33
  50. data/ext/libcouchbase/src/handler.cc +118 -7
  51. data/ext/libcouchbase/src/hostlist.cc +0 -36
  52. data/ext/libcouchbase/src/hostlist.h +44 -62
  53. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  54. data/ext/libcouchbase/src/http/http.cc +27 -35
  55. data/ext/libcouchbase/src/http/http.h +1 -34
  56. data/ext/libcouchbase/src/http/http_io.cc +28 -36
  57. data/ext/libcouchbase/src/instance.cc +131 -34
  58. data/ext/libcouchbase/src/internal.h +58 -26
  59. data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
  60. data/ext/libcouchbase/src/jsparse/parser.h +84 -98
  61. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  62. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  63. data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
  64. data/ext/libcouchbase/src/lcbio/connect.h +16 -7
  65. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  66. data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
  67. data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
  68. data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
  69. data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
  70. data/ext/libcouchbase/src/lcbio/manager.h +133 -96
  71. data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
  72. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  73. data/ext/libcouchbase/src/mc/mcreq.c +11 -2
  74. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  75. data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
  76. data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
  77. data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
  78. data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
  79. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  80. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  81. data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
  82. data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
  83. data/ext/libcouchbase/src/newconfig.cc +6 -6
  84. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  85. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  86. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  87. data/ext/libcouchbase/src/operations/durability.cc +6 -26
  88. data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
  89. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  90. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
  91. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  92. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  93. data/ext/libcouchbase/src/operations/stats.cc +3 -8
  94. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  95. data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
  96. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  97. data/ext/libcouchbase/src/packetutils.h +30 -2
  98. data/ext/libcouchbase/src/probes.d +1 -1
  99. data/ext/libcouchbase/src/rdb/rope.c +1 -1
  100. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
  101. data/ext/libcouchbase/src/retryq.cc +52 -14
  102. data/ext/libcouchbase/src/retryq.h +3 -3
  103. data/ext/libcouchbase/src/settings.c +5 -0
  104. data/ext/libcouchbase/src/settings.h +11 -0
  105. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  106. data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
  107. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  108. data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
  109. data/ext/libcouchbase/src/trace.h +4 -4
  110. data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
  111. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  112. data/ext/libcouchbase/src/views/docreq.h +24 -30
  113. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  114. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  115. data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
  116. data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
  117. data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
  118. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
  119. data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
  120. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
  121. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  122. data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
  123. data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
  124. data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
  125. data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
  126. data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
  127. data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
  128. data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
  129. data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
  130. data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
  131. data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
  132. data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
  133. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
  134. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
  135. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  136. data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
  137. data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
  138. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  139. data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
  140. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  141. data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
  142. data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
  143. data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
  144. data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
  145. data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
  146. data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
  147. data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
  148. data/ext/libcouchbase/tools/cbc.cc +143 -10
  149. data/ext/libcouchbase/tools/docgen/loc.h +1 -1
  150. data/lib/libcouchbase/connection.rb +4 -3
  151. data/lib/libcouchbase/version.rb +1 -1
  152. metadata +37 -28
  153. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  154. data/ext/libcouchbase/src/bootstrap.c +0 -269
  155. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  156. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  157. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  158. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  159. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  160. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  161. data/ext/libcouchbase/src/lcbio/manager.c +0 -584
  162. data/ext/libcouchbase/src/packetutils.c +0 -37
  163. data/ext/libcouchbase/src/simplestring.c +0 -211
  164. data/ext/libcouchbase/src/simplestring.h +0 -228
  165. data/ext/libcouchbase/src/ssobuf.h +0 -82
  166. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  167. data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -28,7 +28,7 @@ provider libcouchbase {
28
28
  uint16_t, /* return code (from libcouchbase) */
29
29
  const char*, /* key */
30
30
  size_t, /* nkey */
31
- const void*, /* bytes */
31
+ const char*, /* bytes */
32
32
  size_t, /* nbytes */
33
33
  uint32_t, /* flags */
34
34
  uint64_t, /* cas */
@@ -395,7 +395,7 @@ dump_ropebuf(const rdb_ROPEBUF *buf, FILE *fp)
395
395
  rdb_ROPESEG *seg = LCB_LIST_ITEM(llcur, rdb_ROPESEG, llnode);
396
396
  fprintf(fp, "%sSEG=%p\n", indent, (void*)seg);
397
397
  fprintf(fp, "%sALLOCATOR=%p [%u]\n", indent, (void*)seg->allocator, seg->allocid);
398
- fprintf(fp, "%sBUFROOT=%p\n", indent, seg->root);
398
+ fprintf(fp, "%sBUFROOT=%p\n", indent, (void *)seg->root);
399
399
  fprintf(fp, "%sALLOC SIZE: %u\n", indent, seg->nalloc);
400
400
  fprintf(fp, "%sDATA SIZE: %u\n", indent, seg->nused);
401
401
  fprintf(fp, "%sDATS OFFSET: %u\n", indent, seg->start);
@@ -20,8 +20,8 @@
20
20
  int
21
21
  lcb_should_retry(const lcb_settings *settings, const mc_PACKET *pkt, lcb_error_t err)
22
22
  {
23
- lcb_RETRYCMDOPTS policy;
24
- lcb_RETRYMODEOPTS mode;
23
+ unsigned policy;
24
+ unsigned mode;
25
25
  protocol_binary_request_header hdr;
26
26
 
27
27
  mcreq_read_hdr(pkt, &hdr);
@@ -70,7 +70,6 @@ lcb_should_retry(const lcb_settings *settings, const mc_PACKET *pkt, lcb_error_t
70
70
 
71
71
  /* get is a safe operation which may be retried */
72
72
  case PROTOCOL_BINARY_CMD_GET:
73
- case PROTOCOL_BINARY_CMD_GETKQ:
74
73
  case PROTOCOL_BINARY_CMD_SUBDOC_GET:
75
74
  case PROTOCOL_BINARY_CMD_SUBDOC_EXISTS:
76
75
  case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_LOOKUP:
@@ -37,7 +37,13 @@ struct lcb::RetryOp : mc_EPKTDATUM, SchedNode, TmoNode {
37
37
  hrtime_t trytime; /**< Next retry time */
38
38
  mc_PACKET *pkt;
39
39
  lcb_error_t origerr;
40
- RetryOp();
40
+ errmap::RetrySpec *spec;
41
+ RetryOp(errmap::RetrySpec *spec);
42
+ ~RetryOp() {
43
+ if (spec != NULL) {
44
+ spec->unref();
45
+ }
46
+ }
41
47
  };
42
48
 
43
49
  static RetryOp *from_schednode(lcb_list_t *ll) {
@@ -79,10 +85,24 @@ RetryQueue::update_trytime(RetryOp *op, hrtime_t now)
79
85
  if (!now) {
80
86
  now = gethrtime();
81
87
  }
82
- op->trytime = now + (hrtime_t) (
83
- (float)get_retry_interval() *
84
- (float)op->pkt->retries *
85
- (float)settings->retry_backoff);
88
+
89
+ if (op->spec) {
90
+ uint32_t us_trytime = op->spec->get_next_interval(op->pkt->retries - 1);
91
+ if (op->pkt->retries == 1) {
92
+ us_trytime += op->spec->after;
93
+ }
94
+ if (!us_trytime) {
95
+ goto GT_DEFAULT;
96
+ }
97
+ op->trytime = now + (LCB_US2NS(us_trytime));
98
+ } else {
99
+ GT_DEFAULT:
100
+ op->trytime = now + (hrtime_t) (
101
+ (float)get_retry_interval() *
102
+ (float)op->pkt->retries *
103
+ (float)settings->retry_backoff);
104
+
105
+ }
86
106
  }
87
107
 
88
108
  /** Comparison routine for sorting by timeout */
@@ -139,7 +159,7 @@ RetryQueue::fail(RetryOp *op, lcb_error_t err)
139
159
  PROTOCOL_BINARY_RESPONSE_EINVAL);
140
160
 
141
161
  assign_error(op, err);
142
- lcb_log(LOGARGS(this, WARN), "Failing command (seq=%u) from retry queue with error code 0x%x", op->pkt->opaque, op->origerr);
162
+ lcb_log(LOGARGS(this, WARN), "Failing command (seq=%u) from retry queue: %s", op->pkt->opaque, lcb_strerror_short(op->origerr));
143
163
 
144
164
  mcreq_dispatch_response(&tmpsrv, op->pkt, &resp, op->origerr);
145
165
  op->pkt->flags |= MCREQ_F_FLUSHED|MCREQ_F_INVOKED;
@@ -231,8 +251,8 @@ RetryQueue::flush(bool throttle)
231
251
  * configuration (i.e. the attempt has not been throttled) then
232
252
  * keep the command in there until it has a chance to be scheduled.
233
253
  */
234
- lcb_bootstrap_common(get_instance(), LCB_BS_REFRESH_THROTTLE);
235
- if (lcb_confmon_is_refreshing(get_instance()->confmon) ||
254
+ get_instance()->bootstrap(lcb::BS_REFRESH_THROTTLE);
255
+ if (get_instance()->confmon->is_refreshing() ||
236
256
  settings->retry[LCB_RETRY_ON_MISSINGNODE]) {
237
257
 
238
258
  lcb_list_delete(static_cast<SchedNode*>(op));
@@ -276,22 +296,40 @@ static void op_dtorfn(mc_EPKTDATUM *d) {
276
296
  delete static_cast<RetryOp*>(d);
277
297
  }
278
298
 
279
- RetryOp::RetryOp() {
280
- memset(this, 0, sizeof *this);
299
+ RetryOp::RetryOp(errmap::RetrySpec *spec_)
300
+ : mc_EPKTDATUM(), start(0), trytime(0), pkt(NULL), origerr(LCB_SUCCESS),
301
+ spec(spec_) {
281
302
  mc_EPKTDATUM::dtorfn = op_dtorfn;
282
303
  mc_EPKTDATUM::key = RETRY_PKT_KEY;
304
+
305
+ if (spec != NULL) {
306
+ spec->ref();
307
+ }
283
308
  }
284
309
 
285
310
  void
286
- RetryQueue::add(mc_EXPACKET *pkt, const lcb_error_t err, int options)
311
+ RetryQueue::add(mc_EXPACKET *pkt, const lcb_error_t err,
312
+ errmap::RetrySpec *spec, int options)
287
313
  {
288
314
  RetryOp *op;
289
315
  mc_EPKTDATUM *d = mcreq_epkt_find(pkt, RETRY_PKT_KEY);
290
316
  if (d) {
291
317
  op = static_cast<RetryOp *>(d);
292
318
  } else {
293
- op = new RetryOp();
319
+ op = new RetryOp(NULL);
294
320
  op->start = MCREQ_PKT_RDATA(&pkt->base)->start;
321
+ if (spec) {
322
+ op->spec = spec;
323
+ spec->ref();
324
+
325
+ if (spec->max_duration && spec->max_duration < settings->operation_timeout) {
326
+ // Offset the start by the difference between the duration and
327
+ // the timeout. We really use this number only for calculating
328
+ // the timeout, so it shouldn't hurt to fake it.
329
+ uint32_t diff = settings->operation_timeout - op->spec->max_duration;
330
+ op->start -= LCB_US2NS(diff);
331
+ }
332
+ }
295
333
  mcreq_epkt_insert(pkt, op);
296
334
  }
297
335
 
@@ -320,7 +358,7 @@ RetryQueue::nmvadd(mc_EXPACKET *detchpkt)
320
358
  if (settings->nmv_retry_imm) {
321
359
  flags = RETRY_SCHED_IMM;
322
360
  }
323
- add(detchpkt, LCB_NOT_MY_VBUCKET, flags);
361
+ add(detchpkt, LCB_NOT_MY_VBUCKET, NULL, flags);
324
362
  }
325
363
 
326
364
  static void
@@ -332,7 +370,7 @@ fallback_handler(mc_CMDQUEUE *cq, mc_PACKET *pkt)
332
370
 
333
371
  void RetryQueue::add_fallback(mc_PACKET *pkt) {
334
372
  mc_PACKET *copy = mcreq_renew_packet(pkt);
335
- add((mc_EXPACKET*)copy, LCB_NO_MATCHING_SERVER, RETRY_SCHED_IMM);
373
+ add((mc_EXPACKET*)copy, LCB_NO_MATCHING_SERVER, NULL, RETRY_SCHED_IMM);
336
374
  }
337
375
 
338
376
  void
@@ -72,8 +72,8 @@ public:
72
72
  * it may _not_ be used for memcached buckets (which is typically OK, as we only
73
73
  * map things here as a response for a not-my-vbucket).
74
74
  */
75
- void add(mc_EXPACKET *detchpkt, lcb_error_t err) {
76
- add(detchpkt, err, 0);
75
+ void add(mc_EXPACKET *detchpkt, lcb_error_t err, errmap::RetrySpec *spec) {
76
+ add(detchpkt, err, spec, 0);
77
77
  }
78
78
 
79
79
  /**
@@ -151,7 +151,7 @@ private:
151
151
  enum AddOptions {
152
152
  RETRY_SCHED_IMM = 0x01
153
153
  };
154
- void add(mc_EXPACKET *pkt, lcb_error_t, int options);
154
+ void add(mc_EXPACKET *pkt, lcb_error_t, errmap::RetrySpec*, int options);
155
155
 
156
156
  /** List of operations in retry ordering. Sorted by 'crtime' */
157
157
  lcb_list_t schedops;
@@ -57,6 +57,9 @@ void lcb_default_settings(lcb_settings *settings)
57
57
  settings->tcp_nodelay = LCB_DEFAULT_TCP_NODELAY;
58
58
  settings->retry_nmv_interval = LCB_DEFAULT_RETRY_NMV_INTERVAL;
59
59
  settings->vb_noguess = LCB_DEFAULT_VB_NOGUESS;
60
+ settings->select_bucket = LCB_DEFAULT_SELECT_BUCKET;
61
+ settings->tcp_keepalive = LCB_DEFAULT_TCP_KEEPALIVE;
62
+ settings->send_hello = 1;
60
63
  }
61
64
 
62
65
  LCB_INTERNAL_API
@@ -67,6 +70,7 @@ lcb_settings_new(void)
67
70
  lcb_default_settings(settings);
68
71
  settings->refcount = 1;
69
72
  settings->auth = lcbauth_new();
73
+ settings->errmap = lcb_errmap_new();
70
74
  return settings;
71
75
  }
72
76
 
@@ -83,6 +87,7 @@ lcb_settings_unref(lcb_settings *settings)
83
87
  free(settings->client_string);
84
88
 
85
89
  lcbauth_unref(settings->auth);
90
+ lcb_errmap_free(settings->errmap);
86
91
 
87
92
  if (settings->ssl_ctx) {
88
93
  lcbio_ssl_free(settings->ssl_ctx);
@@ -84,9 +84,12 @@
84
84
  #define LCB_DEFAULT_RETRY_NMV_INTERVAL LCB_MS2US(100)
85
85
  #define LCB_DEFAULT_VB_NOGUESS 1
86
86
  #define LCB_DEFAULT_TCP_NODELAY 1
87
+ #define LCB_DEFAULT_SELECT_BUCKET 1
88
+ #define LCB_DEFAULT_TCP_KEEPALIVE 1
87
89
 
88
90
  #include "config.h"
89
91
  #include <libcouchbase/couchbase.h>
92
+ #include "errmap.h"
90
93
 
91
94
  #ifdef __cplusplus
92
95
  extern "C" {
@@ -128,6 +131,9 @@ typedef struct lcb_settings_st {
128
131
  * updates. */
129
132
  lcb_U32 bc_http_stream_time;
130
133
 
134
+ /** Time to wait in between background config polls. 0 disables this */
135
+ lcb_U32 config_poll_interval;
136
+
131
137
  unsigned bc_http_urltype : 4;
132
138
 
133
139
  /** Don't guess next vbucket server. Mainly for testing */
@@ -148,6 +154,10 @@ typedef struct lcb_settings_st {
148
154
  unsigned ipv6 : 2;
149
155
  unsigned tcp_nodelay : 1;
150
156
  unsigned readj_ts_wait : 1;
157
+ unsigned use_errmap : 1;
158
+ unsigned select_bucket : 1;
159
+ unsigned tcp_keepalive : 1;
160
+ unsigned send_hello : 1;
151
161
 
152
162
  short max_redir;
153
163
  unsigned refcount;
@@ -165,6 +175,7 @@ typedef struct lcb_settings_st {
165
175
  void (*dtorcb)(const void *);
166
176
  void *dtorarg;
167
177
  char *client_string;
178
+ lcb_pERRMAP errmap;
168
179
  lcb_U32 retry_nmv_interval;
169
180
  } lcb_settings;
170
181
 
@@ -137,6 +137,7 @@ async_write(void *arg)
137
137
  {
138
138
  lcbio_CSSL *cs = arg;
139
139
  appdata_encode(cs);
140
+ schedule_wants(cs);
140
141
  appdata_free_flushed(cs);
141
142
  }
142
143
 
@@ -156,7 +156,9 @@ iotssl_log_errors(lcbio_XSSL *xs)
156
156
  if (ERR_GET_LIB(curerr) == ERR_LIB_SSL) {
157
157
  switch (ERR_GET_REASON(curerr)) {
158
158
  case SSL_R_CERTIFICATE_VERIFY_FAILED:
159
+ #ifdef SSL_R_MISSING_VERIFY_MESSAGE
159
160
  case SSL_R_MISSING_VERIFY_MESSAGE:
161
+ #endif
160
162
  xs->errcode = LCB_SSL_CANTVERIFY;
161
163
  break;
162
164
 
@@ -16,7 +16,6 @@
16
16
  */
17
17
 
18
18
  #include "ssl_iot_common.h"
19
- #include "simplestring.h"
20
19
  #include <openssl/err.h>
21
20
  /**
22
21
  * Event-Style SSL Wrapping.
@@ -105,7 +105,7 @@ bool urldecode(Ti first, Ti last, To out, size_t& nout) {
105
105
 
106
106
  inline bool
107
107
  urldecode(const char *input, char *output) {
108
- const char *endp = NULL;
108
+ const char *endp = input + strlen(input);
109
109
  size_t nout = 0;
110
110
  if (urldecode(input, endp, output, nout)) {
111
111
  output[nout] = '\0';
@@ -40,11 +40,11 @@
40
40
 
41
41
  #define TRACE_BEGIN_COMMON(TGT, req, cmd, ...) \
42
42
  TGT((req)->request.opaque, ntohs((req)->request.vbucket), (req)->request.opcode, \
43
- (cmd)->key.contig.bytes, (cmd)->key.contig.nbytes, ## __VA_ARGS__)
43
+ (const char *)((cmd)->key.contig.bytes), (cmd)->key.contig.nbytes, ## __VA_ARGS__)
44
44
 
45
45
  #define TRACE_BEGIN_SIMPLE(TGT, req, cmd) \
46
46
  TGT((req)->request.opaque, ntohs((req)->request.vbucket), (req)->request.opcode, \
47
- (cmd)->key.contig.bytes, (cmd)->key.contig.nbytes)
47
+ (const char *)(cmd)->key.contig.bytes, (cmd)->key.contig.nbytes)
48
48
 
49
49
  #define TRACE_END_COMMON(TGT, mcresp, resp, ...) \
50
50
  TGT(mcresp->opaque(), 0, mcresp->opcode(), (resp)->rc, (const char *)(resp)->key, (resp)->nkey, \
@@ -58,7 +58,7 @@
58
58
 
59
59
  #define TRACE_GET_END(mcresp, resp) \
60
60
  TRACE(TRACE_END_COMMON(LIBCOUCHBASE_GET_END, mcresp, resp, \
61
- (char*)(resp)->value, (resp)->nvalue, (resp)->itmflags, (resp)->cas, \
61
+ (const char*)(resp)->value, (resp)->nvalue, (resp)->itmflags, (resp)->cas, \
62
62
  mcresp->datatype()))
63
63
 
64
64
  #define TRACE_UNLOCK_BEGIN(req, cmd) TRACE(TRACE_BEGIN_SIMPLE(LIBCOUCHBASE_UNLOCK_BEGIN, req, cmd))
@@ -66,7 +66,7 @@
66
66
 
67
67
  #define TRACE_STORE_BEGIN(req, cmd) \
68
68
  TRACE(TRACE_BEGIN_COMMON(LIBCOUCHBASE_STORE_BEGIN, req, cmd, \
69
- ( (cmd)->value.vtype == LCB_KV_IOV ? NULL : (cmd)->value.u_buf.contig.bytes ),\
69
+ (const char *)( (cmd)->value.vtype == LCB_KV_IOV ? NULL : (cmd)->value.u_buf.contig.bytes ),\
70
70
  ( (cmd)->value.vtype == LCB_KV_IOV ? 0 : (cmd)->value.u_buf.contig.nbytes ),\
71
71
  (cmd)->flags, (cmd)->cas, (req)->request.datatype, (cmd)->exptime))
72
72
 
@@ -26,7 +26,6 @@
26
26
  #include "json-inl.h"
27
27
  #include "hash.h"
28
28
  #include "crc32.h"
29
- #include "simplestring.h"
30
29
 
31
30
  #define STRINGIFY_(X) #X
32
31
  #define STRINGIFY(X) STRINGIFY_(X)
@@ -1367,15 +1366,12 @@ lcbvb_genconfig_ex(lcbvb_CONFIG *vb,
1367
1366
  }
1368
1367
  }
1369
1368
 
1370
- if (!vb->ndatasrv) {
1371
- vb->errstr = "No data servers in list";
1372
- return -1;
1373
- }
1374
-
1375
- vb->vbuckets = malloc(vb->nvb * sizeof(*vb->vbuckets));
1376
- if (!vb->vbuckets) {
1377
- vb->errstr = "Couldn't allocate vbucket array";
1378
- return -1;
1369
+ if (vb->nvb) {
1370
+ vb->vbuckets = malloc(vb->nvb * sizeof(*vb->vbuckets));
1371
+ if (!vb->vbuckets) {
1372
+ vb->errstr = "Couldn't allocate vbucket array";
1373
+ return -1;
1374
+ }
1379
1375
  }
1380
1376
 
1381
1377
  for (ii = 0; ii < vb->nvb; ii++) {
@@ -2,56 +2,53 @@
2
2
  #include "internal.h"
3
3
  #include "sllist-inl.h"
4
4
 
5
+ using namespace lcb::docreq;
6
+
5
7
  static void docreq_handler(void *arg);
6
- static void invoke_pending(lcb_DOCQUEUE*);
8
+ static void invoke_pending(Queue*);
7
9
  static void doc_callback(lcb_t,int, const lcb_RESPBASE *);
8
10
 
9
11
  #define MAX_PENDING_DOCREQ 10
10
12
  #define MIN_SCHED_SIZE 5
11
13
  #define DOCQ_DELAY_US 200000
12
14
 
13
- #define DOCQ_REF(q) (q)->refcount++
14
- #define DOCQ_UNREF(q) if (!--(q)->refcount) { docq_free(q); }
15
-
16
- lcb_DOCQUEUE *
17
- lcbdocq_create(lcb_t instance)
18
- {
19
- lcb_DOCQUEUE *q = calloc(1, sizeof *q);
20
- q->timer = lcbio_timer_new(instance->iotable, q, docreq_handler);
21
- q->refcount = 1;
22
- q->instance = instance;
23
- q->max_pending_response = MAX_PENDING_DOCREQ;
24
- q->min_batch_size = MIN_SCHED_SIZE;
25
- return q;
15
+ Queue::Queue(lcb_t instance_)
16
+ : instance(instance_),
17
+ parent(NULL),
18
+ timer(lcbio_timer_new(instance->iotable, this, docreq_handler)),
19
+ cb_ready(NULL), cb_throttle(NULL),
20
+ n_awaiting_schedule(0),
21
+ n_awaiting_response(0),
22
+ max_pending_response(MAX_PENDING_DOCREQ),
23
+ min_batch_size(MIN_SCHED_SIZE),
24
+ cancelled(false),
25
+ refcount(1)
26
+ {
27
+
28
+ memset(&pending_gets, 0, sizeof pending_gets);
29
+ memset(&cb_queue, 0, sizeof cb_queue);
26
30
  }
27
31
 
28
- static void
29
- docq_free(lcb_DOCQUEUE *q)
30
- {
31
- lcbdocq_cancel(q);
32
- lcbio_timer_destroy(q->timer);
33
- free(q);
32
+ Queue::~Queue() {
33
+ cancel();
34
+ lcbio_timer_destroy(timer);
34
35
  }
35
36
 
36
- void
37
- lcbdocq_unref(lcb_DOCQUEUE *q)
38
- {
39
- DOCQ_UNREF(q);
37
+ void Queue::unref() {
38
+ if (!--refcount) {
39
+ delete this;
40
+ }
40
41
  }
41
42
 
42
- void
43
- lcbdocq_cancel(lcb_DOCQUEUE *q)
44
- {
45
- if (!q->cancelled) {
46
- q->cancelled = 1;
47
- }
43
+ void Queue::cancel() {
44
+ cancelled = true;
48
45
  }
49
46
 
50
47
  /* Calling this function ensures that the request will be scheduled in due
51
48
  * time. This may be done at the next event loop iteration, or after a delay
52
49
  * depending on how many items are actually found within the queue. */
53
50
  static void
54
- docq_poke(lcb_DOCQUEUE *q)
51
+ docq_poke(Queue *q)
55
52
  {
56
53
  if (q->n_awaiting_response < q->max_pending_response) {
57
54
  if (q->n_awaiting_schedule > q->min_batch_size) {
@@ -65,27 +62,26 @@ docq_poke(lcb_DOCQUEUE *q)
65
62
  }
66
63
  }
67
64
 
68
- void
69
- lcbdocq_add(lcb_DOCQUEUE *q, lcb_DOCQREQ *req)
65
+ void Queue::add(DocRequest *req)
70
66
  {
71
- sllist_append(&q->pending_gets, &req->slnode);
72
- q->n_awaiting_schedule++;
73
- req->parent = q;
67
+ sllist_append(&pending_gets, &req->slnode);
68
+ n_awaiting_schedule++;
69
+ req->parent = this;
74
70
  req->ready = 0;
75
- DOCQ_REF(q);
76
- docq_poke(q);
71
+ ref();
72
+ docq_poke(this);
77
73
  }
78
74
 
79
75
  static void
80
76
  docreq_handler(void *arg)
81
77
  {
82
- lcb_DOCQUEUE *q = arg;
78
+ Queue *q = reinterpret_cast<Queue*>(arg);
83
79
  sllist_iterator iter;
84
80
  lcb_t instance = q->instance;
85
81
 
86
82
  lcb_sched_enter(instance);
87
83
  SLLIST_ITERFOR(&q->pending_gets, &iter) {
88
- lcb_DOCQREQ *cont = SLLIST_ITEM(iter.cur, lcb_DOCQREQ, slnode);
84
+ DocRequest *cont = SLLIST_ITEM(iter.cur, DocRequest, slnode);
89
85
 
90
86
  if (q->n_awaiting_response > q->max_pending_response) {
91
87
  lcbio_timer_rearm(q->timer, DOCQ_DELAY_US);
@@ -136,13 +132,12 @@ docreq_handler(void *arg)
136
132
  /* Invokes the callback on all requests which are ready, until a request which
137
133
  * is not yet ready is reached. */
138
134
  static void
139
- invoke_pending(lcb_DOCQUEUE *q)
135
+ invoke_pending(Queue *q)
140
136
  {
141
137
  sllist_iterator iter = { NULL };
142
-
143
- DOCQ_REF(q);
138
+ q->ref();
144
139
  SLLIST_ITERFOR(&q->cb_queue, &iter) {
145
- lcb_DOCQREQ *dreq = SLLIST_ITEM(iter.cur, lcb_DOCQREQ, slnode);
140
+ DocRequest *dreq = SLLIST_ITEM(iter.cur, DocRequest, slnode);
146
141
  void *bufh = NULL;
147
142
 
148
143
  if (dreq->ready == 0) {
@@ -157,21 +152,21 @@ invoke_pending(lcb_DOCQUEUE *q)
157
152
 
158
153
  q->cb_ready(q, dreq);
159
154
  if (bufh) {
160
- lcb_backbuf_unref(bufh);
155
+ lcb_backbuf_unref(reinterpret_cast<lcb_BACKBUF>(bufh));
161
156
  }
162
- DOCQ_UNREF(q);
157
+ q->unref();
163
158
  }
164
- DOCQ_UNREF(q);
159
+ q->unref();
165
160
  }
166
161
 
167
162
  static void
168
- doc_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
163
+ doc_callback(lcb_t, int, const lcb_RESPBASE *rb)
169
164
  {
170
165
  const lcb_RESPGET *rg = (const lcb_RESPGET *)rb;
171
- lcb_DOCQREQ *dreq = rb->cookie;
172
- lcb_DOCQUEUE *q = dreq->parent;
166
+ DocRequest *dreq = reinterpret_cast<DocRequest*>(rb->cookie);
167
+ Queue *q = dreq->parent;
173
168
 
174
- DOCQ_REF(q);
169
+ q->ref();
175
170
 
176
171
  q->n_awaiting_response--;
177
172
  dreq->docresp = *rg;
@@ -182,13 +177,12 @@ doc_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
182
177
  /* Reference the response data, since we might not be invoking this right
183
178
  * away */
184
179
  if (rg->rc == LCB_SUCCESS) {
185
- lcb_backbuf_ref(dreq->docresp.bufh);
180
+ lcb_backbuf_ref(reinterpret_cast<lcb_BACKBUF>(dreq->docresp.bufh));
186
181
  }
187
182
 
188
183
  /* Ensure the invoke_pending doesn't destroy us */
189
184
  invoke_pending(q);
190
185
  docq_poke(q);
191
186
 
192
- DOCQ_UNREF(q);
193
- (void)instance; (void)cbtype;
187
+ q->unref();
194
188
  }