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
@@ -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
+ }