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
@@ -17,9 +17,6 @@
17
17
 
18
18
  #ifndef LCB_BOOTSTRAP_H
19
19
  #define LCB_BOOTSTRAP_H
20
- #ifdef __cplusplus
21
- extern "C" {
22
- #endif
23
20
 
24
21
  /**@file
25
22
  * Core bootstrap/cluster configuration routines */
@@ -29,19 +26,49 @@ extern "C" {
29
26
  * @{
30
27
  */
31
28
 
32
- #if defined(__LCB_DOXYGEN__) || defined(LCB_BOOTSTRAP_DEFINE_STRUCT)
29
+ #ifdef __cplusplus
33
30
  #include "bucketconfig/clconfig.h"
31
+ #include <lcbio/timer-cxx.h>
34
32
 
33
+ namespace lcb {
35
34
  /**
36
35
  * Structure containing the bootstrap state for the instance.
36
+ *
37
+ * Derived from Listener,
38
+ * used to react when a new configuration is received. This
39
+ * is used for both requested configurations (i.e. an explicit call to
40
+ * lcb_bootstrap_common()) as well as unsolicited updates such as
41
+ * HTTP streaming configurations or Not-My-Vbucket "Carrier" updates.
37
42
  */
38
- struct lcb_BOOTSTRAP {
39
- /**Listener object used to react when a new configuration is received. This
40
- * is used for both requested configurations (i.e. an explicit call to
41
- * lcb_bootstrap_common()) as well as unsolicited updates such as
42
- * HTTP streaming configurations or Not-My-Vbucket "Carrier" updates.
43
+ class Bootstrap : lcb::clconfig::Listener {
44
+ public:
45
+ Bootstrap(lcb_t);
46
+ ~Bootstrap();
47
+ lcb_error_t bootstrap(unsigned options);
48
+
49
+ hrtime_t get_last_refresh() const {
50
+ return last_refresh;
51
+ }
52
+ void reset_last_refresh() {
53
+ last_refresh = 0;
54
+ }
55
+ size_t get_errcounter() const {
56
+ return errcounter;
57
+ }
58
+
59
+ /**
60
+ * Try to start/stop background polling depending on whether we're able to.
43
61
  */
44
- clconfig_listener listener;
62
+ void check_bgpoll();
63
+
64
+ private:
65
+ // Override
66
+ void clconfig_lsn(lcb::clconfig::EventType e, lcb::clconfig::ConfigInfo* i);
67
+
68
+ inline void config_callback(lcb::clconfig::EventType, lcb::clconfig::ConfigInfo*);
69
+ inline void initial_error(lcb_error_t, const char *);
70
+ void timer_dispatch();
71
+ void bgpoll();
45
72
 
46
73
  lcb_t parent;
47
74
 
@@ -49,7 +76,10 @@ struct lcb_BOOTSTRAP {
49
76
  * updates as an asynchronous event (to allow safe updates and avoid
50
77
  * reentrancy issues)
51
78
  */
52
- lcbio_pTIMER tm;
79
+ lcb::io::Timer<Bootstrap, &Bootstrap::timer_dispatch> tm;
80
+
81
+ /**Timer used for periodic polling of config */
82
+ lcb::io::Timer<Bootstrap, &Bootstrap::bgpoll> tmpoll;
53
83
 
54
84
  /**
55
85
  * Timestamp indicating the most recent configuration activity. This
@@ -73,57 +103,47 @@ struct lcb_BOOTSTRAP {
73
103
  */
74
104
  unsigned errcounter;
75
105
 
76
- /** Flag indicating whether the _initial_ configuration has been received */
77
- int bootstrapped;
106
+ enum State {
107
+ /** Initial 'blank' state */
108
+ S_INITIAL_PRE = 0,
109
+ /** We got something after our initial callback */
110
+ S_INITIAL_TRIGGERED,
111
+ /** Have received at least one valid configuration */
112
+ S_BOOTSTRAPPED
113
+ };
114
+ State state;
78
115
  };
79
- #endif
80
116
 
81
117
  /**
82
118
  * These flags control the bootstrap refreshing mode that will take place
83
119
  * when lcb_bootstrap_common() is invoked. These options may be OR'd with
84
120
  * each other (with the exception of ::LCB_BS_REFRESH_ALWAYS).
85
121
  */
86
- typedef enum {
122
+ enum BootstrapOptions {
87
123
  /** Always fetch a new configuration. No throttling checks are performed */
88
- LCB_BS_REFRESH_ALWAYS = 0x00,
124
+ BS_REFRESH_ALWAYS = 0x00,
89
125
  /** Special mode used to fetch the first configuration */
90
- LCB_BS_REFRESH_INITIAL = 0x02,
126
+ BS_REFRESH_INITIAL = 0x02,
91
127
 
92
128
  /** Make the request for a new configuration subject to throttling
93
129
  * limitations. Currently this will be subject to the interval specified
94
130
  * in the @ref LCB_CNTL_CONFDELAY_THRESH setting and the @ref
95
131
  * LCB_CNTL_CONFERRTHRESH setting. If the refresh has been throttled
96
132
  * the lcb_confmon_is_refreshing() function will return false */
97
- LCB_BS_REFRESH_THROTTLE = 0x04,
133
+ BS_REFRESH_THROTTLE = 0x04,
98
134
 
99
135
  /** To be used in conjunction with ::LCB_BS_REFRESH_THROTTLE, this will
100
136
  * increment the error counter in case the current refresh is throttled,
101
137
  * such that when the error counter reaches the threshold, the throttle
102
138
  * limitations will expire and a new refresh will take place */
103
- LCB_BS_REFRESH_INCRERR = 0x08
104
- } lcb_BSFLAGS;
105
-
106
- /**
107
- * @brief Request that the handle update its configuration.
108
- *
109
- * This function acts as a gateway to the more abstract confmon interface.
110
- *
111
- * @param instance The instance
112
- * @param options A set of options specified as flags, indicating under what
113
- * conditions a new configuration should be refetched.
114
- *
115
- * @return
116
- */
117
- LCB_INTERNAL_API
118
- lcb_error_t
119
- lcb_bootstrap_common(lcb_t instance, int options);
139
+ BS_REFRESH_INCRERR = 0x08
140
+ };
120
141
 
121
142
  void
122
143
  lcb_bootstrap_destroy(lcb_t instance);
123
144
 
124
145
  /**@}*/
125
146
 
126
- #ifdef __cplusplus
127
- }
128
- #endif
147
+ } // namespace lcb
148
+ #endif // __cplusplus
129
149
  #endif /* LCB_BOOTSTRAP_H */
@@ -24,46 +24,74 @@
24
24
  #include "internal.h"
25
25
  #include "clconfig.h"
26
26
  #include "packetutils.h"
27
- #include "simplestring.h"
28
27
  #include <mcserver/negotiate.h>
29
28
  #include <lcbio/lcbio.h>
30
- #include <lcbio/timer-ng.h>
29
+ #include <lcbio/timer-cxx.h>
31
30
  #include <lcbio/ssl.h>
32
31
  #include "ctx-log-inl.h"
33
32
  #define LOGARGS(cccp, lvl) cccp->parent->settings, "cccp", LCB_LOG_##lvl, __FILE__, __LINE__
34
33
  #define LOGFMT "<%s:%s> "
35
34
  #define LOGID(cccp) get_ctx_host(cccp->ioctx), get_ctx_port(cccp->ioctx)
36
35
 
37
- #define PROVIDER_SETTING_T(fld) PROVIDER_SETTING(this, fld)
38
-
39
36
  struct CccpCookie;
40
37
 
41
- struct CccpProvider : public clconfig_provider {
42
- CccpProvider(lcb_confmon *);
38
+ using namespace lcb::clconfig;
39
+
40
+ struct CccpProvider : public Provider {
41
+ CccpProvider(Confmon *);
43
42
  ~CccpProvider();
44
43
 
45
- void release_socket(bool can_reuse);
44
+ /**
45
+ * Stops the current request.
46
+ * @param is_clean Whether the state of the current request is 'clean',
47
+ * i.e. whether we are stopping because of an error condition, or
48
+ * because we have received a successful response.
49
+ */
50
+ void stop_current_request(bool is_clean);
46
51
  lcb_error_t schedule_next_request(lcb_error_t why, bool can_rollover);
47
52
  lcb_error_t mcio_error(lcb_error_t why);
53
+ void on_timeout() { mcio_error(LCB_ETIMEDOUT); }
48
54
  lcb_error_t update(const char *host, const char* data);
49
55
  void request_config();
50
- void on_config_updated(lcbvb_CONFIG *vbc);
51
56
  void on_io_read();
52
57
 
58
+ bool pause(); // Override
59
+ void configure_nodes(const lcb::Hostlist&); // Override
60
+ void config_updated(lcbvb_CONFIG *); // Override;
61
+ void dump(FILE*) const; // Override
62
+ lcb_error_t refresh(); // Override
63
+
64
+ ConfigInfo *get_cached() /* Override */ {
65
+ return config;
66
+ }
67
+
68
+ const lcb::Hostlist* get_nodes() const /* Override */ {
69
+ return nodes;
70
+ }
71
+
72
+ void enable(void *arg) {
73
+ instance = reinterpret_cast<lcb_t>(arg);
74
+ Provider::enable();
75
+ }
76
+
77
+ // Whether there is a pending CCCP config request.
78
+ bool has_pending_request() const {
79
+ return creq != NULL || cmdcookie != NULL || ioctx != NULL;
80
+ }
81
+
53
82
  lcb::Hostlist *nodes;
54
- clconfig_info *config;
55
- bool server_active;
56
- lcbio_pTIMER timer;
83
+ ConfigInfo *config;
84
+ lcb::io::Timer<CccpProvider, &CccpProvider::on_timeout> timer;
57
85
  lcb_t instance;
58
- lcbio_CONNREQ creq;
86
+ lcb::io::ConnectionRequest *creq;
59
87
  lcbio_CTX *ioctx;
60
88
  CccpCookie *cmdcookie;
61
89
  };
62
90
 
63
91
  struct CccpCookie {
64
92
  CccpProvider *parent;
65
- bool ignore_errors;
66
- CccpCookie(CccpProvider *parent_) : parent(parent_), ignore_errors(false) {
93
+ bool active;
94
+ CccpCookie(CccpProvider *parent_) : parent(parent_), active(true) {
67
95
  }
68
96
  };
69
97
 
@@ -77,25 +105,24 @@ pooled_close_cb(lcbio_SOCKET *sock, int reusable, void *arg)
77
105
  bool *ru_ex = reinterpret_cast<bool*>(arg);
78
106
  lcbio_ref(sock);
79
107
  if (reusable && *ru_ex) {
80
- lcbio_mgr_put(sock);
108
+ lcb::io::Pool::put(sock);
81
109
  } else {
82
- lcbio_mgr_discard(sock);
110
+ lcb::io::Pool::discard(sock);
83
111
  }
84
112
  }
85
113
 
86
114
  void
87
- CccpProvider::release_socket(bool can_reuse)
115
+ CccpProvider::stop_current_request(bool is_clean)
88
116
  {
89
117
  if (cmdcookie) {
90
- cmdcookie->ignore_errors = 1;
118
+ cmdcookie->active = false;
91
119
  cmdcookie = NULL;
92
- return;
93
120
  }
94
121
 
95
- lcbio_connreq_cancel(&creq);
122
+ lcb::io::ConnectionRequest::cancel(&creq);
96
123
 
97
124
  if (ioctx) {
98
- lcbio_ctx_close(ioctx, pooled_close_cb, &can_reuse);
125
+ lcbio_ctx_close(ioctx, pooled_close_cb, &is_clean);
99
126
  ioctx = NULL;
100
127
  }
101
128
  }
@@ -103,35 +130,28 @@ CccpProvider::release_socket(bool can_reuse)
103
130
  lcb_error_t
104
131
  CccpProvider::schedule_next_request(lcb_error_t err, bool can_rollover)
105
132
  {
106
- lcb::Server *server;
107
133
  lcb_host_t *next_host = nodes->next(can_rollover);
108
134
  if (!next_host) {
109
- lcbio_timer_disarm(timer);
110
- lcb_confmon_provider_failed(this, err);
111
- server_active = false;
135
+ timer.cancel();
136
+ parent->provider_failed(this, err);
112
137
  return err;
113
138
  }
114
139
 
115
- server = lcb_find_server_by_host(instance, next_host);
140
+ lcb::Server* server = instance->find_server(*next_host);
116
141
  if (server) {
117
- CccpCookie *cookie = new CccpCookie(this);
118
- cmdcookie = cookie;
142
+ cmdcookie = new CccpCookie(this);
119
143
  lcb_log(LOGARGS(this, INFO), "Re-Issuing CCCP Command on server struct %p (%s:%s)", (void*)server, next_host->host, next_host->port);
120
- lcbio_timer_rearm(timer, PROVIDER_SETTING_T(config_node_timeout));
121
- return lcb_getconfig(instance, cookie, server);
144
+ timer.rearm(settings().config_node_timeout);
145
+ instance->request_config(cmdcookie, server);
122
146
 
123
147
  } else {
124
- lcbio_pMGRREQ preq;
125
148
 
126
149
  lcb_log(LOGARGS(this, INFO), "Requesting connection to node %s:%s for CCCP configuration", next_host->host, next_host->port);
127
- preq = lcbio_mgr_get(
128
- instance->memd_sockpool, next_host,
129
- PROVIDER_SETTING_T(config_node_timeout),
130
- on_connected, this);
131
- LCBIO_CONNREQ_MKPOOLED(&creq, preq);
150
+ creq = instance->memd_sockpool->get(*next_host,
151
+ settings().config_node_timeout,
152
+ on_connected, this);
132
153
  }
133
154
 
134
- server_active = true;
135
155
  return LCB_SUCCESS;
136
156
  }
137
157
 
@@ -139,42 +159,25 @@ lcb_error_t
139
159
  CccpProvider::mcio_error(lcb_error_t err)
140
160
  {
141
161
  if (err != LCB_NOT_SUPPORTED && err != LCB_UNKNOWN_COMMAND) {
142
- lcb_log(LOGARGS(this, ERR), LOGFMT "Got I/O Error=0x%x", LOGID(this), err);
162
+ lcb_log(LOGARGS(this, ERR), LOGFMT "Could not get configuration: %s", LOGID(this), lcb_strerror_short(err));
143
163
  }
144
164
 
145
- release_socket(err == LCB_NOT_SUPPORTED);
165
+ stop_current_request(err == LCB_NOT_SUPPORTED);
146
166
  return schedule_next_request(err, false);
147
167
  }
148
168
 
149
- static void socket_timeout(void *arg) {
150
- reinterpret_cast<CccpProvider*>(arg)->mcio_error(LCB_ETIMEDOUT);
151
- }
152
-
153
- void lcb_clconfig_cccp_enable(clconfig_provider *pb, lcb_t instance)
154
- {
155
- CccpProvider *cccp = static_cast<CccpProvider*>(pb);
156
- lcb_assert(pb->type == LCB_CLCONFIG_CCCP);
157
- cccp->instance = instance;
158
- pb->enabled = true;
159
- }
160
-
161
- static hostlist_t get_nodes(const clconfig_provider *pb) {
162
- return static_cast<const CccpProvider*>(pb)->nodes;
163
- }
164
-
165
169
  /** Update the configuration from a server. */
166
170
  lcb_error_t
167
- lcb_cccp_update(clconfig_provider *provider, const char *host, const char *data) {
171
+ lcb::clconfig::cccp_update(Provider *provider, const char *host, const char *data) {
168
172
  return static_cast<CccpProvider*>(provider)->update(host, data);
169
173
  }
170
174
 
171
175
  lcb_error_t
172
176
  CccpProvider::update(const char *host, const char *data)
173
177
  {
174
- /** TODO: replace this with lcbvb_ names */
175
178
  lcbvb_CONFIG* vbc;
176
179
  int rv;
177
- clconfig_info *new_config;
180
+ ConfigInfo *new_config;
178
181
  vbc = lcbvb_create();
179
182
 
180
183
  if (!vbc) {
@@ -190,7 +193,7 @@ CccpProvider::update(const char *host, const char *data)
190
193
  }
191
194
 
192
195
  lcbvb_replace_host(vbc, host);
193
- new_config = lcb_clconfig_create(vbc, LCB_CLCONFIG_CCCP);
196
+ new_config = ConfigInfo::create(vbc, CLCONFIG_CCCP);
194
197
 
195
198
  if (!new_config) {
196
199
  lcbvb_destroy(vbc);
@@ -198,38 +201,38 @@ CccpProvider::update(const char *host, const char *data)
198
201
  }
199
202
 
200
203
  if (config) {
201
- lcb_clconfig_decref(config);
204
+ config->decref();
202
205
  }
203
206
 
204
207
  /** TODO: Figure out the comparison vector */
205
- new_config->cmpclock = gethrtime();
206
208
  config = new_config;
207
- lcb_confmon_provider_success(this, new_config);
209
+ parent->provider_got_config(this, new_config);
208
210
  return LCB_SUCCESS;
209
211
  }
210
212
 
211
- void lcb_cccp_update2(const void *cookie, lcb_error_t err,
212
- const void *bytes, lcb_size_t nbytes,
213
- const lcb_host_t *origin)
213
+ void lcb::clconfig::cccp_update(
214
+ const void *cookie_, lcb_error_t err,
215
+ const void *bytes, size_t nbytes, const lcb_host_t *origin)
214
216
  {
215
- CccpCookie *ck = reinterpret_cast<CccpCookie*>(const_cast<void*>(cookie));
216
- CccpProvider *cccp = ck->parent;
217
+ CccpCookie *cookie = reinterpret_cast<CccpCookie*>(const_cast<void*>(cookie_));
218
+ CccpProvider *cccp = cookie->parent;
217
219
 
218
- if (ck == cccp->cmdcookie) {
219
- lcbio_timer_disarm(cccp->timer);
220
+ bool was_active = cookie->active;
221
+ if (cookie->active) {
222
+ cookie->active = false;
223
+ cccp->timer.cancel();
220
224
  cccp->cmdcookie = NULL;
221
225
  }
226
+ delete cookie;
222
227
 
223
228
  if (err == LCB_SUCCESS) {
224
229
  std::string ss(reinterpret_cast<const char *>(bytes), nbytes);
225
230
  err = cccp->update(origin->host, ss.c_str());
226
231
  }
227
232
 
228
- if (err != LCB_SUCCESS && ck->ignore_errors == 0) {
233
+ if (err != LCB_SUCCESS && was_active) {
229
234
  cccp->mcio_error(err);
230
235
  }
231
-
232
- free(ck);
233
236
  }
234
237
 
235
238
  static void
@@ -238,21 +241,20 @@ on_connected(lcbio_SOCKET *sock, void *data, lcb_error_t err, lcbio_OSERR)
238
241
  lcbio_CTXPROCS ioprocs;
239
242
  CccpProvider *cccp = reinterpret_cast<CccpProvider*>(data);
240
243
  lcb_settings *settings = cccp->parent->settings;
244
+ cccp->creq = NULL;
241
245
 
242
- LCBIO_CONNREQ_CLEAR(&cccp->creq);
243
246
  if (err != LCB_SUCCESS) {
244
247
  if (sock) {
245
- lcbio_mgr_discard(sock);
248
+ lcb::io::Pool::discard(sock);
246
249
  }
247
250
  cccp->mcio_error(err);
248
251
  return;
249
252
  }
250
253
 
251
254
  if (lcbio_protoctx_get(sock, LCBIO_PROTOCTX_SESSINFO) == NULL) {
252
- lcb::SessionRequest *sreq = lcb::SessionRequest::start(
255
+ cccp->creq = lcb::SessionRequest::start(
253
256
  sock, settings, settings->config_node_timeout, on_connected,
254
257
  cccp);
255
- LCBIO_CONNREQ_MKGENERIC(&cccp->creq, sreq, lcb::sessreq_cancel);
256
258
  return;
257
259
  }
258
260
 
@@ -263,70 +265,49 @@ on_connected(lcbio_SOCKET *sock, void *data, lcb_error_t err, lcbio_OSERR)
263
265
  cccp->request_config();
264
266
  }
265
267
 
266
- static lcb_error_t cccp_get(clconfig_provider *pb)
267
- {
268
- CccpProvider *cccp = static_cast<CccpProvider *>(pb);
269
- if (cccp->creq.u.p_generic || cccp->server_active || cccp->cmdcookie) {
268
+ lcb_error_t CccpProvider::refresh() {
269
+ if (has_pending_request()) {
270
270
  return LCB_BUSY;
271
271
  }
272
272
 
273
- return cccp->schedule_next_request(LCB_SUCCESS, true);
274
- }
275
-
276
- static clconfig_info *cccp_get_cached(clconfig_provider *pb) {
277
- return static_cast<CccpProvider *>(pb)->config;
273
+ return schedule_next_request(LCB_SUCCESS, true);
278
274
  }
279
275
 
280
- static lcb_error_t cccp_pause(clconfig_provider *pb)
276
+ bool
277
+ CccpProvider::pause()
281
278
  {
282
- CccpProvider *cccp = static_cast<CccpProvider *>(pb);
283
- if (!cccp->server_active) {
284
- return LCB_SUCCESS;
279
+ if (!has_pending_request()) {
280
+ return true;
285
281
  }
286
282
 
287
- cccp->server_active = 0;
288
- cccp->release_socket(false);
289
- lcbio_timer_disarm(cccp->timer);
290
- return LCB_SUCCESS;
291
- }
292
-
293
- static void cccp_cleanup(clconfig_provider *pb) {
294
- delete static_cast<CccpProvider*>(pb);
283
+ stop_current_request(false);
284
+ timer.cancel();
285
+ return true;
295
286
  }
296
287
 
297
288
  CccpProvider::~CccpProvider() {
298
- release_socket(false);
289
+ stop_current_request(false);
299
290
 
300
291
  if (config) {
301
- lcb_clconfig_decref(config);
292
+ config->decref();
302
293
  }
303
294
  if (nodes) {
304
295
  delete nodes;
305
296
  }
306
- if (timer) {
307
- lcbio_timer_destroy(timer);
308
- }
309
- if (cmdcookie) {
310
- cmdcookie->ignore_errors = 1;
311
- }
297
+ timer.release();
312
298
  }
313
299
 
314
- static void
315
- configure_nodes(clconfig_provider *pb, const hostlist_t nodes)
300
+ void
301
+ CccpProvider::configure_nodes(const lcb::Hostlist& nodes_)
316
302
  {
317
- CccpProvider *cccp = static_cast<CccpProvider *>(pb);
318
- cccp->nodes->assign(*nodes);
319
- if (PROVIDER_SETTING(pb, randomize_bootstrap_nodes)) {
320
- cccp->nodes->randomize();
303
+ nodes->assign(nodes_);
304
+ if (parent->settings->randomize_bootstrap_nodes) {
305
+ nodes->randomize();
321
306
  }
322
307
  }
323
308
 
324
- static void config_updated(clconfig_provider *provider, lcbvb_CONFIG* vbc) {
325
- static_cast<CccpProvider*>(provider)->on_config_updated(vbc);
326
- }
327
-
328
309
  void
329
- CccpProvider::on_config_updated(lcbvb_CONFIG *vbc)
310
+ CccpProvider::config_updated(lcbvb_CONFIG *vbc)
330
311
  {
331
312
  lcbvb_SVCMODE mode;
332
313
  if (LCBVB_NSERVERS(vbc) < 1) {
@@ -334,7 +315,7 @@ CccpProvider::on_config_updated(lcbvb_CONFIG *vbc)
334
315
  }
335
316
 
336
317
  nodes->clear();
337
- if (PROVIDER_SETTING_T(sslopts) & LCB_SSL_ENABLED) {
318
+ if (settings().sslopts & LCB_SSL_ENABLED) {
338
319
  mode = LCBVB_SVCMODE_SSL;
339
320
  } else {
340
321
  mode = LCBVB_SVCMODE_PLAIN;
@@ -349,7 +330,7 @@ CccpProvider::on_config_updated(lcbvb_CONFIG *vbc)
349
330
  nodes->add(mcaddr, LCB_CONFIG_MCD_PORT);
350
331
  }
351
332
 
352
- if (PROVIDER_SETTING_T(randomize_bootstrap_nodes)) {
333
+ if (settings().randomize_bootstrap_nodes) {
353
334
  nodes->randomize();
354
335
  }
355
336
  }
@@ -406,13 +387,12 @@ CccpProvider::on_io_read()
406
387
  std::string hoststr(lcbio_get_host(lcbio_ctx_sock(ioctx))->host);
407
388
 
408
389
  resp.release(ioctx);
409
- release_socket(true);
390
+ stop_current_request(true);
410
391
 
411
392
  lcb_error_t err = update(hoststr.c_str(), jsonstr.c_str());
412
393
 
413
394
  if (err == LCB_SUCCESS) {
414
- lcbio_timer_disarm(timer);
415
- server_active = false;
395
+ timer.cancel();
416
396
  } else {
417
397
  schedule_next_request(LCB_PROTOCOL_ERROR, 0);
418
398
  }
@@ -427,62 +407,44 @@ void CccpProvider::request_config()
427
407
  lcbio_ctx_put(ioctx, req.data(), req.size());
428
408
  lcbio_ctx_rwant(ioctx, 24);
429
409
  lcbio_ctx_schedule(ioctx);
430
- lcbio_timer_rearm(timer, PROVIDER_SETTING(this, config_node_timeout));
410
+ timer.rearm(settings().config_node_timeout);
431
411
  }
432
412
 
433
- static void do_dump(clconfig_provider *pb, FILE *fp)
434
- {
435
- CccpProvider *cccp = (CccpProvider *)pb;
436
-
437
- if (!cccp->enabled) {
413
+ void CccpProvider::dump(FILE *fp) const {
414
+ if (!enabled) {
438
415
  return;
439
416
  }
440
417
 
441
418
  fprintf(fp, "## BEGIN CCCP PROVIDER DUMP ##\n");
442
- fprintf(fp, "TIMER ACTIVE: %s\n", lcbio_timer_armed(cccp->timer) ? "YES" : "NO");
443
- fprintf(fp, "PIPELINE RESPONSE COOKIE: %p\n", (void*)cccp->cmdcookie);
444
- if (cccp->ioctx) {
419
+ fprintf(fp, "TIMER ACTIVE: %s\n", timer.is_armed() ? "YES" : "NO");
420
+ fprintf(fp, "PIPELINE RESPONSE COOKIE: %p\n", (void*)cmdcookie);
421
+ if (ioctx) {
445
422
  fprintf(fp, "CCCP Owns connection:\n");
446
- lcbio_ctx_dump(cccp->ioctx, fp);
447
- } else if (cccp->creq.u.p_generic) {
423
+ lcbio_ctx_dump(ioctx, fp);
424
+ } else if (creq) {
448
425
  fprintf(fp, "CCCP Is connecting\n");
449
426
  } else {
450
427
  fprintf(fp, "CCCP does not have a dedicated connection\n");
451
428
  }
452
429
 
453
- for (size_t ii = 0; ii < cccp->nodes->size(); ii++) {
454
- const lcb_host_t &curhost = (*cccp->nodes)[ii];
430
+ for (size_t ii = 0; ii < nodes->size(); ii++) {
431
+ const lcb_host_t &curhost = (*nodes)[ii];
455
432
  fprintf(fp, "CCCP NODE: %s:%s\n", curhost.host, curhost.port);
456
433
  }
457
434
  fprintf(fp, "## END CCCP PROVIDER DUMP ##\n");
458
435
  }
459
436
 
460
- clconfig_provider * lcb_clconfig_create_cccp(lcb_confmon *mon)
461
- {
462
- return new CccpProvider(mon);
463
- }
464
-
465
- CccpProvider::CccpProvider(lcb_confmon *mon)
466
- : nodes(new lcb::Hostlist()),
437
+ CccpProvider::CccpProvider(Confmon *mon)
438
+ : Provider(mon, CLCONFIG_CCCP),
439
+ nodes(new lcb::Hostlist()),
467
440
  config(NULL),
468
- server_active(false),
469
- timer(NULL),
441
+ timer(mon->iot, this),
470
442
  instance(NULL),
471
443
  ioctx(NULL),
472
- cmdcookie(NULL)
473
- {
474
- clconfig_provider::type = LCB_CLCONFIG_CCCP;
475
- clconfig_provider::refresh = cccp_get;
476
- clconfig_provider::get_cached = cccp_get_cached;
477
- clconfig_provider::pause = cccp_pause;
478
- clconfig_provider::shutdown = cccp_cleanup;
479
- clconfig_provider::config_updated = ::config_updated;
480
- clconfig_provider::configure_nodes = ::configure_nodes;
481
- clconfig_provider::get_nodes = ::get_nodes;
482
- clconfig_provider::dump = do_dump;
483
- clconfig_provider::parent = mon;
484
- clconfig_provider::enabled = 0;
485
-
486
- timer = lcbio_timer_new(mon->iot, this, socket_timeout);
444
+ cmdcookie(NULL) {
487
445
  std::memset(&creq, 0, sizeof creq);
488
446
  }
447
+
448
+ Provider* lcb::clconfig::new_cccp_provider(Confmon *mon) {
449
+ return new CccpProvider(mon);
450
+ }