libcouchbase 1.2.8 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -4
  3. data/README.md +16 -8
  4. data/ext/libcouchbase/CMakeLists.txt +34 -32
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +277 -6
  6. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +14 -0
  7. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibevent.cmake +2 -0
  8. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibuv.cmake +2 -1
  9. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
  10. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +8 -1
  11. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  12. data/ext/libcouchbase/cmake/config-cmake.h.in +14 -0
  13. data/ext/libcouchbase/cmake/configure +8 -26
  14. data/ext/libcouchbase/cmake/defs.mk.in +2 -2
  15. data/ext/libcouchbase/cmake/libcouchbase.stp.in +829 -0
  16. data/ext/libcouchbase/cmake/source_files.cmake +11 -2
  17. data/ext/libcouchbase/contrib/cbsasl/CMakeLists.txt +18 -2
  18. data/ext/libcouchbase/contrib/cbsasl/include/cbsasl/cbsasl.h +44 -2
  19. data/ext/libcouchbase/contrib/cbsasl/src/client.c +285 -73
  20. data/ext/libcouchbase/contrib/cbsasl/src/common.c +4 -0
  21. data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.c +500 -0
  22. data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.h +99 -0
  23. data/ext/libcouchbase/contrib/cliopts/CMakeLists.txt +1 -1
  24. data/ext/libcouchbase/contrib/cliopts/cliopts.h +14 -1
  25. data/ext/libcouchbase/contrib/snappy/CMakeLists.txt +2 -3
  26. data/ext/libcouchbase/contrib/snappy/snappy-sinksource.cc +4 -0
  27. data/ext/libcouchbase/contrib/snappy/snappy-stubs-public.h +7 -5
  28. data/ext/libcouchbase/contrib/snappy/snappy.cc +7 -2
  29. data/ext/libcouchbase/example/crypto/.gitignore +2 -0
  30. data/ext/libcouchbase/example/crypto/Makefile +13 -0
  31. data/ext/libcouchbase/example/crypto/common_provider.c +24 -0
  32. data/ext/libcouchbase/example/crypto/common_provider.h +31 -0
  33. data/ext/libcouchbase/example/crypto/openssl_symmetric_decrypt.c +139 -0
  34. data/ext/libcouchbase/example/crypto/openssl_symmetric_encrypt.c +147 -0
  35. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.c +281 -0
  36. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.h +29 -0
  37. data/ext/libcouchbase/example/tracing/.gitignore +2 -0
  38. data/ext/libcouchbase/example/tracing/Makefile +8 -0
  39. data/ext/libcouchbase/example/tracing/cJSON.c +1 -0
  40. data/ext/libcouchbase/example/tracing/cJSON.h +1 -0
  41. data/ext/libcouchbase/example/tracing/tracing.c +439 -0
  42. data/ext/libcouchbase/example/tracing/views.c +444 -0
  43. data/ext/libcouchbase/include/libcouchbase/auth.h +56 -4
  44. data/ext/libcouchbase/include/libcouchbase/cbft.h +8 -0
  45. data/ext/libcouchbase/include/libcouchbase/cntl-private.h +55 -1
  46. data/ext/libcouchbase/include/libcouchbase/cntl.h +101 -1
  47. data/ext/libcouchbase/include/libcouchbase/configuration.h.in +6 -0
  48. data/ext/libcouchbase/include/libcouchbase/couchbase.h +109 -6
  49. data/ext/libcouchbase/include/libcouchbase/crypto.h +140 -0
  50. data/ext/libcouchbase/include/libcouchbase/error.h +38 -2
  51. data/ext/libcouchbase/include/libcouchbase/kvbuf.h +6 -1
  52. data/ext/libcouchbase/include/libcouchbase/metrics.h +79 -0
  53. data/ext/libcouchbase/include/libcouchbase/n1ql.h +9 -0
  54. data/ext/libcouchbase/include/libcouchbase/tracing.h +319 -0
  55. data/ext/libcouchbase/include/libcouchbase/vbucket.h +1 -1
  56. data/ext/libcouchbase/include/libcouchbase/views.h +8 -0
  57. data/ext/libcouchbase/include/memcached/protocol_binary.h +40 -10
  58. data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +6 -14
  59. data/ext/libcouchbase/plugins/io/libuv/plugin-internal.h +3 -0
  60. data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +1 -0
  61. data/ext/libcouchbase/plugins/io/select/plugin-select.c +4 -1
  62. data/ext/libcouchbase/src/auth-priv.h +36 -4
  63. data/ext/libcouchbase/src/auth.cc +66 -27
  64. data/ext/libcouchbase/src/bootstrap.cc +1 -1
  65. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +12 -7
  66. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +26 -17
  67. data/ext/libcouchbase/src/bucketconfig/bc_http.h +1 -1
  68. data/ext/libcouchbase/src/bucketconfig/clconfig.h +4 -2
  69. data/ext/libcouchbase/src/bucketconfig/confmon.cc +6 -3
  70. data/ext/libcouchbase/src/cbft.cc +48 -0
  71. data/ext/libcouchbase/src/cntl.cc +138 -2
  72. data/ext/libcouchbase/src/config_static.h +17 -0
  73. data/ext/libcouchbase/src/connspec.cc +54 -6
  74. data/ext/libcouchbase/src/connspec.h +9 -1
  75. data/ext/libcouchbase/src/crypto.cc +386 -0
  76. data/ext/libcouchbase/src/ctx-log-inl.h +23 -6
  77. data/ext/libcouchbase/src/dump.cc +4 -0
  78. data/ext/libcouchbase/src/getconfig.cc +1 -2
  79. data/ext/libcouchbase/src/handler.cc +65 -27
  80. data/ext/libcouchbase/src/hostlist.cc +35 -7
  81. data/ext/libcouchbase/src/hostlist.h +7 -0
  82. data/ext/libcouchbase/src/http/http-priv.h +2 -0
  83. data/ext/libcouchbase/src/http/http.cc +77 -37
  84. data/ext/libcouchbase/src/http/http_io.cc +19 -2
  85. data/ext/libcouchbase/src/instance.cc +90 -17
  86. data/ext/libcouchbase/src/internal.h +5 -0
  87. data/ext/libcouchbase/src/lcbio/connect.cc +39 -4
  88. data/ext/libcouchbase/src/lcbio/connect.h +27 -0
  89. data/ext/libcouchbase/src/lcbio/ctx.c +49 -23
  90. data/ext/libcouchbase/src/lcbio/ioutils.cc +30 -3
  91. data/ext/libcouchbase/src/lcbio/ioutils.h +2 -0
  92. data/ext/libcouchbase/src/lcbio/manager.cc +44 -8
  93. data/ext/libcouchbase/src/lcbio/manager.h +2 -0
  94. data/ext/libcouchbase/src/lcbio/rw-inl.h +1 -0
  95. data/ext/libcouchbase/src/lcbio/ssl.h +3 -5
  96. data/ext/libcouchbase/src/logging.c +1 -1
  97. data/ext/libcouchbase/src/logging.h +2 -0
  98. data/ext/libcouchbase/src/mc/compress.cc +164 -0
  99. data/ext/libcouchbase/src/mc/compress.h +7 -12
  100. data/ext/libcouchbase/src/mc/mcreq-flush-inl.h +5 -1
  101. data/ext/libcouchbase/src/mc/mcreq.c +11 -1
  102. data/ext/libcouchbase/src/mc/mcreq.h +35 -4
  103. data/ext/libcouchbase/src/mcserver/mcserver.cc +30 -7
  104. data/ext/libcouchbase/src/mcserver/mcserver.h +7 -0
  105. data/ext/libcouchbase/src/mcserver/negotiate.cc +103 -57
  106. data/ext/libcouchbase/src/mcserver/negotiate.h +2 -2
  107. data/ext/libcouchbase/src/mctx-helper.h +11 -0
  108. data/ext/libcouchbase/src/metrics.cc +132 -0
  109. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
  110. data/ext/libcouchbase/src/n1ql/n1ql.cc +66 -0
  111. data/ext/libcouchbase/src/newconfig.cc +9 -2
  112. data/ext/libcouchbase/src/operations/counter.cc +2 -1
  113. data/ext/libcouchbase/src/operations/durability-cas.cc +11 -0
  114. data/ext/libcouchbase/src/operations/durability-seqno.cc +3 -0
  115. data/ext/libcouchbase/src/operations/durability.cc +24 -2
  116. data/ext/libcouchbase/src/operations/durability_internal.h +19 -0
  117. data/ext/libcouchbase/src/operations/get.cc +4 -2
  118. data/ext/libcouchbase/src/operations/observe-seqno.cc +1 -0
  119. data/ext/libcouchbase/src/operations/observe.cc +113 -62
  120. data/ext/libcouchbase/src/operations/ping.cc +246 -67
  121. data/ext/libcouchbase/src/operations/remove.cc +2 -1
  122. data/ext/libcouchbase/src/operations/store.cc +17 -14
  123. data/ext/libcouchbase/src/operations/touch.cc +3 -0
  124. data/ext/libcouchbase/src/packetutils.h +68 -4
  125. data/ext/libcouchbase/src/probes.d +132 -161
  126. data/ext/libcouchbase/src/rdb/bigalloc.c +1 -1
  127. data/ext/libcouchbase/src/retryq.cc +6 -2
  128. data/ext/libcouchbase/src/rnd.cc +68 -0
  129. data/ext/libcouchbase/src/rnd.h +39 -0
  130. data/ext/libcouchbase/src/settings.c +27 -0
  131. data/ext/libcouchbase/src/settings.h +67 -3
  132. data/ext/libcouchbase/src/ssl/CMakeLists.txt +0 -12
  133. data/ext/libcouchbase/src/ssl/ssl_common.c +23 -4
  134. data/ext/libcouchbase/src/strcodecs/base64.c +141 -16
  135. data/ext/libcouchbase/src/strcodecs/strcodecs.h +16 -1
  136. data/ext/libcouchbase/src/trace.h +68 -61
  137. data/ext/libcouchbase/src/tracing/span.cc +289 -0
  138. data/ext/libcouchbase/src/tracing/threshold_logging_tracer.cc +171 -0
  139. data/ext/libcouchbase/src/tracing/tracer.cc +53 -0
  140. data/ext/libcouchbase/src/tracing/tracing-internal.h +213 -0
  141. data/ext/libcouchbase/src/utilities.c +5 -0
  142. data/ext/libcouchbase/src/vbucket/CMakeLists.txt +2 -2
  143. data/ext/libcouchbase/src/vbucket/vbucket.c +50 -18
  144. data/ext/libcouchbase/src/views/docreq.cc +26 -1
  145. data/ext/libcouchbase/src/views/docreq.h +17 -0
  146. data/ext/libcouchbase/src/views/viewreq.cc +64 -1
  147. data/ext/libcouchbase/src/views/viewreq.h +21 -0
  148. data/ext/libcouchbase/tests/CMakeLists.txt +6 -6
  149. data/ext/libcouchbase/tests/basic/t_base64.cc +34 -6
  150. data/ext/libcouchbase/tests/basic/t_connstr.cc +14 -0
  151. data/ext/libcouchbase/tests/basic/t_creds.cc +10 -10
  152. data/ext/libcouchbase/tests/basic/t_host.cc +22 -2
  153. data/ext/libcouchbase/tests/basic/t_scram.cc +514 -0
  154. data/ext/libcouchbase/tests/check-all.cc +6 -2
  155. data/ext/libcouchbase/tests/iotests/mock-environment.cc +64 -0
  156. data/ext/libcouchbase/tests/iotests/mock-environment.h +27 -1
  157. data/ext/libcouchbase/tests/iotests/t_confmon.cc +2 -2
  158. data/ext/libcouchbase/tests/iotests/t_forward.cc +8 -0
  159. data/ext/libcouchbase/tests/iotests/t_netfail.cc +124 -0
  160. data/ext/libcouchbase/tests/iotests/t_smoke.cc +1 -1
  161. data/ext/libcouchbase/tests/iotests/t_snappy.cc +316 -0
  162. data/ext/libcouchbase/tests/socktests/socktest.cc +2 -2
  163. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  164. data/ext/libcouchbase/tests/socktests/t_manager.cc +1 -1
  165. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  166. data/ext/libcouchbase/tools/CMakeLists.txt +1 -1
  167. data/ext/libcouchbase/tools/cbc-handlers.h +17 -0
  168. data/ext/libcouchbase/tools/cbc-n1qlback.cc +7 -4
  169. data/ext/libcouchbase/tools/cbc-pillowfight.cc +408 -100
  170. data/ext/libcouchbase/tools/cbc-proxy.cc +134 -3
  171. data/ext/libcouchbase/tools/cbc-subdoc.cc +1 -2
  172. data/ext/libcouchbase/tools/cbc.cc +113 -8
  173. data/ext/libcouchbase/tools/common/histogram.cc +1 -0
  174. data/ext/libcouchbase/tools/common/options.cc +28 -1
  175. data/ext/libcouchbase/tools/common/options.h +5 -0
  176. data/ext/libcouchbase/tools/docgen/docgen.h +36 -10
  177. data/ext/libcouchbase/tools/docgen/loc.h +5 -4
  178. data/ext/libcouchbase/tools/docgen/seqgen.h +28 -0
  179. data/lib/libcouchbase/ext/libcouchbase/enums.rb +10 -0
  180. data/lib/libcouchbase/n1ql.rb +6 -1
  181. data/lib/libcouchbase/version.rb +1 -1
  182. data/spec/connection_spec.rb +6 -6
  183. metadata +38 -5
  184. data/ext/libcouchbase/cmake/Modules/FindCouchbaseSnappy.cmake +0 -11
  185. data/ext/libcouchbase/src/mc/compress.c +0 -90
  186. data/ext/libcouchbase/tools/common/my_inttypes.h +0 -22
