libcouchbase 0.3.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,42 +0,0 @@
|
|
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
|
-
#ifndef MEMCACHED_VBUCKET_H
|
19
|
-
#define MEMCACHED_VBUCKET_H 1
|
20
|
-
|
21
|
-
#ifdef __cplusplus
|
22
|
-
extern "C"
|
23
|
-
{
|
24
|
-
#endif
|
25
|
-
|
26
|
-
typedef enum {
|
27
|
-
vbucket_state_active = 1, /**< Actively servicing a vbucket. */
|
28
|
-
vbucket_state_replica, /**< Servicing a vbucket as a replica only. */
|
29
|
-
vbucket_state_pending, /**< Pending active. */
|
30
|
-
vbucket_state_dead /**< Not in use, pending deletion. */
|
31
|
-
} vbucket_state_t;
|
32
|
-
|
33
|
-
#define is_valid_vbucket_state_t(state) \
|
34
|
-
(state == vbucket_state_active || \
|
35
|
-
state == vbucket_state_replica || \
|
36
|
-
state == vbucket_state_pending || \
|
37
|
-
state == vbucket_state_dead)
|
38
|
-
|
39
|
-
#ifdef __cplusplus
|
40
|
-
}
|
41
|
-
#endif
|
42
|
-
#endif
|
@@ -1,269 +0,0 @@
|
|
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
|
-
static void async_step_callback(clconfig_listener*,clconfig_event_t,clconfig_info*);
|
25
|
-
static void initial_bootstrap_error(lcb_t, lcb_error_t,const char*);
|
26
|
-
|
27
|
-
/**
|
28
|
-
* This function is where the configuration actually takes place. We ensure
|
29
|
-
* in other functions that this is only ever called directly from an event
|
30
|
-
* loop stack frame (or one of the small mini functions here) so that we
|
31
|
-
* don't accidentally end up destroying resources underneath us.
|
32
|
-
*/
|
33
|
-
static void
|
34
|
-
config_callback(clconfig_listener *listener, clconfig_event_t event,
|
35
|
-
clconfig_info *info)
|
36
|
-
{
|
37
|
-
struct lcb_BOOTSTRAP *bs = (struct lcb_BOOTSTRAP *)listener;
|
38
|
-
lcb_t instance = bs->parent;
|
39
|
-
|
40
|
-
if (event != CLCONFIG_EVENT_GOT_NEW_CONFIG) {
|
41
|
-
if (event == CLCONFIG_EVENT_PROVIDERS_CYCLED) {
|
42
|
-
if (!LCBT_VBCONFIG(instance)) {
|
43
|
-
initial_bootstrap_error(
|
44
|
-
instance, LCB_ERROR, "No more bootstrap providers remain");
|
45
|
-
}
|
46
|
-
}
|
47
|
-
return;
|
48
|
-
}
|
49
|
-
|
50
|
-
instance->last_error = LCB_SUCCESS;
|
51
|
-
/** Ensure we're not called directly twice again */
|
52
|
-
listener->callback = async_step_callback;
|
53
|
-
lcbio_timer_disarm(bs->tm);
|
54
|
-
|
55
|
-
lcb_log(LOGARGS(instance, DEBUG), "Instance configured!");
|
56
|
-
|
57
|
-
if (info->origin != LCB_CLCONFIG_FILE) {
|
58
|
-
/* Set the timestamp for the current config to control throttling,
|
59
|
-
* but only if it's not an initial file-based config. See CCBC-482 */
|
60
|
-
bs->last_refresh = gethrtime();
|
61
|
-
bs->errcounter = 0;
|
62
|
-
}
|
63
|
-
|
64
|
-
if (info->origin == LCB_CLCONFIG_CCCP) {
|
65
|
-
/* Disable HTTP provider if we've received something via CCCP */
|
66
|
-
|
67
|
-
if (instance->cur_configinfo == NULL ||
|
68
|
-
instance->cur_configinfo->origin != LCB_CLCONFIG_HTTP) {
|
69
|
-
/* Never disable HTTP if it's still being used */
|
70
|
-
lcb_confmon_set_provider_active(
|
71
|
-
instance->confmon, LCB_CLCONFIG_HTTP, 0);
|
72
|
-
}
|
73
|
-
}
|
74
|
-
|
75
|
-
if (instance->type != LCB_TYPE_CLUSTER) {
|
76
|
-
lcb_update_vbconfig(instance, info);
|
77
|
-
}
|
78
|
-
|
79
|
-
if (!bs->bootstrapped) {
|
80
|
-
bs->bootstrapped = 1;
|
81
|
-
lcb_aspend_del(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL);
|
82
|
-
|
83
|
-
if (instance->type == LCB_TYPE_BUCKET &&
|
84
|
-
LCBVB_DISTTYPE(LCBT_VBCONFIG(instance)) == LCBVB_DIST_KETAMA &&
|
85
|
-
instance->cur_configinfo->origin != LCB_CLCONFIG_MCRAW) {
|
86
|
-
|
87
|
-
lcb_log(LOGARGS(instance, INFO), "Reverting to HTTP Config for memcached buckets");
|
88
|
-
instance->settings->bc_http_stream_time = -1;
|
89
|
-
lcb_confmon_set_provider_active(
|
90
|
-
instance->confmon, LCB_CLCONFIG_HTTP, 1);
|
91
|
-
lcb_confmon_set_provider_active(
|
92
|
-
instance->confmon, LCB_CLCONFIG_CCCP, 0);
|
93
|
-
}
|
94
|
-
instance->callbacks.bootstrap(instance, LCB_SUCCESS);
|
95
|
-
}
|
96
|
-
|
97
|
-
lcb_maybe_breakout(instance);
|
98
|
-
}
|
99
|
-
|
100
|
-
|
101
|
-
static void
|
102
|
-
initial_bootstrap_error(lcb_t instance, lcb_error_t err, const char *errinfo)
|
103
|
-
{
|
104
|
-
struct lcb_BOOTSTRAP *bs = instance->bootstrap;
|
105
|
-
|
106
|
-
instance->last_error = lcb_confmon_last_error(instance->confmon);
|
107
|
-
if (instance->last_error == LCB_SUCCESS) {
|
108
|
-
instance->last_error = err;
|
109
|
-
}
|
110
|
-
instance->callbacks.error(instance, instance->last_error, errinfo);
|
111
|
-
lcb_log(LOGARGS(instance, ERR), "Failed to bootstrap client=%p. Code=0x%x, Message=%s", (void *)instance, err, errinfo);
|
112
|
-
lcbio_timer_disarm(bs->tm);
|
113
|
-
|
114
|
-
instance->callbacks.bootstrap(instance, instance->last_error);
|
115
|
-
|
116
|
-
lcb_aspend_del(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL);
|
117
|
-
lcb_maybe_breakout(instance);
|
118
|
-
}
|
119
|
-
|
120
|
-
/**
|
121
|
-
* This it the initial bootstrap timeout handler. This timeout pins down the
|
122
|
-
* instance. It is only scheduled during the initial bootstrap and is only
|
123
|
-
* triggered if the initial bootstrap fails to configure in time.
|
124
|
-
*/
|
125
|
-
static void initial_timeout(void *arg)
|
126
|
-
{
|
127
|
-
struct lcb_BOOTSTRAP *bs = arg;
|
128
|
-
initial_bootstrap_error(bs->parent, LCB_ETIMEDOUT, "Failed to bootstrap in time");
|
129
|
-
}
|
130
|
-
|
131
|
-
/**
|
132
|
-
* Proxy async call to config_callback
|
133
|
-
*/
|
134
|
-
static void async_refresh(void *arg)
|
135
|
-
{
|
136
|
-
/** Get the best configuration and run stuff.. */
|
137
|
-
struct lcb_BOOTSTRAP *bs = arg;
|
138
|
-
clconfig_info *info;
|
139
|
-
|
140
|
-
info = lcb_confmon_get_config(bs->parent->confmon);
|
141
|
-
config_callback(&bs->listener, CLCONFIG_EVENT_GOT_NEW_CONFIG, info);
|
142
|
-
}
|
143
|
-
|
144
|
-
/**
|
145
|
-
* set_next listener callback which schedules an async call to our config
|
146
|
-
* callback.
|
147
|
-
*/
|
148
|
-
static void
|
149
|
-
async_step_callback(clconfig_listener *listener, clconfig_event_t event,
|
150
|
-
clconfig_info *info)
|
151
|
-
{
|
152
|
-
struct lcb_BOOTSTRAP *bs = (struct lcb_BOOTSTRAP *)listener;
|
153
|
-
|
154
|
-
if (event != CLCONFIG_EVENT_GOT_NEW_CONFIG) {
|
155
|
-
return;
|
156
|
-
}
|
157
|
-
|
158
|
-
if (lcbio_timer_armed(bs->tm) && lcbio_timer_get_target(bs->tm) == async_refresh) {
|
159
|
-
lcb_log(LOGARGS(bs->parent, DEBUG), "Timer already present..");
|
160
|
-
return;
|
161
|
-
}
|
162
|
-
|
163
|
-
lcb_log(LOGARGS(bs->parent, INFO), "Got async step callback..");
|
164
|
-
lcbio_timer_set_target(bs->tm, async_refresh);
|
165
|
-
lcbio_async_signal(bs->tm);
|
166
|
-
(void)info;
|
167
|
-
}
|
168
|
-
|
169
|
-
lcb_error_t
|
170
|
-
lcb_bootstrap_common(lcb_t instance, int options)
|
171
|
-
{
|
172
|
-
struct lcb_BOOTSTRAP *bs = instance->bootstrap;
|
173
|
-
hrtime_t now = gethrtime();
|
174
|
-
|
175
|
-
if (!bs) {
|
176
|
-
bs = calloc(1, sizeof(*instance->bootstrap));
|
177
|
-
if (!bs) {
|
178
|
-
return LCB_CLIENT_ENOMEM;
|
179
|
-
}
|
180
|
-
|
181
|
-
bs->tm = lcbio_timer_new(instance->iotable, bs, initial_timeout);
|
182
|
-
instance->bootstrap = bs;
|
183
|
-
bs->parent = instance;
|
184
|
-
lcb_confmon_add_listener(instance->confmon, &bs->listener);
|
185
|
-
}
|
186
|
-
|
187
|
-
if (lcb_confmon_is_refreshing(instance->confmon)) {
|
188
|
-
return LCB_SUCCESS;
|
189
|
-
}
|
190
|
-
|
191
|
-
if (options & LCB_BS_REFRESH_THROTTLE) {
|
192
|
-
/* Refresh throttle requested. This is not true if options == ALWAYS */
|
193
|
-
hrtime_t next_ts;
|
194
|
-
unsigned errthresh = LCBT_SETTING(instance, weird_things_threshold);
|
195
|
-
|
196
|
-
if (options & LCB_BS_REFRESH_INCRERR) {
|
197
|
-
bs->errcounter++;
|
198
|
-
}
|
199
|
-
next_ts = bs->last_refresh;
|
200
|
-
next_ts += LCB_US2NS(LCBT_SETTING(instance, weird_things_delay));
|
201
|
-
if (now < next_ts && bs->errcounter < errthresh) {
|
202
|
-
lcb_log(LOGARGS(instance, INFO),
|
203
|
-
"Not requesting a config refresh because of throttling parameters. Next refresh possible in %ums or %u errors. "
|
204
|
-
"See LCB_CNTL_CONFDELAY_THRESH and LCB_CNTL_CONFERRTHRESH to modify the throttling settings",
|
205
|
-
LCB_NS2US(next_ts-now)/1000, (unsigned)errthresh-bs->errcounter);
|
206
|
-
return LCB_SUCCESS;
|
207
|
-
}
|
208
|
-
}
|
209
|
-
|
210
|
-
if (options == LCB_BS_REFRESH_INITIAL) {
|
211
|
-
lcb_confmon_prepare(instance->confmon);
|
212
|
-
|
213
|
-
bs->listener.callback = config_callback;
|
214
|
-
lcbio_timer_set_target(bs->tm, initial_timeout);
|
215
|
-
lcbio_timer_rearm(bs->tm, LCBT_SETTING(instance, config_timeout));
|
216
|
-
lcb_aspend_add(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL);
|
217
|
-
} else {
|
218
|
-
/** No initial timer */
|
219
|
-
bs->listener.callback = async_step_callback;
|
220
|
-
}
|
221
|
-
|
222
|
-
/* Reset the counters */
|
223
|
-
bs->errcounter = 0;
|
224
|
-
if (options != LCB_BS_REFRESH_INITIAL) {
|
225
|
-
bs->last_refresh = now;
|
226
|
-
}
|
227
|
-
return lcb_confmon_start(instance->confmon);
|
228
|
-
}
|
229
|
-
|
230
|
-
void lcb_bootstrap_destroy(lcb_t instance)
|
231
|
-
{
|
232
|
-
struct lcb_BOOTSTRAP *bs = instance->bootstrap;
|
233
|
-
if (!bs) {
|
234
|
-
return;
|
235
|
-
}
|
236
|
-
if (bs->tm) {
|
237
|
-
lcbio_timer_destroy(bs->tm);
|
238
|
-
}
|
239
|
-
|
240
|
-
lcb_confmon_remove_listener(instance->confmon, &bs->listener);
|
241
|
-
free(bs);
|
242
|
-
instance->bootstrap = NULL;
|
243
|
-
}
|
244
|
-
|
245
|
-
LIBCOUCHBASE_API
|
246
|
-
lcb_error_t
|
247
|
-
lcb_get_bootstrap_status(lcb_t instance)
|
248
|
-
{
|
249
|
-
if (instance->cur_configinfo) {
|
250
|
-
return LCB_SUCCESS;
|
251
|
-
}
|
252
|
-
if (instance->last_error != LCB_SUCCESS) {
|
253
|
-
return instance->last_error;
|
254
|
-
}
|
255
|
-
if (instance->type == LCB_TYPE_CLUSTER) {
|
256
|
-
lcbio_SOCKET *restconn = lcb_confmon_get_rest_connection(instance->confmon);
|
257
|
-
if (restconn) {
|
258
|
-
return LCB_SUCCESS;
|
259
|
-
}
|
260
|
-
}
|
261
|
-
return LCB_ERROR;
|
262
|
-
}
|
263
|
-
|
264
|
-
LIBCOUCHBASE_API
|
265
|
-
void
|
266
|
-
lcb_refresh_config(lcb_t instance)
|
267
|
-
{
|
268
|
-
lcb_bootstrap_common(instance, LCB_BS_REFRESH_ALWAYS);
|
269
|
-
}
|
@@ -1,347 +0,0 @@
|
|
1
|
-
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
-
/*
|
3
|
-
* Copyright 2013 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
|
-
#include "internal.h"
|
19
|
-
#include "clconfig.h"
|
20
|
-
#include "simplestring.h"
|
21
|
-
#include <lcbio/lcbio.h>
|
22
|
-
#include <lcbio/timer-ng.h>
|
23
|
-
|
24
|
-
#define CONFIG_CACHE_MAGIC "{{{fb85b563d0a8f65fa8d3d58f1b3a0708}}}"
|
25
|
-
|
26
|
-
#define LOGARGS(pb, lvl) pb->base.parent->settings, "bc_file", LCB_LOG_##lvl, __FILE__, __LINE__
|
27
|
-
#define LOGFMT "(cache=%s) "
|
28
|
-
#define LOGID(fb) fb->filename
|
29
|
-
|
30
|
-
typedef struct {
|
31
|
-
clconfig_provider base;
|
32
|
-
char *filename;
|
33
|
-
clconfig_info *config;
|
34
|
-
time_t last_mtime;
|
35
|
-
int last_errno;
|
36
|
-
int ro_mode; /* Whether the config cache should _not_ overwrite the file */
|
37
|
-
lcbio_pTIMER timer;
|
38
|
-
clconfig_listener listener;
|
39
|
-
} file_provider;
|
40
|
-
|
41
|
-
static int load_cache(file_provider *provider)
|
42
|
-
{
|
43
|
-
lcb_string str;
|
44
|
-
char line[1024];
|
45
|
-
lcb_ssize_t nr;
|
46
|
-
int fail;
|
47
|
-
FILE *fp = NULL;
|
48
|
-
lcbvb_CONFIG *config = NULL;
|
49
|
-
char *end;
|
50
|
-
struct stat st;
|
51
|
-
int status = -1;
|
52
|
-
|
53
|
-
lcb_string_init(&str);
|
54
|
-
|
55
|
-
if (provider->filename == NULL) {
|
56
|
-
return -1;
|
57
|
-
}
|
58
|
-
|
59
|
-
fp = fopen(provider->filename, "r");
|
60
|
-
if (fp == NULL) {
|
61
|
-
int save_errno = errno;
|
62
|
-
lcb_log(LOGARGS(provider, ERROR), LOGFMT "Couldn't open for reading: %s", LOGID(provider), strerror(save_errno));
|
63
|
-
return -1;
|
64
|
-
}
|
65
|
-
|
66
|
-
if (fstat(fileno(fp), &st)) {
|
67
|
-
provider->last_errno = errno;
|
68
|
-
goto GT_DONE;
|
69
|
-
}
|
70
|
-
|
71
|
-
if (provider->last_mtime == st.st_mtime) {
|
72
|
-
lcb_log(LOGARGS(provider, WARN), LOGFMT "Modification time too old", LOGID(provider));
|
73
|
-
goto GT_DONE;
|
74
|
-
}
|
75
|
-
|
76
|
-
config = lcbvb_create();
|
77
|
-
if (config == NULL) {
|
78
|
-
goto GT_DONE;
|
79
|
-
}
|
80
|
-
|
81
|
-
lcb_string_init(&str);
|
82
|
-
|
83
|
-
while ((nr = fread(line, 1, sizeof(line), fp)) > 0) {
|
84
|
-
if (lcb_string_append(&str, line, nr)) {
|
85
|
-
goto GT_DONE;
|
86
|
-
}
|
87
|
-
}
|
88
|
-
|
89
|
-
if (ferror(fp)) {
|
90
|
-
goto GT_DONE;
|
91
|
-
}
|
92
|
-
|
93
|
-
fclose(fp);
|
94
|
-
fp = NULL;
|
95
|
-
|
96
|
-
if (!str.nused) {
|
97
|
-
status = -1;
|
98
|
-
goto GT_DONE;
|
99
|
-
}
|
100
|
-
|
101
|
-
end = strstr(str.base, CONFIG_CACHE_MAGIC);
|
102
|
-
if (end == NULL) {
|
103
|
-
lcb_log(LOGARGS(provider, ERROR), LOGFMT "Couldn't find magic", LOGID(provider));
|
104
|
-
if (!provider->ro_mode) {
|
105
|
-
remove(provider->filename);
|
106
|
-
}
|
107
|
-
status = -1;
|
108
|
-
goto GT_DONE;
|
109
|
-
}
|
110
|
-
|
111
|
-
fail = lcbvb_load_json(config, str.base);
|
112
|
-
if (fail) {
|
113
|
-
status = -1;
|
114
|
-
lcb_log(LOGARGS(provider, ERROR), LOGFMT "Couldn't parse configuration", LOGID(provider));
|
115
|
-
lcb_log_badconfig(LOGARGS(provider, ERROR), config, str.base);
|
116
|
-
if (!provider->ro_mode) {
|
117
|
-
remove(provider->filename);
|
118
|
-
}
|
119
|
-
goto GT_DONE;
|
120
|
-
}
|
121
|
-
|
122
|
-
if (lcbvb_get_distmode(config) != LCBVB_DIST_VBUCKET) {
|
123
|
-
status = -1;
|
124
|
-
lcb_log(LOGARGS(provider, ERROR), LOGFMT "Not applying cached memcached config", LOGID(provider));
|
125
|
-
goto GT_DONE;
|
126
|
-
}
|
127
|
-
|
128
|
-
if (strcmp(config->bname, PROVIDER_SETTING(&provider->base, bucket)) != 0) {
|
129
|
-
status = -1;
|
130
|
-
lcb_log(LOGARGS(provider, ERROR), LOGFMT "Bucket name in file is different from the one requested", LOGID(provider));
|
131
|
-
}
|
132
|
-
|
133
|
-
if (provider->config) {
|
134
|
-
lcb_clconfig_decref(provider->config);
|
135
|
-
}
|
136
|
-
|
137
|
-
provider->config = lcb_clconfig_create(config, LCB_CLCONFIG_FILE);
|
138
|
-
provider->config->cmpclock = gethrtime();
|
139
|
-
provider->config->origin = provider->base.type;
|
140
|
-
provider->last_mtime = st.st_mtime;
|
141
|
-
status = 0;
|
142
|
-
config = NULL;
|
143
|
-
|
144
|
-
GT_DONE:
|
145
|
-
if (fp != NULL) {
|
146
|
-
fclose(fp);
|
147
|
-
}
|
148
|
-
|
149
|
-
if (config != NULL) {
|
150
|
-
lcbvb_destroy(config);
|
151
|
-
}
|
152
|
-
|
153
|
-
lcb_string_release(&str);
|
154
|
-
return status;
|
155
|
-
}
|
156
|
-
|
157
|
-
static void
|
158
|
-
write_to_file(file_provider *provider, lcbvb_CONFIG *cfg)
|
159
|
-
{
|
160
|
-
FILE *fp;
|
161
|
-
|
162
|
-
if (provider->filename == NULL || provider->ro_mode) {
|
163
|
-
return;
|
164
|
-
}
|
165
|
-
|
166
|
-
fp = fopen(provider->filename, "w");
|
167
|
-
if (fp) {
|
168
|
-
char *json = lcbvb_save_json(cfg);
|
169
|
-
lcb_log(LOGARGS(provider, INFO), LOGFMT "Writing configuration to file", LOGID(provider));
|
170
|
-
fprintf(fp, "%s%s", json, CONFIG_CACHE_MAGIC);
|
171
|
-
fclose(fp);
|
172
|
-
free(json);
|
173
|
-
} else {
|
174
|
-
int save_errno = errno;
|
175
|
-
lcb_log(LOGARGS(provider, ERROR), LOGFMT "Couldn't open file for writing: %s", LOGID(provider), strerror(save_errno));
|
176
|
-
}
|
177
|
-
}
|
178
|
-
|
179
|
-
static clconfig_info * get_cached(clconfig_provider *pb)
|
180
|
-
{
|
181
|
-
file_provider *provider = (file_provider *)pb;
|
182
|
-
if (!provider->filename) {
|
183
|
-
return NULL;
|
184
|
-
}
|
185
|
-
|
186
|
-
return provider->config;
|
187
|
-
}
|
188
|
-
|
189
|
-
static void async_callback(void *cookie)
|
190
|
-
{
|
191
|
-
time_t last_mtime;
|
192
|
-
file_provider *provider = (file_provider *)cookie;
|
193
|
-
last_mtime = provider->last_mtime;
|
194
|
-
if (load_cache(provider) == 0) {
|
195
|
-
if (last_mtime != provider->last_mtime) {
|
196
|
-
lcb_confmon_provider_success(&provider->base, provider->config);
|
197
|
-
return;
|
198
|
-
}
|
199
|
-
}
|
200
|
-
|
201
|
-
lcb_confmon_provider_failed(&provider->base, LCB_ERROR);
|
202
|
-
}
|
203
|
-
|
204
|
-
static lcb_error_t refresh_file(clconfig_provider *pb)
|
205
|
-
{
|
206
|
-
file_provider *provider = (file_provider *)pb;
|
207
|
-
if (lcbio_timer_armed(provider->timer)) {
|
208
|
-
return LCB_SUCCESS;
|
209
|
-
}
|
210
|
-
|
211
|
-
lcbio_async_signal(provider->timer);
|
212
|
-
return LCB_SUCCESS;
|
213
|
-
}
|
214
|
-
|
215
|
-
static lcb_error_t pause_file(clconfig_provider *pb)
|
216
|
-
{
|
217
|
-
(void)pb;
|
218
|
-
return LCB_SUCCESS;
|
219
|
-
}
|
220
|
-
|
221
|
-
static void shutdown_file(clconfig_provider *pb)
|
222
|
-
{
|
223
|
-
file_provider *provider = (file_provider *)pb;
|
224
|
-
free(provider->filename);
|
225
|
-
if (provider->timer) {
|
226
|
-
lcbio_timer_destroy(provider->timer);
|
227
|
-
}
|
228
|
-
if (provider->config) {
|
229
|
-
lcb_clconfig_decref(provider->config);
|
230
|
-
}
|
231
|
-
free(provider);
|
232
|
-
}
|
233
|
-
|
234
|
-
static void config_listener(clconfig_listener *lsn, clconfig_event_t event,
|
235
|
-
clconfig_info *info)
|
236
|
-
{
|
237
|
-
file_provider *provider;
|
238
|
-
|
239
|
-
if (event != CLCONFIG_EVENT_GOT_NEW_CONFIG) {
|
240
|
-
return;
|
241
|
-
}
|
242
|
-
|
243
|
-
provider = (file_provider *) (void*)(((char *)lsn) - offsetof(file_provider, listener));
|
244
|
-
if (!provider->base.enabled) {
|
245
|
-
return;
|
246
|
-
}
|
247
|
-
|
248
|
-
if (info->origin == LCB_CLCONFIG_PHONY || info->origin == LCB_CLCONFIG_FILE) {
|
249
|
-
lcb_log(LOGARGS(provider, TRACE), "Not writing configuration originating from PHONY or FILE to cache");
|
250
|
-
return;
|
251
|
-
}
|
252
|
-
|
253
|
-
write_to_file(provider, info->vbc);
|
254
|
-
}
|
255
|
-
|
256
|
-
static void
|
257
|
-
do_file_dump(clconfig_provider *pb, FILE *fp)
|
258
|
-
{
|
259
|
-
file_provider *pr = (file_provider *)pb;
|
260
|
-
|
261
|
-
fprintf(fp, "## BEGIN FILE PROVIEDER DUMP ##\n");
|
262
|
-
if (pr->filename) {
|
263
|
-
fprintf(fp, "FILENAME: %s\n", pr->filename);
|
264
|
-
}
|
265
|
-
fprintf(fp, "LAST SYSTEM ERRNO: %d\n", pr->last_errno);
|
266
|
-
fprintf(fp, "LAST MTIME: %lu\n", (unsigned long)pr->last_mtime);
|
267
|
-
fprintf(fp, "## END FILE PROVIDER DUMP ##\n");
|
268
|
-
|
269
|
-
}
|
270
|
-
|
271
|
-
clconfig_provider * lcb_clconfig_create_file(lcb_confmon *parent)
|
272
|
-
{
|
273
|
-
file_provider *provider = calloc(1, sizeof(*provider));
|
274
|
-
|
275
|
-
if (!provider) {
|
276
|
-
return NULL;
|
277
|
-
}
|
278
|
-
|
279
|
-
provider->base.get_cached = get_cached;
|
280
|
-
provider->base.refresh = refresh_file;
|
281
|
-
provider->base.pause = pause_file;
|
282
|
-
provider->base.shutdown = shutdown_file;
|
283
|
-
provider->base.dump = do_file_dump;
|
284
|
-
provider->base.type = LCB_CLCONFIG_FILE;
|
285
|
-
provider->listener.callback = config_listener;
|
286
|
-
provider->timer = lcbio_timer_new(parent->iot, provider, async_callback);
|
287
|
-
|
288
|
-
lcb_confmon_add_listener(parent, &provider->listener);
|
289
|
-
|
290
|
-
return &provider->base;
|
291
|
-
}
|
292
|
-
|
293
|
-
|
294
|
-
static char *mkcachefile(const char *name, const char *bucket)
|
295
|
-
{
|
296
|
-
if (name != NULL) {
|
297
|
-
return strdup(name);
|
298
|
-
} else {
|
299
|
-
char buffer[1024];
|
300
|
-
const char *tmpdir = lcb_get_tmpdir();
|
301
|
-
|
302
|
-
snprintf(buffer, sizeof(buffer),
|
303
|
-
"%s/%s", tmpdir ? tmpdir : ".", bucket);
|
304
|
-
return strdup(buffer);
|
305
|
-
}
|
306
|
-
}
|
307
|
-
|
308
|
-
int lcb_clconfig_file_set_filename(clconfig_provider *p, const char *f, int ro)
|
309
|
-
{
|
310
|
-
file_provider *provider = (file_provider *)p;
|
311
|
-
lcb_assert(provider->base.type == LCB_CLCONFIG_FILE);
|
312
|
-
provider->base.enabled = 1;
|
313
|
-
|
314
|
-
if (provider->filename) {
|
315
|
-
free(provider->filename);
|
316
|
-
}
|
317
|
-
|
318
|
-
provider->filename = mkcachefile(f, p->parent->settings->bucket);
|
319
|
-
|
320
|
-
if (ro) {
|
321
|
-
FILE *fp_tmp;
|
322
|
-
provider->ro_mode = 1;
|
323
|
-
|
324
|
-
fp_tmp = fopen(provider->filename, "r");
|
325
|
-
if (!fp_tmp) {
|
326
|
-
lcb_log(LOGARGS(provider, ERROR), LOGFMT "Couldn't open for reading: %s", LOGID(provider), strerror(errno));
|
327
|
-
return -1;
|
328
|
-
} else {
|
329
|
-
fclose(fp_tmp);
|
330
|
-
}
|
331
|
-
}
|
332
|
-
|
333
|
-
return 0;
|
334
|
-
}
|
335
|
-
|
336
|
-
const char *
|
337
|
-
lcb_clconfig_file_get_filename(clconfig_provider *p)
|
338
|
-
{
|
339
|
-
file_provider *fp = (file_provider *)p;
|
340
|
-
return fp->filename;
|
341
|
-
}
|
342
|
-
|
343
|
-
void
|
344
|
-
lcb_clconfig_file_set_readonly(clconfig_provider *p, int val)
|
345
|
-
{
|
346
|
-
((file_provider *)p)->ro_mode = val;
|
347
|
-
}
|