libcouchbase 0.0.7 → 0.0.8
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/.gitignore +2 -0
- data/ext/libcouchbase/CMakeLists.txt +5 -7
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +49 -0
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +2 -1
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +34 -14
- data/ext/libcouchbase/configure.pl +1 -1
- data/ext/libcouchbase/contrib/genhash/genhash.h +6 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +10 -0
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +10 -0
- data/ext/libcouchbase/include/libcouchbase/error.h +7 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +13 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +9 -0
- 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 +21 -1132
- 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 +1 -0
- data/ext/libcouchbase/src/auth.cc +10 -0
- data/ext/libcouchbase/src/bootstrap.cc +216 -0
- data/ext/libcouchbase/src/bootstrap.h +50 -39
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +455 -0
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +528 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +115 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +407 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +378 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +24 -24
- data/ext/libcouchbase/src/connspec.cc +30 -1
- data/ext/libcouchbase/src/connspec.h +17 -0
- data/ext/libcouchbase/src/dns-srv.cc +143 -0
- data/ext/libcouchbase/src/{dump.c → dump.cc} +8 -11
- data/ext/libcouchbase/src/getconfig.cc +73 -0
- data/ext/libcouchbase/src/handler.cc +84 -85
- data/ext/libcouchbase/src/hostlist.cc +0 -1
- data/ext/libcouchbase/src/hostlist.h +6 -1
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +9 -29
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +22 -26
- data/ext/libcouchbase/src/instance.cc +102 -28
- data/ext/libcouchbase/src/internal.h +47 -29
- data/ext/libcouchbase/src/jsparse/parser.cc +146 -202
- data/ext/libcouchbase/src/jsparse/parser.h +91 -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 +562 -0
- data/ext/libcouchbase/src/lcbio/connect.h +9 -2
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +61 -16
- data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
- data/ext/libcouchbase/src/lcbio/manager.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +723 -0
- data/ext/libcouchbase/src/mcserver/mcserver.h +160 -70
- data/ext/libcouchbase/src/mcserver/negotiate.cc +118 -152
- data/ext/libcouchbase/src/mcserver/negotiate.h +85 -74
- 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 +56 -32
- data/ext/libcouchbase/src/{newconfig.c → newconfig.cc} +42 -70
- data/ext/libcouchbase/src/nodeinfo.cc +4 -8
- 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-cas.c → durability-cas.cc} +92 -76
- data/ext/libcouchbase/src/operations/{durability-seqno.c → durability-seqno.cc} +55 -49
- data/ext/libcouchbase/src/operations/durability.cc +643 -0
- data/ext/libcouchbase/src/operations/durability_internal.h +212 -124
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe-seqno.c → observe-seqno.cc} +5 -8
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +69 -94
- 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.c → stats.cc} +66 -78
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +38 -18
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +200 -137
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +3 -4
- data/ext/libcouchbase/src/retryq.cc +394 -0
- data/ext/libcouchbase/src/retryq.h +116 -104
- data/ext/libcouchbase/src/settings.h +2 -1
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/trace.h +8 -8
- data/ext/libcouchbase/src/vbucket/vbucket.c +0 -1
- 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/src/{wait.c → wait.cc} +12 -17
- data/ext/libcouchbase/tests/basic/t_connstr.cc +89 -50
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -78
- data/ext/libcouchbase/tests/basic/t_packet.cc +35 -42
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +94 -111
- data/ext/libcouchbase/tests/iotests/t_sched.cc +1 -2
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
- data/lib/libcouchbase/version.rb +1 -1
- metadata +36 -39
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +0 -495
- 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/getconfig.c +0 -100
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/mcserver/mcserver.c +0 -784
- data/ext/libcouchbase/src/operations/durability.c +0 -668
- data/ext/libcouchbase/src/packetutils.c +0 -60
- data/ext/libcouchbase/src/retryq.c +0 -424
- 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,495 +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
|
-
/**
|
|
19
|
-
* This file contains the CCCP (Cluster Carrier Configuration Protocol)
|
|
20
|
-
* implementation of the confmon provider. It utilizes a memcached connection
|
|
21
|
-
* to retrieve configuration information.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
#include "internal.h"
|
|
25
|
-
#include "clconfig.h"
|
|
26
|
-
#include "packetutils.h"
|
|
27
|
-
#include "simplestring.h"
|
|
28
|
-
#include <mcserver/negotiate.h>
|
|
29
|
-
#include <lcbio/lcbio.h>
|
|
30
|
-
#include <lcbio/timer-ng.h>
|
|
31
|
-
#include <lcbio/ssl.h>
|
|
32
|
-
#include "ctx-log-inl.h"
|
|
33
|
-
#define LOGARGS(cccp, lvl) cccp->base.parent->settings, "cccp", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
34
|
-
#define LOGFMT "<%s:%s> "
|
|
35
|
-
#define LOGID(cccp) get_ctx_host(cccp->ioctx), get_ctx_port(cccp->ioctx)
|
|
36
|
-
|
|
37
|
-
struct cccp_cookie_st;
|
|
38
|
-
|
|
39
|
-
typedef struct {
|
|
40
|
-
clconfig_provider base;
|
|
41
|
-
hostlist_t nodes;
|
|
42
|
-
clconfig_info *config;
|
|
43
|
-
int server_active;
|
|
44
|
-
int disabled;
|
|
45
|
-
lcbio_pTIMER timer;
|
|
46
|
-
lcb_t instance;
|
|
47
|
-
lcbio_CONNREQ creq;
|
|
48
|
-
lcbio_CTX *ioctx;
|
|
49
|
-
struct cccp_cookie_st *cmdcookie;
|
|
50
|
-
} cccp_provider;
|
|
51
|
-
|
|
52
|
-
typedef struct cccp_cookie_st {
|
|
53
|
-
/** Parent object */
|
|
54
|
-
cccp_provider *parent;
|
|
55
|
-
|
|
56
|
-
/** Whether to ignore errors on this cookie object */
|
|
57
|
-
int ignore_errors;
|
|
58
|
-
} cccp_cookie;
|
|
59
|
-
|
|
60
|
-
static void io_error_handler(lcbio_CTX *, lcb_error_t);
|
|
61
|
-
static void io_read_handler(lcbio_CTX *, unsigned nr);
|
|
62
|
-
static void request_config(cccp_provider *);
|
|
63
|
-
static void on_connected(lcbio_SOCKET *, void*, lcb_error_t, lcbio_OSERR);
|
|
64
|
-
|
|
65
|
-
static void
|
|
66
|
-
pooled_close_cb(lcbio_SOCKET *sock, int reusable, void *arg)
|
|
67
|
-
{
|
|
68
|
-
int *ru_ex = arg;
|
|
69
|
-
lcbio_ref(sock);
|
|
70
|
-
if (reusable && *ru_ex) {
|
|
71
|
-
lcbio_mgr_put(sock);
|
|
72
|
-
} else {
|
|
73
|
-
lcbio_mgr_discard(sock);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
static void release_socket(cccp_provider *cccp, int can_reuse)
|
|
78
|
-
{
|
|
79
|
-
if (cccp->cmdcookie) {
|
|
80
|
-
cccp->cmdcookie->ignore_errors = 1;
|
|
81
|
-
cccp->cmdcookie = NULL;
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
lcbio_connreq_cancel(&cccp->creq);
|
|
86
|
-
|
|
87
|
-
if (cccp->ioctx) {
|
|
88
|
-
lcbio_ctx_close(cccp->ioctx, pooled_close_cb, &can_reuse);
|
|
89
|
-
cccp->ioctx = NULL;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
static lcb_error_t
|
|
94
|
-
schedule_next_request(cccp_provider *cccp, lcb_error_t err, int can_rollover)
|
|
95
|
-
{
|
|
96
|
-
mc_SERVER *server;
|
|
97
|
-
lcb_host_t *next_host = hostlist_shift_next(cccp->nodes, can_rollover);
|
|
98
|
-
if (!next_host) {
|
|
99
|
-
lcbio_timer_disarm(cccp->timer);
|
|
100
|
-
lcb_confmon_provider_failed(&cccp->base, err);
|
|
101
|
-
cccp->server_active = 0;
|
|
102
|
-
return err;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
server = lcb_find_server_by_host(cccp->instance, next_host);
|
|
106
|
-
if (server) {
|
|
107
|
-
cccp_cookie *cookie = calloc(1, sizeof(*cookie));
|
|
108
|
-
cccp->cmdcookie = cookie;
|
|
109
|
-
cookie->parent = cccp;
|
|
110
|
-
lcb_log(LOGARGS(cccp, INFO), "Re-Issuing CCCP Command on server struct %p (%s:%s)", (void*)server, next_host->host, next_host->port);
|
|
111
|
-
lcbio_timer_rearm(
|
|
112
|
-
cccp->timer, PROVIDER_SETTING(&cccp->base, config_node_timeout));
|
|
113
|
-
return lcb_getconfig(cccp->instance, cookie, server);
|
|
114
|
-
|
|
115
|
-
} else {
|
|
116
|
-
lcbio_pMGRREQ preq;
|
|
117
|
-
|
|
118
|
-
lcb_log(LOGARGS(cccp, INFO), "Requesting connection to node %s:%s for CCCP configuration", next_host->host, next_host->port);
|
|
119
|
-
preq = lcbio_mgr_get(
|
|
120
|
-
cccp->instance->memd_sockpool, next_host,
|
|
121
|
-
PROVIDER_SETTING(&cccp->base, config_node_timeout),
|
|
122
|
-
on_connected, cccp);
|
|
123
|
-
LCBIO_CONNREQ_MKPOOLED(&cccp->creq, preq);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
cccp->server_active = 1;
|
|
127
|
-
return LCB_SUCCESS;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
static lcb_error_t mcio_error(cccp_provider *cccp, lcb_error_t err)
|
|
131
|
-
{
|
|
132
|
-
if (err != LCB_NOT_SUPPORTED && err != LCB_UNKNOWN_COMMAND) {
|
|
133
|
-
lcb_log(LOGARGS(cccp, ERR), LOGFMT "Got I/O Error=0x%x", LOGID(cccp), err);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
release_socket(cccp, err == LCB_NOT_SUPPORTED);
|
|
137
|
-
return schedule_next_request(cccp, err, 0);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
static void socket_timeout(void *arg)
|
|
141
|
-
{
|
|
142
|
-
cccp_provider *cccp = arg;
|
|
143
|
-
mcio_error(cccp, LCB_ETIMEDOUT);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
void lcb_clconfig_cccp_enable(clconfig_provider *pb, lcb_t instance)
|
|
147
|
-
{
|
|
148
|
-
cccp_provider *cccp = (cccp_provider *)pb;
|
|
149
|
-
lcb_assert(pb->type == LCB_CLCONFIG_CCCP);
|
|
150
|
-
cccp->instance = instance;
|
|
151
|
-
pb->enabled = 1;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
static hostlist_t get_nodes(const clconfig_provider *pb)
|
|
155
|
-
{
|
|
156
|
-
return ((cccp_provider *)pb)->nodes;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/** Update the configuration from a server. */
|
|
160
|
-
lcb_error_t lcb_cccp_update(clconfig_provider *provider,
|
|
161
|
-
const char *host,
|
|
162
|
-
lcb_string *data)
|
|
163
|
-
{
|
|
164
|
-
/** TODO: replace this with lcbvb_ names */
|
|
165
|
-
|
|
166
|
-
lcbvb_CONFIG* vbc;
|
|
167
|
-
int rv;
|
|
168
|
-
clconfig_info *new_config;
|
|
169
|
-
cccp_provider *cccp = (cccp_provider *)provider;
|
|
170
|
-
vbc = lcbvb_create();
|
|
171
|
-
|
|
172
|
-
if (!vbc) {
|
|
173
|
-
return LCB_CLIENT_ENOMEM;
|
|
174
|
-
}
|
|
175
|
-
rv = lcbvb_load_json(vbc, data->base);
|
|
176
|
-
|
|
177
|
-
if (rv) {
|
|
178
|
-
lcb_log(LOGARGS(cccp, ERROR), LOGFMT "Failed to parse config", LOGID(cccp));
|
|
179
|
-
lcb_log_badconfig(LOGARGS(cccp, ERROR), vbc, data->base);
|
|
180
|
-
lcbvb_destroy(vbc);
|
|
181
|
-
return LCB_PROTOCOL_ERROR;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
lcbvb_replace_host(vbc, host);
|
|
185
|
-
new_config = lcb_clconfig_create(vbc, LCB_CLCONFIG_CCCP);
|
|
186
|
-
|
|
187
|
-
if (!new_config) {
|
|
188
|
-
lcbvb_destroy(vbc);
|
|
189
|
-
return LCB_CLIENT_ENOMEM;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (cccp->config) {
|
|
193
|
-
lcb_clconfig_decref(cccp->config);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/** TODO: Figure out the comparison vector */
|
|
197
|
-
new_config->cmpclock = gethrtime();
|
|
198
|
-
cccp->config = new_config;
|
|
199
|
-
lcb_confmon_provider_success(provider, new_config);
|
|
200
|
-
return LCB_SUCCESS;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
void lcb_cccp_update2(const void *cookie, lcb_error_t err,
|
|
204
|
-
const void *bytes, lcb_size_t nbytes,
|
|
205
|
-
const lcb_host_t *origin)
|
|
206
|
-
{
|
|
207
|
-
cccp_cookie *ck = (cccp_cookie *)cookie;
|
|
208
|
-
cccp_provider *cccp = ck->parent;
|
|
209
|
-
|
|
210
|
-
if (ck == cccp->cmdcookie) {
|
|
211
|
-
lcbio_timer_disarm(cccp->timer);
|
|
212
|
-
cccp->cmdcookie = NULL;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (err == LCB_SUCCESS) {
|
|
216
|
-
lcb_string ss;
|
|
217
|
-
|
|
218
|
-
lcb_string_init(&ss);
|
|
219
|
-
lcb_string_append(&ss, bytes, nbytes);
|
|
220
|
-
err = lcb_cccp_update(&cccp->base, origin->host, &ss);
|
|
221
|
-
lcb_string_release(&ss);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (err != LCB_SUCCESS && ck->ignore_errors == 0) {
|
|
225
|
-
mcio_error(cccp, err);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
free(ck);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
static void
|
|
232
|
-
on_connected(lcbio_SOCKET *sock, void *data, lcb_error_t err, lcbio_OSERR syserr)
|
|
233
|
-
{
|
|
234
|
-
lcbio_CTXPROCS ioprocs;
|
|
235
|
-
cccp_provider *cccp = data;
|
|
236
|
-
lcb_settings *settings = cccp->base.parent->settings;
|
|
237
|
-
|
|
238
|
-
LCBIO_CONNREQ_CLEAR(&cccp->creq);
|
|
239
|
-
if (err != LCB_SUCCESS) {
|
|
240
|
-
if (sock) {
|
|
241
|
-
lcbio_mgr_discard(sock);
|
|
242
|
-
}
|
|
243
|
-
mcio_error(cccp, err);
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (lcbio_protoctx_get(sock, LCBIO_PROTOCTX_SESSINFO) == NULL) {
|
|
248
|
-
mc_pSESSREQ sreq;
|
|
249
|
-
sreq = mc_sessreq_start(
|
|
250
|
-
sock, settings, settings->config_node_timeout, on_connected,
|
|
251
|
-
cccp);
|
|
252
|
-
LCBIO_CONNREQ_MKGENERIC(&cccp->creq, sreq, mc_sessreq_cancel);
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
ioprocs.cb_err = io_error_handler;
|
|
257
|
-
ioprocs.cb_read = io_read_handler;
|
|
258
|
-
cccp->ioctx = lcbio_ctx_new(sock, data, &ioprocs);
|
|
259
|
-
cccp->ioctx->subsys = "bc_cccp";
|
|
260
|
-
request_config(cccp);
|
|
261
|
-
|
|
262
|
-
(void)syserr;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
static lcb_error_t cccp_get(clconfig_provider *pb)
|
|
266
|
-
{
|
|
267
|
-
cccp_provider *cccp = (cccp_provider *)pb;
|
|
268
|
-
if (cccp->creq.u.p_generic || cccp->server_active || cccp->cmdcookie) {
|
|
269
|
-
return LCB_BUSY;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return schedule_next_request(cccp, LCB_SUCCESS, 1);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
static clconfig_info *cccp_get_cached(clconfig_provider *pb)
|
|
276
|
-
{
|
|
277
|
-
cccp_provider *cccp = (cccp_provider *)pb;
|
|
278
|
-
return cccp->config;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
static lcb_error_t cccp_pause(clconfig_provider *pb)
|
|
282
|
-
{
|
|
283
|
-
cccp_provider *cccp = (cccp_provider *)pb;
|
|
284
|
-
if (!cccp->server_active) {
|
|
285
|
-
return LCB_SUCCESS;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
cccp->server_active = 0;
|
|
289
|
-
release_socket(cccp, 0);
|
|
290
|
-
lcbio_timer_disarm(cccp->timer);
|
|
291
|
-
return LCB_SUCCESS;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
static void cccp_cleanup(clconfig_provider *pb)
|
|
295
|
-
{
|
|
296
|
-
cccp_provider *cccp = (cccp_provider *)pb;
|
|
297
|
-
|
|
298
|
-
release_socket(cccp, 0);
|
|
299
|
-
if (cccp->config) {
|
|
300
|
-
lcb_clconfig_decref(cccp->config);
|
|
301
|
-
}
|
|
302
|
-
if (cccp->nodes) {
|
|
303
|
-
hostlist_destroy(cccp->nodes);
|
|
304
|
-
}
|
|
305
|
-
if (cccp->timer) {
|
|
306
|
-
lcbio_timer_destroy(cccp->timer);
|
|
307
|
-
}
|
|
308
|
-
if (cccp->cmdcookie) {
|
|
309
|
-
cccp->cmdcookie->ignore_errors = 1;
|
|
310
|
-
}
|
|
311
|
-
free(cccp);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
static void
|
|
315
|
-
configure_nodes(clconfig_provider *pb, const hostlist_t nodes)
|
|
316
|
-
{
|
|
317
|
-
cccp_provider *cccp = (cccp_provider *)pb;
|
|
318
|
-
hostlist_assign(cccp->nodes, nodes);
|
|
319
|
-
if (PROVIDER_SETTING(pb, randomize_bootstrap_nodes)) {
|
|
320
|
-
hostlist_randomize(cccp->nodes);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
static void
|
|
325
|
-
config_updated(clconfig_provider *provider, lcbvb_CONFIG* vbc)
|
|
326
|
-
{
|
|
327
|
-
unsigned ii;
|
|
328
|
-
lcbvb_SVCMODE mode;
|
|
329
|
-
cccp_provider *cccp = (cccp_provider *)provider;
|
|
330
|
-
if (LCBVB_NSERVERS(vbc) < 1) {
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
hostlist_clear(cccp->nodes);
|
|
335
|
-
if (PROVIDER_SETTING(provider, sslopts) & LCB_SSL_ENABLED) {
|
|
336
|
-
mode = LCBVB_SVCMODE_SSL;
|
|
337
|
-
} else {
|
|
338
|
-
mode = LCBVB_SVCMODE_PLAIN;
|
|
339
|
-
}
|
|
340
|
-
for (ii = 0; ii < LCBVB_NSERVERS(vbc); ii++) {
|
|
341
|
-
const char *mcaddr = lcbvb_get_hostport(vbc,
|
|
342
|
-
ii, LCBVB_SVCTYPE_DATA, mode);
|
|
343
|
-
if (!mcaddr) {
|
|
344
|
-
lcb_log(LOGARGS(cccp, DEBUG), "Node %d has no data service", ii);
|
|
345
|
-
continue;
|
|
346
|
-
}
|
|
347
|
-
hostlist_add_stringz(cccp->nodes, mcaddr, LCB_CONFIG_MCD_PORT);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
if (PROVIDER_SETTING(provider, randomize_bootstrap_nodes)) {
|
|
351
|
-
hostlist_randomize(cccp->nodes);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
static void
|
|
356
|
-
io_error_handler(lcbio_CTX *ctx, lcb_error_t err)
|
|
357
|
-
{
|
|
358
|
-
cccp_provider *cccp = lcbio_ctx_data(ctx);
|
|
359
|
-
mcio_error(cccp, err);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
static void
|
|
363
|
-
io_read_handler(lcbio_CTX *ioctx, unsigned nr)
|
|
364
|
-
{
|
|
365
|
-
packet_info pi;
|
|
366
|
-
cccp_provider *cccp = lcbio_ctx_data(ioctx);
|
|
367
|
-
lcb_string jsonstr;
|
|
368
|
-
lcb_error_t err;
|
|
369
|
-
int rv;
|
|
370
|
-
unsigned required;
|
|
371
|
-
lcb_host_t curhost;
|
|
372
|
-
|
|
373
|
-
(void)nr;
|
|
374
|
-
|
|
375
|
-
#define return_error(e) \
|
|
376
|
-
lcb_pktinfo_ectx_done(&pi, ioctx); \
|
|
377
|
-
mcio_error(cccp, e); \
|
|
378
|
-
return
|
|
379
|
-
|
|
380
|
-
memset(&pi, 0, sizeof(pi));
|
|
381
|
-
rv = lcb_pktinfo_ectx_get(&pi, ioctx, &required);
|
|
382
|
-
if (!rv) {
|
|
383
|
-
lcbio_ctx_rwant(ioctx, required);
|
|
384
|
-
lcbio_ctx_schedule(ioctx);
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
if (PACKET_STATUS(&pi) != PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
389
|
-
lcb_log(LOGARGS(cccp, WARN), LOGFMT "CCCP Packet responded with 0x%x; nkey=%d, nbytes=%lu, cmd=0x%x, seq=0x%x", LOGID(cccp),
|
|
390
|
-
PACKET_STATUS(&pi), PACKET_NKEY(&pi), (unsigned long)PACKET_NBODY(&pi),
|
|
391
|
-
PACKET_OPCODE(&pi), PACKET_OPAQUE(&pi));
|
|
392
|
-
|
|
393
|
-
switch (PACKET_STATUS(&pi)) {
|
|
394
|
-
case PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED:
|
|
395
|
-
case PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND:
|
|
396
|
-
return_error(LCB_NOT_SUPPORTED);
|
|
397
|
-
default:
|
|
398
|
-
return_error(LCB_PROTOCOL_ERROR);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
if (!PACKET_NBODY(&pi)) {
|
|
405
|
-
return_error(LCB_PROTOCOL_ERROR);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
if (lcb_string_init(&jsonstr)) {
|
|
409
|
-
return_error(LCB_CLIENT_ENOMEM);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
if (lcb_string_append(&jsonstr, PACKET_BODY(&pi), PACKET_NBODY(&pi))) {
|
|
413
|
-
return_error(LCB_CLIENT_ENOMEM);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
curhost = *lcbio_get_host(lcbio_ctx_sock(ioctx));
|
|
417
|
-
lcb_pktinfo_ectx_done(&pi, ioctx);
|
|
418
|
-
release_socket(cccp, 1);
|
|
419
|
-
|
|
420
|
-
err = lcb_cccp_update(&cccp->base, curhost.host, &jsonstr);
|
|
421
|
-
lcb_string_release(&jsonstr);
|
|
422
|
-
if (err == LCB_SUCCESS) {
|
|
423
|
-
lcbio_timer_disarm(cccp->timer);
|
|
424
|
-
cccp->server_active = 0;
|
|
425
|
-
} else {
|
|
426
|
-
schedule_next_request(cccp, LCB_PROTOCOL_ERROR, 0);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
#undef return_error
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
static void request_config(cccp_provider *cccp)
|
|
433
|
-
{
|
|
434
|
-
protocol_binary_request_set_cluster_config req;
|
|
435
|
-
memset(&req, 0, sizeof(req));
|
|
436
|
-
req.message.header.request.magic = PROTOCOL_BINARY_REQ;
|
|
437
|
-
req.message.header.request.opcode = PROTOCOL_BINARY_CMD_GET_CLUSTER_CONFIG;
|
|
438
|
-
req.message.header.request.opaque = 0xF00D;
|
|
439
|
-
lcbio_ctx_put(cccp->ioctx, req.bytes, sizeof(req.bytes));
|
|
440
|
-
lcbio_ctx_rwant(cccp->ioctx, 24);
|
|
441
|
-
lcbio_ctx_schedule(cccp->ioctx);
|
|
442
|
-
lcbio_timer_rearm(cccp->timer, PROVIDER_SETTING(&cccp->base, config_node_timeout));
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
static void do_dump(clconfig_provider *pb, FILE *fp)
|
|
446
|
-
{
|
|
447
|
-
cccp_provider *cccp = (cccp_provider *)pb;
|
|
448
|
-
unsigned ii;
|
|
449
|
-
|
|
450
|
-
if (!cccp->base.enabled) {
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
fprintf(fp, "## BEGIN CCCP PROVIDER DUMP ##\n");
|
|
455
|
-
fprintf(fp, "TIMER ACTIVE: %s\n", lcbio_timer_armed(cccp->timer) ? "YES" : "NO");
|
|
456
|
-
fprintf(fp, "PIPELINE RESPONSE COOKIE: %p\n", (void*)cccp->cmdcookie);
|
|
457
|
-
if (cccp->ioctx) {
|
|
458
|
-
fprintf(fp, "CCCP Owns connection:\n");
|
|
459
|
-
lcbio_ctx_dump(cccp->ioctx, fp);
|
|
460
|
-
} else if (cccp->creq.u.p_generic) {
|
|
461
|
-
fprintf(fp, "CCCP Is connecting\n");
|
|
462
|
-
} else {
|
|
463
|
-
fprintf(fp, "CCCP does not have a dedicated connection\n");
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
for (ii = 0; ii < hostlist_size(cccp->nodes); ii++) {
|
|
467
|
-
const lcb_host_t *curhost = hostlist_get(cccp->nodes, ii);
|
|
468
|
-
fprintf(fp, "CCCP NODE: %s:%s\n", curhost->host, curhost->port);
|
|
469
|
-
}
|
|
470
|
-
fprintf(fp, "## END CCCP PROVIDER DUMP ##\n");
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
clconfig_provider * lcb_clconfig_create_cccp(lcb_confmon *mon)
|
|
474
|
-
{
|
|
475
|
-
cccp_provider *cccp = calloc(1, sizeof(*cccp));
|
|
476
|
-
cccp->nodes = hostlist_create();
|
|
477
|
-
cccp->base.type = LCB_CLCONFIG_CCCP;
|
|
478
|
-
cccp->base.refresh = cccp_get;
|
|
479
|
-
cccp->base.get_cached = cccp_get_cached;
|
|
480
|
-
cccp->base.pause = cccp_pause;
|
|
481
|
-
cccp->base.shutdown = cccp_cleanup;
|
|
482
|
-
cccp->base.config_updated = config_updated;
|
|
483
|
-
cccp->base.configure_nodes = configure_nodes;
|
|
484
|
-
cccp->base.get_nodes = get_nodes;
|
|
485
|
-
cccp->base.dump = do_dump;
|
|
486
|
-
cccp->base.parent = mon;
|
|
487
|
-
cccp->base.enabled = 0;
|
|
488
|
-
cccp->timer = lcbio_timer_new(mon->iot, cccp, socket_timeout);
|
|
489
|
-
|
|
490
|
-
if (!cccp->nodes) {
|
|
491
|
-
free(cccp);
|
|
492
|
-
return NULL;
|
|
493
|
-
}
|
|
494
|
-
return &cccp->base;
|
|
495
|
-
}
|