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.
- checksums.yaml +4 -4
- data/ext/libcouchbase/CMakeLists.txt +6 -8
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +21 -5
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
- data/ext/libcouchbase/example/users/README +48 -0
- data/ext/libcouchbase/example/users/users.c +147 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
- data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
- data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
- data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
- data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
- data/ext/libcouchbase/src/README.md +0 -2
- data/ext/libcouchbase/src/auth-priv.h +23 -4
- data/ext/libcouchbase/src/auth.cc +51 -43
- data/ext/libcouchbase/src/bootstrap.cc +244 -0
- data/ext/libcouchbase/src/bootstrap.h +58 -38
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +56 -22
- data/ext/libcouchbase/src/connspec.cc +47 -6
- data/ext/libcouchbase/src/connspec.h +27 -0
- data/ext/libcouchbase/src/dns-srv.cc +147 -0
- data/ext/libcouchbase/src/dump.cc +3 -3
- data/ext/libcouchbase/src/errmap.cc +173 -0
- data/ext/libcouchbase/src/errmap.h +198 -0
- data/ext/libcouchbase/src/getconfig.cc +7 -33
- data/ext/libcouchbase/src/handler.cc +118 -7
- data/ext/libcouchbase/src/hostlist.cc +0 -36
- data/ext/libcouchbase/src/hostlist.h +44 -62
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +27 -35
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +28 -36
- data/ext/libcouchbase/src/instance.cc +131 -34
- data/ext/libcouchbase/src/internal.h +58 -26
- data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
- data/ext/libcouchbase/src/jsparse/parser.h +84 -98
- data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
- data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
- data/ext/libcouchbase/src/lcbio/connect.h +16 -7
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
- data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
- data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
- data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
- data/ext/libcouchbase/src/lcbio/manager.h +133 -96
- data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.c +11 -2
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
- data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
- data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
- data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
- data/ext/libcouchbase/src/mctx-helper.h +51 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
- data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
- data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
- data/ext/libcouchbase/src/newconfig.cc +6 -6
- data/ext/libcouchbase/src/nodeinfo.cc +2 -2
- data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
- data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
- data/ext/libcouchbase/src/operations/durability.cc +6 -26
- data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
- data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
- data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
- data/ext/libcouchbase/src/operations/stats.cc +3 -8
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +30 -2
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/rdb/rope.c +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
- data/ext/libcouchbase/src/retryq.cc +52 -14
- data/ext/libcouchbase/src/retryq.h +3 -3
- data/ext/libcouchbase/src/settings.c +5 -0
- data/ext/libcouchbase/src/settings.h +11 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
- data/ext/libcouchbase/src/trace.h +4 -4
- data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
- data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
- data/ext/libcouchbase/src/views/docreq.h +24 -30
- data/ext/libcouchbase/src/views/viewreq.cc +318 -0
- data/ext/libcouchbase/src/views/viewreq.h +43 -13
- data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
- data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
- data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
- data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
- data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
- data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
- data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
- data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
- data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
- data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
- data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
- data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
- data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
- data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
- data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
- data/ext/libcouchbase/tools/cbc.cc +143 -10
- data/ext/libcouchbase/tools/docgen/loc.h +1 -1
- data/lib/libcouchbase/connection.rb +4 -3
- data/lib/libcouchbase/version.rb +1 -1
- metadata +37 -28
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
- data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/lcbio/manager.c +0 -584
- data/ext/libcouchbase/src/packetutils.c +0 -37
- data/ext/libcouchbase/src/simplestring.c +0 -211
- data/ext/libcouchbase/src/simplestring.h +0 -228
- data/ext/libcouchbase/src/ssobuf.h +0 -82
- data/ext/libcouchbase/src/views/viewreq.c +0 -358
- data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
|
@@ -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
|
|
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
|
|
23
|
-
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
74
|
+
return it->second;
|
|
68
75
|
}
|
|
69
76
|
} else {
|
|
70
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
{
|
|
90
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
lcb_AUTHENTICATOR *
|
|
100
|
+
lcbauth_clone(const lcb_AUTHENTICATOR *src) {
|
|
101
|
+
return new Authenticator(*src);
|
|
102
|
+
}
|
|
96
103
|
|
|
97
|
-
|
|
98
|
-
|
|
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
|
+
}
|