libcouchbase 0.3.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,4 +1,4 @@
1
- #!/usr/bin/perl
1
+ #!/usr/bin/env perl
2
2
 
3
3
  use strict;
4
4
  use warnings;
@@ -48,11 +48,12 @@ extern "C" {
48
48
  * Create an instance of an event handler that utilize libev for
49
49
  * event notification.
50
50
  *
51
- * @param version the API version to use
51
+ * @param version Set this to 0. This may be used in the future to allow
52
+ * variation on the third argument (`void*` currently).
53
+ * @param[out] io a pointer to a newly created and initialized event handler
52
54
  * @param loop the event loop (struct ev_loop *) to hook use (please
53
55
  * note that you shouldn't reference the event loop from
54
56
  * multiple threads)
55
- * @param io a pointer to a newly created and initialized event handler
56
57
  * @return status of the operation
57
58
  */
58
59
  LIBCOUCHBASE_API
@@ -43,8 +43,6 @@ listing of the various subcomponents and what they do:
43
43
 
44
44
  * `sllist.h, sllist-inl.h` contain the implementation for a single-linked list
45
45
 
46
- * `simplestring.{c,h}` contains the implementation for a dynamically sized string
47
-
48
46
  * `logging.{c,h}` contains the implementation for the library's logging mechanism
49
47
 
50
48
  * `hostlist.{c,h}` defines a list of hosts, with features for de-duping and converting
@@ -10,24 +10,43 @@ namespace lcb {
10
10
  class Authenticator {
11
11
  public:
12
12
  typedef std::map<std::string,std::string> Map;
13
+ // Gets the "global" username
13
14
  const std::string& username() const { return m_username; }
15
+
16
+ // Gets the "global" password
14
17
  const std::string& password() const { return m_password; }
18
+
19
+ // Get the username and password for a specific bucket
20
+ const std::string& username_for(const char *bucket) const;
21
+ const std::string& password_for(const char *bucket) const;
22
+
15
23
  const Map& buckets() const { return m_buckets; }
16
- Authenticator() : m_refcount(1) {}
24
+ Authenticator() : m_refcount(1), m_mode(LCBAUTH_MODE_CLASSIC) {}
25
+ Authenticator(const Authenticator&);
17
26
 
18
27
  size_t refcount() const { return m_refcount; }
19
28
  void incref() { ++m_refcount; }
20
29
  void decref() { if (!--m_refcount) { delete this; } }
30
+ lcb_error_t set_mode(lcbauth_MODE mode_) {
31
+ if (m_buckets.size() || m_username.size() || m_password.size()) {
32
+ return LCB_ERROR;
33
+ } else {
34
+ m_mode = mode_;
35
+ return LCB_SUCCESS;
36
+ }
37
+ }
38
+ lcbauth_MODE mode() const { return m_mode; }
21
39
  lcb_error_t add(const char *user, const char *pass, int flags);
22
- lcb_error_t init(const std::string& username_, const std::string& bucket,
23
- const std::string& password, lcb_type_t conntype);
40
+ lcb_error_t add(const std::string& user, const std::string& pass, int flags) {
41
+ return add(user.c_str(), pass.c_str(), flags);
42
+ }
24
43
 
25
44
  private:
26
- // todo: refactor these out
27
45
  Map m_buckets;
28
46
  std::string m_username;
29
47
  std::string m_password;
30
48
  size_t m_refcount;
49
+ lcbauth_MODE m_mode;
31
50
  };
32
51
  }
33
52
  #endif
@@ -9,16 +9,6 @@ lcbauth_new()
9
9
  return new Authenticator();
10
10
  }
11
11
 
12
- const char *
13
- lcbauth_get_bpass(const lcb_AUTHENTICATOR *auth, const char *u)
14
- {
15
- Authenticator::Map::const_iterator ii = auth->buckets().find(u);
16
- if (ii == auth->buckets().end()) {
17
- return NULL;
18
- }
19
- return ii->second.c_str();
20
- }
21
-
22
12
  lcb_error_t
23
13
  lcbauth_add_pass(lcb_AUTHENTICATOR *auth, const char *u, const char *p, int flags)