@@ -74,7 +74,8 @@ lcb_get3(lcb_t instance, const void *cookie, const lcb_CMDGET *cmd)
74
74
 
75
75
  memcpy(SPAN_BUFFER(&pkt->kh_span), gcmd.bytes, MCREQ_PKT_BASESIZE + extlen);
76
76
  LCB_SCHED_ADD(instance, pl, pkt);
77
- TRACE_GET_BEGIN(hdr, cmd);
77
+ LCBTRACE_KV_START(instance->settings, cmd, LCBTRACE_OP_GET, pkt->opaque, rdata->span);
78
+ TRACE_GET_BEGIN(instance, hdr, cmd);
78
79
 
79
80
  return LCB_SUCCESS;
80
81
  }
@@ -144,8 +145,9 @@ lcb_unlock3(lcb_t instance, const void *cookie, const lcb_CMDUNLOCK *cmd)
144
145
  hdr.request.cas = lcb_htonll(cmd->cas);
145
146
 
146
147
  memcpy(SPAN_BUFFER(&pkt->kh_span), hdr.bytes, sizeof(hdr.bytes));
147
- TRACE_UNLOCK_BEGIN(&hdr, cmd);
148
148
  LCB_SCHED_ADD(instance, pl, pkt);
149
+ LCBTRACE_KV_START(instance->settings, cmd, LCBTRACE_OP_UNLOCK, pkt->opaque, rd->span);
150
+ TRACE_UNLOCK_BEGIN(instance, &hdr, cmd);
149
151
  return LCB_SUCCESS;