24
14
  {
@@ -28,46 +18,63 @@ lcbauth_add_pass(lcb_AUTHENTICATOR *auth, const char *u, const char *p, int flag
28
18
  lcb_error_t
29
19
  Authenticator::add(const char *u, const char *p, int flags)
30
20
  {
31
- if (!flags) {
21
+ if (!(flags & (LCBAUTH_F_BUCKET|LCBAUTH_F_CLUSTER))) {
32
22
  return LCB_EINVAL;
33
23
  }
34
24
 
25
+ if (m_mode == LCBAUTH_MODE_RBAC && (flags & LCBAUTH_F_BUCKET)) {
26
+ return LCB_OPTIONS_CONFLICT;
27
+ }
28
+
35
29
  if (flags & LCBAUTH_F_CLUSTER) {
36
- if (!p) {
37
- m_username.clear();
38
- m_password.clear();
39
- } else {
30
+ if (p) {
40
31
  m_username = u;
41
32
  m_password = p;
33
+ } else {
34
+ m_username.clear();
35
+ m_password.clear();
42
36
  }
43
37
  }
38
+
44
39
  if (flags & LCBAUTH_F_BUCKET) {
45
- if (!p) {
46
- m_buckets.erase(u);
47
- } else {
40
+ if (p) {
48
41
  m_buckets[u] = p;
42
+ } else {
43
+ m_buckets.erase(u);
49
44
  }
50
45
  }
46
+
51
47
  return LCB_SUCCESS;
52
48
  }
53
49
 
54
- void
55
- lcbauth_get_upass(const lcb_AUTHENTICATOR *auth, const char **u, const char **p)
56
- {
57
- if (!auth->username().empty()) {
58
- *u = auth->username().c_str();
59
- *p = auth->password().empty() ? NULL : auth->password().c_str();
60
-
61
- } else if (!auth->buckets().empty()) {
62
- Authenticator::Map::const_iterator it = auth->buckets().begin();
63
- *u = it->first.c_str();
64
- if (!it->second.empty()) {
65
- *p = it->second.c_str();
50
+ static const std::string EmptyString;
51
+
52
+ const std::string&
53
+ Authenticator::username_for(const char *bucket) const {
54
+ if (m_mode == LCBAUTH_MODE_CLASSIC) {
55
+ // Find bucket specific credentials:
56
+ const Map::const_iterator it = m_buckets.find(bucket);
57
+ if (it == m_buckets.end()) {
58
+ return EmptyString;
59
+ } else {
60
+ return it->first;
61
+ }
62
+ } else {
63
+ return m_username;
64
+ }
65
+ }
66
+
67
+ const std::string&
68
+ Authenticator::password_for(const char *bucket) const {
69
+ if (m_mode == LCBAUTH_MODE_CLASSIC) {
70
+ const Map::const_iterator it = m_buckets.find(bucket);
71
+ if (it == m_buckets.end()) {
72
+ return EmptyString;
66
73
  } else {
67
- *p = NULL;
74
+ return it->second;
68
75
  }
69
76
  } else {
70
- *u = *p = NULL;
77
+ return m_password;
71
78
  }
72
79
  }
73
80
 
@@ -83,17 +90,18 @@ lcbauth_unref(lcb_AUTHENTICATOR *auth)
83
90
  auth->decref();
84
91
  }
85
92
 
86
- lcb_error_t
87
- Authenticator::init(const std::string& username_, const std::string& bucket,
88
- const std::string& passwd, lcb_type_t conntype)
89
- {
90
- m_username = (!username_.empty()) ? username_ : bucket;
91
- m_password = passwd;
93
+ Authenticator::Authenticator(const Authenticator& other)
94
+ : m_buckets(other.m_buckets), m_username(other.m_username),
95
+ m_password(other.m_password), m_refcount(1),
96
+ m_mode(other.m_mode) {
97
+ }
92
98
 
93
- if (conntype == LCB_TYPE_BUCKET && m_username != bucket) {
94
- return LCB_INVALID_USERNAME;
95
- }
99
+ lcb_AUTHENTICATOR *
100
+ lcbauth_clone(const lcb_AUTHENTICATOR *src) {
101
+ return new Authenticator(*src);
102
+ }
96
103
 
97
- m_buckets[bucket] = m_password;
98
- return LCB_SUCCESS;
104
+ lcb_error_t
105
+ lcbauth_set_mode(lcb_AUTHENTICATOR *src, lcbauth_MODE mode) {
106
+ return src->set_mode(mode);
99
107
  }
@@ -0,0 +1,244 @@
1
+ /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2014 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #define LCB_BOOTSTRAP_DEFINE_STRUCT 1
19
+ #include "internal.h"
20
+
21
+
22
+ #define LOGARGS(instance, lvl) instance->settings, "bootstrap", LCB_LOG_##lvl, __FILE__, __LINE__
23
+
24
+ using lcb::clconfig::EventType;
25
+ using lcb::clconfig::ConfigInfo;
26
+ using namespace lcb;
27
+
28
+ /**
29
+ * This function is where the configuration actually takes place. We ensure
30
+ * in other functions that this is only ever called directly from an event
31
+ * loop stack frame (or one of the small mini functions here) so that we
32
+ * don't accidentally end up destroying resources underneath us.
33
+ */
34
+ void Bootstrap::config_callback(EventType event, ConfigInfo *info) {
35
+ using namespace lcb::clconfig;
36
+ lcb_t instance = parent;
37
+
38
+ if (event != CLCONFIG_EVENT_GOT_NEW_CONFIG) {
39
+ if (event == CLCONFIG_EVENT_PROVIDERS_CYCLED) {
40
+ if (!LCBT_VBCONFIG(instance)) {
41
+ initial_error(LCB_ERROR, "No more bootstrap providers remain");
42
+ }
43
+ }
44
+ return;
45
+ }
46
+
47
+ instance->last_error = LCB_SUCCESS;
48
+
49
+ /** Ensure we're not called directly twice again */
50
+ if (state < S_INITIAL_TRIGGERED) {
51
+ state = S_INITIAL_TRIGGERED;
52
+ }
53
+
54
+ tm.cancel();
55
+
56
+ lcb_log(LOGARGS(instance, DEBUG), "Instance configured!");
57
+
58
+ if (info->get_origin() != CLCONFIG_FILE) {
59
+ /* Set the timestamp for the current config to control throttling,
60
+ * but only if it's not an initial file-based config. See CCBC-482 */
61
+ last_refresh = gethrtime();
62
+ errcounter = 0;
63
+ }
64
+
65
+ if (info->get_origin() == CLCONFIG_CCCP) {
66
+ /* Disable HTTP provider if we've received something via CCCP */
67
+
68
+ if (instance->cur_configinfo == NULL ||
69
+ instance->cur_configinfo->get_origin() != CLCONFIG_HTTP) {
70
+ /* Never disable HTTP if it's still being used */
71
+ instance->confmon->set_active(CLCONFIG_HTTP, false);
72
+ }
73
+ }
74
+
75
+ if (instance->type == LCB_TYPE_CLUSTER && info->get_origin() == CLCONFIG_CLADMIN) {
76
+ /* Disable HTTP provider for management operations, and fallback to static */
77
+ if (instance->cur_configinfo == NULL ||
78
+ instance->cur_configinfo->get_origin() != CLCONFIG_HTTP) {
79
+ instance->confmon->set_active(CLCONFIG_HTTP, false);
80
+ }
81
+ }
82
+
83
+ if (instance->type != LCB_TYPE_CLUSTER) {
84
+ lcb_update_vbconfig(instance, info);
85
+ }
86
+
87
+ if (state < S_BOOTSTRAPPED) {
88
+ state = S_BOOTSTRAPPED;
89
+ lcb_aspend_del(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL);
90
+
91
+ if (instance->type == LCB_TYPE_BUCKET &&
92
+ LCBVB_DISTTYPE(LCBT_VBCONFIG(instance)) == LCBVB_DIST_KETAMA &&
93
+ instance->cur_configinfo->get_origin() != CLCONFIG_MCRAW) {
94
+
95
+ lcb_log(LOGARGS(instance, INFO), "Reverting to HTTP Config for memcached buckets");
96
+ instance->settings->bc_http_stream_time = -1;
97
+ instance->confmon->set_active(CLCONFIG_HTTP, true);
98
+ instance->confmon->set_active(CLCONFIG_CCCP, false);
99
+ }
100
+ instance->callbacks.bootstrap(instance, LCB_SUCCESS);
101
+
102
+ // See if we can enable background polling.
103
+ check_bgpoll();
104
+ }
105
+
106
+ lcb_maybe_breakout(instance);
107
+ }
108
+
109
+ void Bootstrap::clconfig_lsn(EventType e, ConfigInfo *i) {
110
+ if (state == S_INITIAL_PRE) {
111
+ config_callback(e, i);
112
+ } else if (e == clconfig::CLCONFIG_EVENT_GOT_NEW_CONFIG) {
113
+ lcb_log(LOGARGS(parent, INFO), "Got new config. Will refresh asynchronously");
114
+ tm.signal();
115
+ }
116
+ }
117
+
118
+ void Bootstrap::check_bgpoll() {
119
+ if (parent->cur_configinfo == NULL ||
120
+ parent->cur_configinfo->get_origin() != lcb::clconfig::CLCONFIG_CCCP ||
121
+ LCBT_SETTING(parent, config_poll_interval) == 0) {
122
+ tmpoll.cancel();
123
+ } else {
124
+ tmpoll.rearm(LCBT_SETTING(parent, config_poll_interval));
125
+ }
126
+ }
127
+
128
+ void Bootstrap::bgpoll() {
129
+ lcb_log(LOGARGS(parent, TRACE), "Background-polling for new configuration");
130
+ bootstrap(BS_REFRESH_THROTTLE);
131
+ check_bgpoll();
132
+ }
133
+
134
+ /**
135
+ * This it the initial bootstrap timeout handler. This timeout pins down the
136
+ * instance. It is only scheduled during the initial bootstrap and is only
137
+ * triggered if the initial bootstrap fails to configure in time.
138
+ */
139
+ void Bootstrap::timer_dispatch() {
140
+ if (state > S_INITIAL_PRE) {
141
+ config_callback(clconfig::CLCONFIG_EVENT_GOT_NEW_CONFIG,
142
+ parent->confmon->get_config());
143
+ } else {
144
+ // Not yet bootstrapped!
145
+ initial_error(LCB_ETIMEDOUT, "Failed to bootstrap in time");
146
+ }
147
+ }
148
+
149
+
150
+ void Bootstrap::initial_error(lcb_error_t err, const char *errinfo) {
151
+ parent->last_error = parent->confmon->get_last_error();
152
+ if (parent->last_error == LCB_SUCCESS) {
153
+ parent->last_error = err;
154
+ }
155
+ parent->callbacks.error(parent, parent->last_error, errinfo);
156
+ lcb_log(LOGARGS(parent, ERR), "Failed to bootstrap client=%p. Error=%s, Message=%s", (void *)parent, lcb_strerror_short(parent->last_error), errinfo);
157
+ tm.cancel();
158
+
159
+ parent->callbacks.bootstrap(parent, parent->last_error);
160
+
161
+ lcb_aspend_del(&parent->pendops, LCB_PENDTYPE_COUNTER, NULL);
162
+ lcb_maybe_breakout(parent);
163
+ }
164
+
165
+ Bootstrap::Bootstrap(lcb_t instance)
166
+ : parent(instance),
167
+ tm(parent->iotable, this),
168
+ tmpoll(parent->iotable, this),
169
+ last_refresh(0),
170
+ errcounter(0),
171
+ state(S_INITIAL_PRE) {
172
+ parent->confmon->add_listener(this);
173
+ }
174
+
175
+ lcb_error_t Bootstrap::bootstrap(unsigned options) {
176
+ hrtime_t now = gethrtime();
177
+ if (parent->confmon->is_refreshing()) {
178
+ return LCB_SUCCESS;
179
+ }
180
+
181
+ if (options & BS_REFRESH_THROTTLE) {
182
+ /* Refresh throttle requested. This is not true if options == ALWAYS */
183
+ hrtime_t next_ts;
184
+ unsigned errthresh = LCBT_SETTING(parent, weird_things_threshold);
185
+
186
+ if (options & BS_REFRESH_INCRERR) {
187
+ errcounter++;
188
+ }
189
+ next_ts = last_refresh;
190
+ next_ts += LCB_US2NS(LCBT_SETTING(parent, weird_things_delay));
191
+ if (now < next_ts && errcounter < errthresh) {
192
+ lcb_log(LOGARGS(parent, INFO),
193
+ "Not requesting a config refresh because of throttling parameters. Next refresh possible in %ums or %u errors. "
194
+ "See LCB_CNTL_CONFDELAY_THRESH and LCB_CNTL_CONFERRTHRESH to modify the throttling settings",
195
+ LCB_NS2US(next_ts-now)/1000, (unsigned)errthresh-errcounter);
196
+ return LCB_SUCCESS;
197
+ }
198
+ }
199
+
200
+ if (options == BS_REFRESH_INITIAL) {
201
+ state = S_INITIAL_PRE;
202
+ parent->confmon->prepare();
203
+ tm.rearm(LCBT_SETTING(parent, config_timeout));
204
+ lcb_aspend_add(&parent->pendops, LCB_PENDTYPE_COUNTER, NULL);
205
+ }
206
+
207
+ /* Reset the counters */
208
+ errcounter = 0;
209
+ if (options != BS_REFRESH_INITIAL) {
210
+ last_refresh = now;
211
+ }
212
+ parent->confmon->start();
213
+ return LCB_SUCCESS;
214
+ }
215
+
216
+ Bootstrap::~Bootstrap() {
217
+ tm.release();
218
+ parent->confmon->remove_listener(this);
219
+ }
220
+
221
+ LIBCOUCHBASE_API
222
+ lcb_error_t
223
+ lcb_get_bootstrap_status(lcb_t instance)
224
+ {
225
+ if (instance->cur_configinfo) {
226
+ return LCB_SUCCESS;
227
+ }
228
+ if (instance->last_error != LCB_SUCCESS) {
229
+ return instance->last_error;
230
+ }
231
+ if (instance->type == LCB_TYPE_CLUSTER) {
232
+ if (lcb::clconfig::http_get_conn(instance->confmon) != NULL || instance->confmon->get_config() != NULL) {
233
+ return LCB_SUCCESS;
234
+ }
235
+ }
236
+ return LCB_ERROR;
237
+ }
238
+
239
+ LIBCOUCHBASE_API
240
+ void
241
+ lcb_refresh_config(lcb_t instance)
242
+ {
243
+ instance->bootstrap(BS_REFRESH_ALWAYS);
244
+ }