150
152
  }
151
153
 
@@ -50,6 +50,7 @@ lcb_observe_seqno3(lcb_t instance, const void *cookie, const lcb_CMDOBSEQNO *cmd
50
50
  uuid = lcb_htonll(cmd->uuid);
51
51
  memcpy(SPAN_BUFFER(&pkt->u_value.single), &uuid, sizeof uuid);
52
52
  LCB_SCHED_ADD(instance, server, pkt);
53
+ LCBTRACE_KV_START(instance->settings, cmd, LCBTRACE_OP_OBSERVE_SEQNO, pkt->opaque, MCREQ_PKT_RDATA(pkt)->span);
53
54
  return LCB_SUCCESS;
54
55
  }
55
56
 
@@ -19,50 +19,61 @@
19
19
  #include "durability_internal.h"
20
20
  #include "trace.h"
21
21
  #include "mctx-helper.h"
22
+ #include "sllist-inl.h"
22
23
 
23
- struct ObserveCtx : mc_REQDATAEX, lcb::MultiCmdContext {
24
- void clear_requests() { requests.clear(); }
24
+ struct ObserveCtx : lcb::MultiCmdContext {
25
+ void clear_requests()
26
+ {
27
+ requests.clear();
28
+ num_requests.clear();
29
+ }
25
30
  ObserveCtx(lcb_t instance_);
26
31
 
27
32
  // Overrides
28
- lcb_error_t MCTX_addcmd(const lcb_CMDBASE*);
33
+ lcb_error_t MCTX_addcmd(const lcb_CMDBASE *);
29
34
  lcb_error_t MCTX_done(const void *);
30
35
  void MCTX_fail();
36
+ #ifdef LCB_TRACING
37
+ void MCTX_setspan(lcbtrace_SPAN *span);
38
+ #endif
31
39
 
32
40
  lcb_t instance;
33
41
  size_t remaining;
34
42
  unsigned oflags;
35
43
 
36
- typedef std::vector<uint8_t> ServerBuf;
44
+ typedef std::vector< uint8_t > ServerBuf;
37
45
  /* requests array contains one buffer per server. nrequest essentially
38
46
  * says how many elements (and thus how many servers) */
39
- std::vector<ServerBuf> requests;
47
+ std::vector< ServerBuf > requests;
48
+ std::vector< size_t > num_requests;
49
+ #ifdef LCB_TRACING
50
+ lcbtrace_SPAN *span;
51
+ #endif
52
+ };
53
+
54
+ struct OperationCtx : mc_REQDATAEX {
55
+ OperationCtx(ObserveCtx *parent_, size_t remaining_);
56
+
57
+ ObserveCtx *parent;
58
+ size_t remaining;
40
59
  };
41
60
 
42
- typedef enum {
43
- F_DURABILITY = 0x01,
44
- F_DESTROY = 0x02,
45
- F_SCHEDFAILED = 0x04
46
- } obs_flags;
61
+ typedef enum { F_DURABILITY = 0x01, F_DESTROY = 0x02, F_SCHEDFAILED = 0x04 } obs_flags;
47
62
 
48
63
  // TODO: Move this to a common file
49
- template <typename ContainerType, typename ValueType>
50
- void add_to_buf(ContainerType& c, ValueType v) {
51
- typename ContainerType::value_type *p =
52
- reinterpret_cast<typename ContainerType::value_type*>(&v);
64
+ template < typename ContainerType, typename ValueType > void add_to_buf(ContainerType &c, ValueType v)
65
+ {
66
+ typename ContainerType::value_type *p = reinterpret_cast< typename ContainerType::value_type * >(&v);
53
67
  c.insert(c.end(), p, p + sizeof(ValueType));
54
68
  }
55
69
 
56
- static void
57
- handle_observe_callback(mc_PIPELINE *pl,
58
- mc_PACKET *pkt, lcb_error_t err, const void *arg)
70
+ static void handle_observe_callback(mc_PIPELINE *pl, mc_PACKET *pkt, lcb_error_t err, const void *arg)
59
71
  {
60
- ObserveCtx *oc = static_cast<ObserveCtx*>(pkt->u_rdata.exdata);
61
- lcb_RESPOBSERVE *resp = reinterpret_cast<lcb_RESPOBSERVE*>(const_cast<void*>(arg));
72
+ OperationCtx *opc = static_cast< OperationCtx * >(pkt->u_rdata.exdata);
73
+ ObserveCtx *oc = opc->parent;
74
+ lcb_RESPOBSERVE *resp = reinterpret_cast< lcb_RESPOBSERVE * >(const_cast< void * >(arg));
62
75
  lcb_t instance = oc->instance;
63
76
 
64
- (void)pl;
65
-
66
77
  if (resp == NULL) {
67
78
  int nfailed = 0;
68
79
  /** We need to fail the request manually.. */
@@ -70,7 +81,7 @@ handle_observe_callback(mc_PIPELINE *pl,
70
81
  const char *end = ptr + pkt->u_value.single.size;
71
82
  while (ptr < end) {
72
83
  lcb_uint16_t nkey;
73
- lcb_RESPOBSERVE cur = { 0 };
84
+ lcb_RESPOBSERVE cur = {0};
74
85
  cur.rflags = LCB_RESP_F_CLIENTGEN;
75
86
 
76
87
  ptr += 2;
@@ -81,7 +92,7 @@ handle_observe_callback(mc_PIPELINE *pl,
81
92
  memset(&cur, 0, sizeof(cur));
82
93
  cur.key = ptr;
83
94
  cur.nkey = nkey;
84
- cur.cookie = (void *)oc->cookie;
95
+ cur.cookie = (void *)opc->cookie;
85
96
  cur.rc = err;
86
97
  handle_observe_callback(NULL, pkt, err, &cur);
87
98
  ptr += nkey;
@@ -91,11 +102,18 @@ handle_observe_callback(mc_PIPELINE *pl,
91
102
  return;
92
103
  }
93
104
 
94
- resp->cookie = (void *)oc->cookie;
105
+ resp->cookie = (void *)opc->cookie;
95
106
  resp->rc = err;
107
+ oc->remaining--;
108
+ #ifdef LCB_TRACING
109
+ if (oc->remaining == 0 && oc->span) {
110
+ lcbtrace_span_finish(oc->span, LCBTRACE_NOW);
111
+ oc->span = NULL;
112
+ }
113
+ #endif
96
114
  if (oc->oflags & F_DURABILITY) {
97
115
  resp->ttp = pl ? pl->index : -1;
98
- lcbdur_cas_update(instance, (void*)MCREQ_PKT_COOKIE(pkt), err, resp);
116
+ lcbdur_cas_update(instance, (void *)MCREQ_PKT_COOKIE(pkt), err, resp);
99
117
 
100
118
  } else if ((oc->oflags & F_SCHEDFAILED) == 0) {
101
119
  lcb_RESPCALLBACK callback = lcb_find_callback(instance, LCB_CALLBACK_OBSERVE);
@@ -105,27 +123,35 @@ handle_observe_callback(mc_PIPELINE *pl,
105
123
  if (oc->oflags & F_DESTROY) {
106
124
  return;
107
125
  }
108
-
109
- if (--oc->remaining) {
110
- return;
111
- } else {
112
- lcb_RESPOBSERVE resp2 = { 0 };
126
+ if (oc->remaining == 0) {
127
+ lcb_RESPOBSERVE resp2 = {0};
113
128
  resp2.rc = err;
114
- resp2.rflags = LCB_RESP_F_CLIENTGEN|LCB_RESP_F_FINAL;
129
+ resp2.rflags = LCB_RESP_F_CLIENTGEN | LCB_RESP_F_FINAL;
115
130
  oc->oflags |= F_DESTROY;
116
131
  handle_observe_callback(NULL, pkt, err, &resp2);
117
132
  delete oc;
118
133
  }
134
+ opc->remaining--;
135
+ if (opc->remaining == 0) {
136
+ delete opc;
137
+ }
119
138
  }
120
139
 
121
- static void
122
- handle_schedfail(mc_PACKET *pkt)
140
+ static void handle_schedfail(mc_PACKET *pkt)
123
141
  {
124
- ObserveCtx *oc = static_cast<ObserveCtx*>(pkt->u_rdata.exdata);
142
+ OperationCtx *opc = static_cast< OperationCtx * >(pkt->u_rdata.exdata);
143
+ ObserveCtx *oc = opc->parent;
125
144
  oc->oflags |= F_SCHEDFAILED;
126
145
  handle_observe_callback(NULL, pkt, LCB_SCHEDFAIL_INTERNAL, NULL);
127
146
  }
128
147
 
148
+ #ifdef LCB_TRACING
149
+ void ObserveCtx::MCTX_setspan(lcbtrace_SPAN *span_)
150
+ {
151
+ span = span_;
152
+ }
153
+ #endif
154
+
129
155
  lcb_error_t ObserveCtx::MCTX_addcmd(const lcb_CMDBASE *cmdbase)
130
156
  {
131
157
  int vbid, srvix_dummy;
@@ -182,22 +208,18 @@ lcb_error_t ObserveCtx::MCTX_addcmd(const lcb_CMDBASE *cmdbase)
182
208
 
183
209
  lcb_assert(ix < requests.size());
184
210
 
185
- ServerBuf& rr = requests[ix];
211
+ ServerBuf &rr = requests[ix];
186
212
  add_to_buf(rr, uint16_t(htons(vbid)));
187
213
  add_to_buf(rr, uint16_t(htons(cmd->key.contig.nbytes)));
188
- rr.insert(rr.end(),
189
- reinterpret_cast<const uint8_t*>(cmd->key.contig.bytes),
190
- reinterpret_cast<const uint8_t*>(cmd->key.contig.bytes) +
191
- cmd->key.contig.nbytes);
214
+ rr.insert(rr.end(), reinterpret_cast< const uint8_t * >(cmd->key.contig.bytes),
215
+ reinterpret_cast< const uint8_t * >(cmd->key.contig.bytes) + cmd->key.contig.nbytes);
192
216
  remaining++;
217
+ num_requests[ii]++;
193
218
  }
194
219
  return LCB_SUCCESS;
195
220
  }
196
221
 
197
- static mc_REQDATAPROCS obs_procs = {
198
- handle_observe_callback,
199
- handle_schedfail
200
- };
222
+ static mc_REQDATAPROCS obs_procs = {handle_observe_callback, handle_schedfail};
201
223
 
202
224
  lcb_error_t ObserveCtx::MCTX_done(const void *cookie_)
203
225
  {
@@ -208,7 +230,7 @@ lcb_error_t ObserveCtx::MCTX_done(const void *cookie_)
208
230
  protocol_binary_request_header hdr;
209
231
  mc_PACKET *pkt;
210
232
  mc_PIPELINE *pipeline;
211
- ServerBuf& rr = requests[ii];
233
+ ServerBuf &rr = requests[ii];
212
234
  pipeline = cq->pipelines[ii];
213
235
 
214
236
  if (rr.empty()) {
@@ -234,15 +256,30 @@ lcb_error_t ObserveCtx::MCTX_done(const void *cookie_)
234
256
  memcpy(SPAN_BUFFER(&pkt->kh_span), hdr.bytes, sizeof(hdr.bytes));
235
257
  memcpy(SPAN_BUFFER(&pkt->u_value.single), &rr[0], rr.size());
236
258
 
259
+ OperationCtx *ctx = new OperationCtx(this, this->num_requests[ii]);
260
+ ctx->start = gethrtime();
261
+ ctx->cookie = cookie_;
262
+
237
263
  pkt->flags |= MCREQ_F_REQEXT;
238
- pkt->u_rdata.exdata = this;
264
+ pkt->u_rdata.exdata = ctx;
265
+ #ifdef LCB_TRACING
266
+ if (instance->settings->tracer) {
267
+ lcbtrace_REF ref;
268
+ char opid[20] = {};
269
+ snprintf(opid, sizeof(opid), "0x%x", (int)pkt->opaque);
270
+ ref.type = LCBTRACE_REF_CHILD_OF;
271
+ ref.span = span;
272
+ MCREQ_PKT_RDATA(pkt)->span =
273
+ lcbtrace_span_start(instance->settings->tracer, LCBTRACE_OP_OBSERVE_CAS, LCBTRACE_NOW, &ref);
274
+ lcbtrace_span_add_tag_str(MCREQ_PKT_RDATA(pkt)->span, LCBTRACE_TAG_OPERATION_ID, opid);
275
+ lcbtrace_span_add_system_tags(MCREQ_PKT_RDATA(pkt)->span, instance->settings, LCBTRACE_TAG_SERVICE_KV);
276
+ }
277
+ #endif
278
+
239
279
  mcreq_sched_add(pipeline, pkt);
240
- TRACE_OBSERVE_BEGIN(&hdr, SPAN_BUFFER(&pkt->u_value.single));
280
+ TRACE_OBSERVE_BEGIN(instance, &hdr, SPAN_BUFFER(&pkt->u_value.single));
241
281
  }
242
282
 
243
- start = gethrtime();
244
- cookie = cookie_;
245
-
246
283
  if (requests.size() == 0 || remaining == 0) {
247
284
  delete this;
248
285
  return LCB_EINVAL;
@@ -252,35 +289,49 @@ lcb_error_t ObserveCtx::MCTX_done(const void *cookie_)
252
289
  }
253
290
  }
254
291
 
255
- void ObserveCtx::MCTX_fail() {
292
+ void ObserveCtx::MCTX_fail()
293
+ {
294
+ #ifdef LCB_TRACING
295
+ if (span) {
296
+ lcbtrace_span_finish(span, LCBTRACE_NOW);
297
+ span = NULL;
298
+ }
299
+ #endif
256
300
  delete this;
257
301
  }
258
302
 
259
303
  ObserveCtx::ObserveCtx(lcb_t instance_)
260
- : mc_REQDATAEX(NULL, obs_procs, 0),
261
- instance(instance_),
262
- remaining(0),
263
- oflags(0) {
264
-
304
+ : instance(instance_), remaining(0), oflags(0)
305
+ #ifdef LCB_TRACING
306
+ ,
307
+ span(NULL)
308
+ #endif
309
+ {
265
310
  requests.resize(LCBT_NSERVERS(instance));
311
+ num_requests.resize(requests.size());
312
+ }
313
+
314
+ OperationCtx::OperationCtx(ObserveCtx *parent_, size_t remaining_)
315
+ : mc_REQDATAEX(NULL, obs_procs, 0), parent(parent_), remaining(remaining_)
316
+ {
266
317
  }
267
318
 
268
319
  LIBCOUCHBASE_API
269
- lcb_MULTICMD_CTX * lcb_observe3_ctxnew(lcb_t instance) {
320
+ lcb_MULTICMD_CTX *lcb_observe3_ctxnew(lcb_t instance)
321
+ {
270
322
  return new ObserveCtx(instance);
271
323
  }
272
324
 
273
- lcb_MULTICMD_CTX *
274
- lcb_observe_ctx_dur_new(lcb_t instance) {
325
+ lcb_MULTICMD_CTX *lcb_observe_ctx_dur_new(lcb_t instance)
326
+ {
275
327
  ObserveCtx *ctx = new ObserveCtx(instance);
276
328
  ctx->oflags |= F_DURABILITY;
277
329
  return ctx;
278
330
  }
279
331
 
280
332
  LIBCOUCHBASE_API
281
- lcb_error_t lcb_observe(lcb_t instance,
282
- const void *command_cookie, lcb_size_t num,
283
- const lcb_observe_cmd_t *const *items)
333
+ lcb_error_t lcb_observe(lcb_t instance, const void *command_cookie, lcb_size_t num,
334
+ const lcb_observe_cmd_t *const *items)
284
335
  {
285
336
  unsigned ii;
286
337
  lcb_error_t err;
@@ -294,7 +345,7 @@ lcb_error_t lcb_observe(lcb_t instance,
294
345
  }
295
346
 
296
347
  for (ii = 0; ii < num; ii++) {
297
- lcb_CMDOBSERVE cmd = { 0 };
348
+ lcb_CMDOBSERVE cmd = {0};
298
349
  const lcb_observe_cmd_t *src = items[ii];
299
350
  if (src->version == 1 && (src->v.v1.options & LCB_OBSERVE_MASTER_ONLY)) {
300
351
  cmd.cmdflags |= LCB_CMDOBSERVE_F_MASTER_ONLY;
@@ -32,6 +32,7 @@ struct PingCookie : mc_REQDATAEX {
32
32
  int remaining;
33
33
  int options;
34
34
  std::list<lcb_PINGSVC> responses;
35
+ std::string id;
35
36
 
36
37
  PingCookie(const void *cookie_, int _options)
37
38
  : mc_REQDATAEX(cookie_, ping_procs, gethrtime()),
@@ -41,8 +42,12 @@ struct PingCookie : mc_REQDATAEX {
41
42
  ~PingCookie() {
42
43
  for (std::list<lcb_PINGSVC>::iterator it = responses.begin(); it != responses.end(); it++) {
43
44
  if (it->server) {
44
- free(it->server);
45
+ free((void *)it->server);
45
46
  it->server = NULL;
47
+ free((void *)it->local);
48
+ it->local = NULL;
49
+ free((void *)it->id);
50
+ it->id = NULL;
46
51
  }
47
52
  }
48
53
  }
@@ -73,23 +78,6 @@ refcnt_dtor_ping(mc_PACKET *pkt)
73
78
  }
74
79
  }
75
80
 
76
- static std::string latency_to_string(lcb_U64 latency)
77
- {
78
- std::stringstream ss;
79
- ss.precision(3);
80
- ss.setf(std::ios::fixed);
81
- if (latency < 1000) {
82
- ss << latency << "ns";
83
- } else if (latency < LCB_US2NS(1000)) {
84
- ss << (latency / (double)LCB_US2NS(1)) << "us";
85
- } else if (latency < LCB_MS2NS(1000)) {
86
- ss << (latency / (double)LCB_MS2NS(1)) << "ms";
87
- } else {
88
- ss << (latency / (double)LCB_S2NS(1)) << "s";
89
- }
90
- return ss.str();
91
- }
92
-
93
81
  static const char* svc_to_string(lcb_PINGSVCTYPE type)
94
82
  {
95
83
  switch (type) {
@@ -107,21 +95,55 @@ static const char* svc_to_string(lcb_PINGSVCTYPE type)
107
95
  }
108
96
 
109
97
  static void
110
- build_ping_json(lcb_RESPPING &ping, Json::Value &root, bool details)
98
+ build_ping_json(lcb_t instance, lcb_RESPPING &ping, Json::Value &root, PingCookie *ck)
111
99
  {
112
100
  Json::Value services;
113
101
  for (size_t ii = 0; ii < ping.nservices; ii++) {
114
102
  lcb_PINGSVC &svc = ping.services[ii];
115
103
  Json::Value service;
116
- service["server"] = svc.server;
117
- service["latency"] = latency_to_string(svc.latency);
118
- service["status"] = svc.status;
119
- if (details) {
120
- service["details"] = lcb_strerror(NULL, svc.status);
104
+ service["remote"] = svc.server;
105
+ if (svc.local) {
106
+ service["local"] = svc.local;
107
+ }
108
+ if (svc.id) {
109
+ service["id"] = svc.id;
110
+ }
111
+ if (svc.scope) {
112
+ service["scope"] = svc.scope;
113
+ }
114
+
115
+ service["latency_us"] = (Json::Value::UInt64)LCB_NS2US(svc.latency);
116
+ switch (svc.status) {
117
+ case LCB_PINGSTATUS_OK:
118
+ service["status"] = "ok";
119
+ break;
120
+ case LCB_PINGSTATUS_TIMEOUT:
121
+ service["status"] = "timeout";
122
+ break;
123
+ default:
124
+ service["status"] = "error";
125
+ if (ck->needDetails()) {
126
+ service["details"] = lcb_strerror_long(svc.rc);
127
+ }
121
128
  }
122
129
  services[svc_to_string(svc.type)].append(service);
123
130
  }
124
131
  root["services"] = services;
132
+ root["version"] = 1;
133
+
134
+ std::string sdk("libcouchbase/" LCB_VERSION_STRING);
135
+ if (LCBT_SETTING(instance, client_string)) {
136
+ sdk.append(" ").append(LCBT_SETTING(instance, client_string));
137
+ }
138
+ root["sdk"] = sdk.c_str();
139
+ root["id"] = ck->id;
140
+
141
+ int config_rev = -1;
142
+ if (instance->cur_configinfo) {
143
+ lcb::clconfig::ConfigInfo *cfg = instance->cur_configinfo;
144
+ config_rev = cfg->vbc->revid;
145
+ }
146
+ root["config_rev"] = config_rev;
125
147
  }
126
148
 
127
149
  static void
@@ -139,7 +161,7 @@ invoke_ping_callback(lcb_t instance, PingCookie *ck)
139
161
  }
140
162
  if (ck->needJSON()) {
141
163
  Json::Value root;
142
- build_ping_json(ping, root, ck->needDetails());
164
+ build_ping_json(instance, ping, root, ck);
143
165
  Json::Writer *w;
144
166
  if (ck->needPretty()) {
145
167
  w = new Json::StyledWriter();
@@ -169,15 +191,38 @@ handle_ping(mc_PIPELINE *pipeline, mc_PACKET *req, lcb_error_t err, const void *
169
191
  PingCookie *ck = (PingCookie *)req->u_rdata.exdata;
170
192
 
171
193
  if (ck->needMetrics()) {
172
- std::string hh(server->get_host().host);
173
- hh.append(":");
174
- hh.append(server->get_host().port);
175
-
176
- lcb_PINGSVC svc;
194
+ const lcb_host_t &remote = server->get_host();
195
+ std::string hh;
196
+ if (remote.ipv6) {
197
+ hh.append("[").append(remote.host).append("]:").append(remote.port);
198
+ } else {
199
+ hh.append(remote.host).append(":").append(remote.port);
200
+ }
201
+ lcb_PINGSVC svc = {};
177
202
  svc.type = LCB_PINGSVC_KV;
178
203
  svc.server = strdup(hh.c_str());
179
204
  svc.latency = gethrtime() - MCREQ_PKT_RDATA(req)->start;
180
- svc.status = err;
205
+ svc.rc = err;
206
+ switch (err) {
207
+ case LCB_ETIMEDOUT:
208
+ svc.status = LCB_PINGSTATUS_TIMEOUT;
209
+ break;
210
+ case LCB_SUCCESS:
211
+ svc.status = LCB_PINGSTATUS_OK;
212
+ break;
213
+ default:
214
+ svc.status = LCB_PINGSTATUS_ERROR;
215
+ break;
216
+ }
217
+ lcbio_CTX *ctx = server->connctx;
218
+ if (ctx) {
219
+ char id[20] = {0};
220
+ svc.local = strdup(lcbio__inet_ntop(&ctx->sock->info->sa_local).c_str());
221
+ snprintf(id, sizeof(id), "%p", (void *)ctx->sock);
222
+ svc.id = strdup(id);
223
+ }
224
+ svc.scope = server->get_instance()->get_bucketname();
225
+
181
226
  ck->responses.push_back(svc);
182
227
  }
183
228
 
@@ -196,11 +241,35 @@ static void handle_http(lcb_t instance, lcb_PINGSVCTYPE type, const lcb_RESPHTTP
196
241
  lcb::http::Request *htreq = reinterpret_cast<lcb::http::Request*>(resp->_htreq);
197
242
 
198
243
  if (ck->needMetrics()) {
199
- lcb_PINGSVC svc;
244
+ lcb_PINGSVC svc = {};
200
245
  svc.type = type;
201
- svc.server = strdup((htreq->host + ":" + htreq->port).c_str());
246
+ std::string hh;
247
+ if (htreq->ipv6) {
248
+ hh = "[" + std::string(htreq->host) + "]:" + std::string(htreq->port);
249
+ } else {
250
+ hh = std::string(htreq->host) + ":" + std::string(htreq->port);
251
+ }
252
+ svc.server = strdup(hh.c_str());
202
253
  svc.latency = gethrtime() - htreq->start;
203
- svc.status = resp->rc;
254
+ svc.rc = resp->rc;
255
+ switch (resp->rc) {
256
+ case LCB_ETIMEDOUT:
257
+ svc.status = LCB_PINGSTATUS_TIMEOUT;
258
+ break;
259
+ case LCB_SUCCESS:
260
+ svc.status = LCB_PINGSTATUS_OK;
261
+ break;
262
+ default:
263
+ svc.status = LCB_PINGSTATUS_ERROR;
264
+ break;
265
+ }
266
+ lcbio_CTX *ctx = htreq->ioctx;
267
+ if (ctx) {
268
+ char id[20] = {0};
269
+ snprintf(id, sizeof(id), "%p", (void *)ctx->sock);
270
+ svc.id = strdup(id);
271
+ svc.local = strdup(lcbio__inet_ntop(&ctx->sock->info->sa_local).c_str());
272
+ }
204
273
  ck->responses.push_back(svc);
205
274
  }
206
275
  if (--ck->remaining) {
@@ -236,9 +305,25 @@ lcb_ping3(lcb_t instance, const void *cookie, const lcb_CMDPING *cmd)
236
305
  }
237
306
 
238
307
  PingCookie *ckwrap = new PingCookie(cookie, cmd->options);
308
+ {
309
+ char id[20] = {0};
310
+ snprintf(id, sizeof(id), "%p", (void *)instance);
311
+ ckwrap->id = id;
312
+ if (cmd->id) {
313
+ ckwrap->id.append("/").append(cmd->id);
314
+ }
315
+ }
239
316
 
317
+ lcbvb_CONFIG *cfg = LCBT_VBCONFIG(instance);
318
+ const lcbvb_SVCMODE mode = LCBT_SETTING(instance, sslopts) ?
319
+ LCBVB_SVCMODE_SSL : LCBVB_SVCMODE_PLAIN;
240
320
  if (cmd->services & LCB_PINGSVC_F_KV) {
241
321
  for (ii = 0; ii < cq->npipelines; ii++) {
322
+ unsigned port = lcbvb_get_port(cfg, ii, LCBVB_SVCTYPE_DATA, mode);
323
+ if (!port) {
324
+ continue;
325
+ }
326
+
242
327
  mc_PIPELINE *pl = cq->pipelines[ii];
243
328
  mc_PACKET *pkt = mcreq_allocate_packet(pl);
244
329
  protocol_binary_request_header hdr;
@@ -262,46 +347,43 @@ lcb_ping3(lcb_t instance, const void *cookie, const lcb_CMDPING *cmd)
262
347
  }
263
348
  }
264
349
 
265
- lcbvb_CONFIG *cfg = LCBT_VBCONFIG(instance);
266
- const lcbvb_SVCMODE mode = LCBT_SETTING(instance, sslopts) ?
267
- LCBVB_SVCMODE_SSL : LCBVB_SVCMODE_PLAIN;
268
350
  for (int idx = 0; idx < (int)LCBVB_NSERVERS(cfg); idx++) {
269
- #define PING_HTTP(SVC, QUERY, TMO, CB) \
270
- do { \
271
- lcb_error_t rc; \
272
- struct lcb_http_request_st *htreq; \
273
- lcb_CMDHTTP htcmd = {0}; \
274
- htcmd.host = lcbvb_get_resturl(cfg, idx, SVC, mode); \
275
- if (htcmd.host == NULL) { \
276
- continue; \
277
- } \
278
- htcmd.body = QUERY; \
279
- htcmd.nbody = strlen(htcmd.body); \
280
- htcmd.content_type = "application/json"; \
281
- htcmd.method = LCB_HTTP_METHOD_POST; \
282
- htcmd.type = LCB_HTTP_TYPE_RAW; \
283
- htcmd.reqhandle = &htreq; \
284
- const lcb::Authenticator& auth = *instance->settings->auth; \
285
- htcmd.username = auth.username_for(LCBT_SETTING(instance, bucket)).c_str(); \
286
- htcmd.password = auth.password_for(LCBT_SETTING(instance, bucket)).c_str(); \
287
- htcmd.cmdflags = LCB_CMDHTTP_F_CASTMO; \
288
- htcmd.cas = LCBT_SETTING(instance, TMO); \
289
- rc = lcb_http3(instance, ckwrap, &htcmd); \
290
- if (rc == LCB_SUCCESS) { \
291
- htreq->set_callback(CB); \
292
- } \
293
- ckwrap->remaining++; \
294
- } while (0);
351
+ #define PING_HTTP(SVC, PATH, TMO, CB) \
352
+ lcb_error_t rc; \
353
+ struct lcb_http_request_st *htreq; \
354
+ lcb_CMDHTTP htcmd = {0}; \
355
+ char buf[1024] = {0}; \
356
+ unsigned port; \
357
+ port = lcbvb_get_port(cfg, idx, SVC, mode); \
358
+ if (port) { \
359
+ lcbvb_SERVER *srv = LCBVB_GET_SERVER(cfg, idx); \
360
+ bool ipv6 = strchr(srv->hostname, ':'); \
361
+ snprintf(buf, sizeof(buf), "%s://%s%s%s:%d%s", (mode == LCBVB_SVCMODE_PLAIN) ? "http" : "https", \
362
+ ipv6 ? "[" : "", srv->hostname, ipv6 ? "]" : "", port, PATH); \
363
+ htcmd.host = buf; \
364
+ htcmd.method = LCB_HTTP_METHOD_GET; \
365
+ htcmd.type = LCB_HTTP_TYPE_RAW; \
366
+ htcmd.reqhandle = &htreq; \
367
+ const lcb::Authenticator& auth = *instance->settings->auth; \
368
+ htcmd.username = auth.username_for(NULL, NULL, LCBT_SETTING(instance, bucket)).c_str(); \
369
+ htcmd.password = auth.password_for(NULL, NULL, LCBT_SETTING(instance, bucket)).c_str(); \
370
+ htcmd.cmdflags = LCB_CMDHTTP_F_CASTMO; \
371
+ htcmd.cas = LCBT_SETTING(instance, TMO); \
372
+ rc = lcb_http3(instance, ckwrap, &htcmd); \
373
+ if (rc == LCB_SUCCESS) { \
374
+ htreq->set_callback(CB); \
375
+ ckwrap->remaining++; \
376
+ } \
377
+ }
295
378
 
296
379
  if (cmd->services & LCB_PINGSVC_F_N1QL) {
297
- PING_HTTP(LCBVB_SVCTYPE_N1QL, "{\"statement\":\"select 1\"}",
298
- n1ql_timeout, handle_n1ql);
380
+ PING_HTTP(LCBVB_SVCTYPE_N1QL, "/admin/ping", n1ql_timeout, handle_n1ql);
299
381
  }
300
382
  if (cmd->services & LCB_PINGSVC_F_VIEWS) {
301
- PING_HTTP(LCBVB_SVCTYPE_VIEWS, "", views_timeout, handle_views);
383
+ PING_HTTP(LCBVB_SVCTYPE_VIEWS, "/", views_timeout, handle_views);
302
384
  }
303
385
  if (cmd->services & LCB_PINGSVC_F_FTS) {
304
- PING_HTTP(LCBVB_SVCTYPE_FTS, "", n1ql_timeout, handle_fts);
386
+ PING_HTTP(LCBVB_SVCTYPE_FTS, "/api/ping", http_timeout, handle_fts);
305
387
  }
306
388
  #undef PING_HTTP
307
389
  }
@@ -313,3 +395,100 @@ lcb_ping3(lcb_t instance, const void *cookie, const lcb_CMDPING *cmd)
313
395
  MAYBE_SCHEDLEAVE(instance);
314
396
  return LCB_SUCCESS;
315
397
  }
398
+
399
+
400
+ LIBCOUCHBASE_API
401
+ lcb_error_t
402
+ lcb_diag(lcb_t instance, const void *cookie, const lcb_CMDDIAG *cmd)
403
+ {
404
+ Json::Value root;
405
+ hrtime_t now = LCB_NS2US(gethrtime());
406
+
407
+ root["version"] = 1;
408
+
409
+ std::string sdk("libcouchbase/" LCB_VERSION_STRING);
410
+ if (LCBT_SETTING(instance, client_string)) {
411
+ sdk.append(" ").append(LCBT_SETTING(instance, client_string));
412
+ }
413
+ root["sdk"] = sdk.c_str();
414
+ {
415
+ char id[20] = {0};
416
+ snprintf(id, sizeof(id), "%p", (void *)instance);
417
+ std::string idstr(id);
418
+ if (cmd->id) {
419
+ idstr.append("/").append(cmd->id);
420
+ }
421
+ root["id"] = idstr;
422
+ }
423
+
424
+ size_t ii;
425
+ Json::Value kv;
426
+ for (ii = 0; ii < instance->cmdq.npipelines; ii++) {
427
+ lcb::Server *server = static_cast<lcb::Server*>(instance->cmdq.pipelines[ii]);
428
+ lcbio_CTX *ctx = server->connctx;
429
+ if (ctx) {
430
+ Json::Value endpoint;
431
+ char id[20] = {0};
432
+ snprintf(id, sizeof(id), "%016" PRIx64, ctx->sock ? ctx->sock->id : (lcb_U64)0);
433
+ endpoint["id"] = id;
434
+ if (server->curhost->ipv6) {
435
+ endpoint["remote"] = "[" + std::string(server->curhost->host) + "]:" + std::string(server->curhost->port);
436
+ } else {
437
+ endpoint["remote"] = std::string(server->curhost->host) + ":" + std::string(server->curhost->port);
438
+ }
439
+ endpoint["local"] = lcbio__inet_ntop(&ctx->sock->info->sa_local);
440
+ endpoint["last_activity_us"] = (Json::Value::UInt64)(now > ctx->sock->atime ? now - ctx->sock->atime : 0);
441
+ endpoint["status"] = "connected";
442
+ root[lcbio_svcstr(ctx->sock->service)].append(endpoint);
443
+ }
444
+ }
445
+ instance->memd_sockpool->toJSON(now, root);
446
+ instance->http_sockpool->toJSON(now, root);
447
+ {
448
+ Json::Value cur;
449
+ lcb_ASPEND_SETTYPE::iterator it;
450
+ lcb_ASPEND_SETTYPE *pendq;
451
+ if ((pendq = instance->pendops.items[LCB_PENDTYPE_HTTP])) {
452
+ for (it = pendq->begin(); it != pendq->end(); ++it) {
453
+ lcb::http::Request *htreq = reinterpret_cast<lcb::http::Request*>(*it);
454
+ lcbio_CTX *ctx = htreq->ioctx;
455
+ if (ctx) {
456
+ Json::Value endpoint;
457
+ char id[20] = {0};
458
+ snprintf(id, sizeof(id), "%016" PRIx64, ctx->sock ? ctx->sock->id : (lcb_U64)0);
459
+ endpoint["id"] = id;
460
+ if (htreq->ipv6) {
461
+ endpoint["remote"] = "[" + std::string(htreq->host) + "]:" + std::string(htreq->port);
462
+ } else {
463
+ endpoint["remote"] = std::string(htreq->host) + ":" + std::string(htreq->port);
464
+ }
465
+ endpoint["local"] = lcbio__inet_ntop(&ctx->sock->info->sa_local);
466
+ endpoint["last_activity_us"] = (Json::Value::UInt64)(now > ctx->sock->atime ? now - ctx->sock->atime : 0);
467
+ endpoint["status"] = "connected";
468
+ root[lcbio_svcstr(ctx->sock->service)].append(endpoint);
469
+ }
470
+ }
471
+ }
472
+ }
473
+
474
+ Json::Writer *w;
475
+ if (cmd->options & LCB_PINGOPT_F_JSONPRETTY) {
476
+ w = new Json::StyledWriter();
477
+ } else {
478
+ w = new Json::FastWriter();
479
+ }
480
+ std::string json = w->write(root);
481
+ delete w;
482
+
483
+ lcb_RESPDIAG resp = {0};
484
+ lcb_RESPCALLBACK callback;
485
+
486
+ resp.njson = json.size();
487
+ resp.json = json.c_str();
488
+
489
+ callback = lcb_find_callback(instance, LCB_CALLBACK_DIAG);
490
+ resp.cookie = const_cast<void*>(cookie);
491
+ callback(instance, LCB_CALLBACK_DIAG, (lcb_RESPBASE *)&resp);
492
+
493
+ return LCB_SUCCESS;
494
+ }