libcouchbase 0.2.0 → 0.3.1
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/.travis.yml +1 -1
- data/README.md +1 -1
- data/ext/libcouchbase/CMakeLists.txt +8 -6
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +0 -86
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +0 -11
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +0 -2
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +1 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +0 -2
- data/ext/libcouchbase/cmake/defs.mk.in +2 -0
- data/ext/libcouchbase/cmake/source_files.cmake +5 -21
- data/ext/libcouchbase/include/libcouchbase/auth.h +0 -10
- data/ext/libcouchbase/include/libcouchbase/cntl.h +1 -27
- data/ext/libcouchbase/include/libcouchbase/error.h +1 -15
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +1 -13
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +0 -9
- data/ext/libcouchbase/include/libcouchbase/views.h +1 -7
- data/ext/libcouchbase/include/libcouchbase/visibility.h +0 -1
- data/ext/libcouchbase/include/memcached/protocol_binary.h +1131 -29
- data/ext/libcouchbase/include/memcached/vbucket.h +42 -0
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +2 -3
- data/ext/libcouchbase/src/README.md +2 -0
- data/ext/libcouchbase/src/auth-priv.h +0 -1
- data/ext/libcouchbase/src/auth.cc +4 -10
- data/ext/libcouchbase/src/bootstrap.c +269 -0
- data/ext/libcouchbase/src/bootstrap.h +39 -50
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +117 -84
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +347 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +630 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +25 -50
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +386 -407
- data/ext/libcouchbase/src/bucketconfig/confmon.c +474 -0
- data/ext/libcouchbase/src/cbft.cc +27 -22
- data/ext/libcouchbase/src/cntl.cc +19 -30
- data/ext/libcouchbase/src/connspec.cc +1 -48
- data/ext/libcouchbase/src/connspec.h +0 -27
- data/ext/libcouchbase/src/dump.cc +2 -2
- data/ext/libcouchbase/src/getconfig.cc +33 -7
- data/ext/libcouchbase/src/handler.cc +2 -0
- data/ext/libcouchbase/src/hostlist.cc +36 -0
- data/ext/libcouchbase/src/hostlist.h +62 -41
- data/ext/libcouchbase/src/http/http-priv.h +112 -125
- data/ext/libcouchbase/src/http/http.cc +30 -15
- data/ext/libcouchbase/src/http/http.h +34 -1
- data/ext/libcouchbase/src/http/http_io.cc +26 -22
- data/ext/libcouchbase/src/instance.cc +23 -94
- data/ext/libcouchbase/src/internal.h +26 -52
- data/ext/libcouchbase/src/jsparse/parser.cc +202 -146
- data/ext/libcouchbase/src/jsparse/parser.h +98 -91
- data/ext/libcouchbase/src/lcbht/lcbht.c +282 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +163 -174
- data/ext/libcouchbase/src/lcbio/connect.c +557 -0
- data/ext/libcouchbase/src/lcbio/connect.h +2 -9
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +16 -61
- data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
- data/ext/libcouchbase/src/lcbio/manager.c +2 -2
- data/ext/libcouchbase/src/mc/mcreq.h +2 -9
- data/ext/libcouchbase/src/mcserver/mcserver.cc +34 -143
- data/ext/libcouchbase/src/mcserver/mcserver.h +12 -7
- data/ext/libcouchbase/src/mcserver/negotiate.cc +38 -132
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
- data/ext/libcouchbase/src/n1ql/n1ql.cc +32 -56
- data/ext/libcouchbase/src/newconfig.cc +6 -6
- data/ext/libcouchbase/src/nodeinfo.cc +2 -2
- data/ext/libcouchbase/src/operations/{cbflush.cc → cbflush.c} +15 -7
- data/ext/libcouchbase/src/operations/{counter.cc → counter.c} +0 -0
- data/ext/libcouchbase/src/operations/durability.cc +26 -6
- data/ext/libcouchbase/src/operations/durability_internal.h +3 -6
- data/ext/libcouchbase/src/operations/{get.cc → get.c} +26 -24
- data/ext/libcouchbase/src/operations/{observe.cc → observe.c} +93 -68
- data/ext/libcouchbase/src/operations/{pktfwd.cc → pktfwd.c} +0 -0
- data/ext/libcouchbase/src/operations/{remove.cc → remove.c} +0 -0
- data/ext/libcouchbase/src/operations/stats.cc +8 -3
- data/ext/libcouchbase/src/operations/{store.cc → store.c} +32 -27
- data/ext/libcouchbase/src/operations/subdoc.cc +18 -38
- data/ext/libcouchbase/src/operations/{touch.cc → touch.c} +0 -0
- data/ext/libcouchbase/src/packetutils.c +37 -0
- data/ext/libcouchbase/src/packetutils.h +2 -2
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/{retrychk.cc → retrychk.c} +3 -2
- data/ext/libcouchbase/src/retryq.cc +4 -4
- data/ext/libcouchbase/src/settings.c +0 -3
- data/ext/libcouchbase/src/settings.h +0 -5
- data/ext/libcouchbase/src/simplestring.c +211 -0
- data/ext/libcouchbase/src/simplestring.h +228 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +0 -1
- data/ext/libcouchbase/src/ssl/ssl_common.c +0 -2
- data/ext/libcouchbase/src/ssl/ssl_e.c +1 -0
- data/ext/libcouchbase/src/ssobuf.h +82 -0
- data/ext/libcouchbase/src/trace.h +4 -4
- data/ext/libcouchbase/src/vbucket/vbucket.c +1 -0
- data/ext/libcouchbase/src/views/{docreq.cc → docreq.c} +54 -48
- data/ext/libcouchbase/src/views/docreq.h +30 -24
- data/ext/libcouchbase/src/views/viewreq.c +358 -0
- data/ext/libcouchbase/src/views/viewreq.h +13 -43
- data/ext/libcouchbase/tests/basic/t_connstr.cc +50 -89
- data/ext/libcouchbase/tests/basic/t_host.cc +75 -67
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +78 -27
- data/ext/libcouchbase/tests/basic/t_string.cc +112 -0
- data/ext/libcouchbase/tests/htparse/t_basic.cc +78 -58
- data/ext/libcouchbase/tests/iotests/mock-environment.h +1 -2
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +114 -96
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
- data/lib/libcouchbase/ext/tasks.rb +6 -2
- data/lib/libcouchbase/query_view.rb +1 -1
- data/lib/libcouchbase/results_fiber.rb +6 -6
- data/lib/libcouchbase/version.rb +1 -1
- metadata +26 -26
- data/ext/libcouchbase/src/bootstrap.cc +0 -216
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +0 -281
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +0 -528
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +0 -115
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +0 -378
- data/ext/libcouchbase/src/dns-srv.cc +0 -142
- data/ext/libcouchbase/src/errmap.cc +0 -107
- data/ext/libcouchbase/src/errmap.h +0 -113
- data/ext/libcouchbase/src/lcbht/lcbht.cc +0 -177
- data/ext/libcouchbase/src/lcbio/connect.cc +0 -562
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +0 -87
- data/ext/libcouchbase/src/mctx-helper.h +0 -51
- data/ext/libcouchbase/src/views/viewreq.cc +0 -318
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +0 -97
|
@@ -24,54 +24,36 @@
|
|
|
24
24
|
#include "internal.h"
|
|
25
25
|
#include "clconfig.h"
|
|
26
26
|
#include "packetutils.h"
|
|
27
|
+
#include "simplestring.h"
|
|
27
28
|
#include <mcserver/negotiate.h>
|
|
28
29
|
#include <lcbio/lcbio.h>
|
|
29
|
-
#include <lcbio/timer-
|
|
30
|
+
#include <lcbio/timer-ng.h>
|
|
30
31
|
#include <lcbio/ssl.h>
|
|
31
32
|
#include "ctx-log-inl.h"
|
|
32
33
|
#define LOGARGS(cccp, lvl) cccp->parent->settings, "cccp", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
33
34
|
#define LOGFMT "<%s:%s> "
|
|
34
35
|
#define LOGID(cccp) get_ctx_host(cccp->ioctx), get_ctx_port(cccp->ioctx)
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
#define PROVIDER_SETTING_T(fld) PROVIDER_SETTING(this, fld)
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
struct CccpCookie;
|
|
39
40
|
|
|
40
|
-
struct CccpProvider : public
|
|
41
|
-
CccpProvider(
|
|
41
|
+
struct CccpProvider : public clconfig_provider {
|
|
42
|
+
CccpProvider(lcb_confmon *);
|
|
42
43
|
~CccpProvider();
|
|
43
44
|
|
|
44
45
|
void release_socket(bool can_reuse);
|
|
45
46
|
lcb_error_t schedule_next_request(lcb_error_t why, bool can_rollover);
|
|
46
47
|
lcb_error_t mcio_error(lcb_error_t why);
|
|
47
|
-
void on_timeout() { mcio_error(LCB_ETIMEDOUT); }
|
|
48
48
|
lcb_error_t update(const char *host, const char* data);
|
|
49
49
|
void request_config();
|
|
50
|
+
void on_config_updated(lcbvb_CONFIG *vbc);
|
|
50
51
|
void on_io_read();
|
|
51
52
|
|
|
52
|
-
bool pause(); // Override
|
|
53
|
-
void configure_nodes(const lcb::Hostlist&); // Override
|
|
54
|
-
void config_updated(lcbvb_CONFIG *); // Override;
|
|
55
|
-
void dump(FILE*) const; // Override
|
|
56
|
-
lcb_error_t refresh(); // Override
|
|
57
|
-
|
|
58
|
-
ConfigInfo *get_cached() /* Override */ {
|
|
59
|
-
return config;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const lcb::Hostlist* get_nodes() const /* Override */ {
|
|
63
|
-
return nodes;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
void enable(void *arg) {
|
|
67
|
-
instance = reinterpret_cast<lcb_t>(arg);
|
|
68
|
-
Provider::enable();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
53
|
lcb::Hostlist *nodes;
|
|
72
|
-
|
|
54
|
+
clconfig_info *config;
|
|
73
55
|
bool server_active;
|
|
74
|
-
|
|
56
|
+
lcbio_pTIMER timer;
|
|
75
57
|
lcb_t instance;
|
|
76
58
|
lcbio_CONNREQ creq;
|
|
77
59
|
lcbio_CTX *ioctx;
|
|
@@ -124,19 +106,19 @@ CccpProvider::schedule_next_request(lcb_error_t err, bool can_rollover)
|
|
|
124
106
|
lcb::Server *server;
|
|
125
107
|
lcb_host_t *next_host = nodes->next(can_rollover);
|
|
126
108
|
if (!next_host) {
|
|
127
|
-
timer
|
|
128
|
-
|
|
109
|
+
lcbio_timer_disarm(timer);
|
|
110
|
+
lcb_confmon_provider_failed(this, err);
|
|
129
111
|
server_active = false;
|
|
130
112
|
return err;
|
|
131
113
|
}
|
|
132
114
|
|
|
133
|
-
server = instance
|
|
115
|
+
server = lcb_find_server_by_host(instance, next_host);
|
|
134
116
|
if (server) {
|
|
135
117
|
CccpCookie *cookie = new CccpCookie(this);
|
|
136
118
|
cmdcookie = cookie;
|
|
137
119
|
lcb_log(LOGARGS(this, INFO), "Re-Issuing CCCP Command on server struct %p (%s:%s)", (void*)server, next_host->host, next_host->port);
|
|
138
|
-
timer
|
|
139
|
-
instance
|
|
120
|
+
lcbio_timer_rearm(timer, PROVIDER_SETTING_T(config_node_timeout));
|
|
121
|
+
return lcb_getconfig(instance, cookie, server);
|
|
140
122
|
|
|
141
123
|
} else {
|
|
142
124
|
lcbio_pMGRREQ preq;
|
|
@@ -144,7 +126,7 @@ CccpProvider::schedule_next_request(lcb_error_t err, bool can_rollover)
|
|
|
144
126
|
lcb_log(LOGARGS(this, INFO), "Requesting connection to node %s:%s for CCCP configuration", next_host->host, next_host->port);
|
|
145
127
|
preq = lcbio_mgr_get(
|
|
146
128
|
instance->memd_sockpool, next_host,
|
|
147
|
-
|
|
129
|
+
PROVIDER_SETTING_T(config_node_timeout),
|
|
148
130
|
on_connected, this);
|
|
149
131
|
LCBIO_CONNREQ_MKPOOLED(&creq, preq);
|
|
150
132
|
}
|
|
@@ -157,16 +139,32 @@ lcb_error_t
|
|
|
157
139
|
CccpProvider::mcio_error(lcb_error_t err)
|
|
158
140
|
{
|
|
159
141
|
if (err != LCB_NOT_SUPPORTED && err != LCB_UNKNOWN_COMMAND) {
|
|
160
|
-
lcb_log(LOGARGS(this, ERR), LOGFMT "
|
|
142
|
+
lcb_log(LOGARGS(this, ERR), LOGFMT "Got I/O Error=0x%x", LOGID(this), err);
|
|
161
143
|
}
|
|
162
144
|
|
|
163
145
|
release_socket(err == LCB_NOT_SUPPORTED);
|
|
164
146
|
return schedule_next_request(err, false);
|
|
165
147
|
}
|
|
166
148
|
|
|
149
|
+
static void socket_timeout(void *arg) {
|
|
150
|
+
reinterpret_cast<CccpProvider*>(arg)->mcio_error(LCB_ETIMEDOUT);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
void lcb_clconfig_cccp_enable(clconfig_provider *pb, lcb_t instance)
|
|
154
|
+
{
|
|
155
|
+
CccpProvider *cccp = static_cast<CccpProvider*>(pb);
|
|
156
|
+
lcb_assert(pb->type == LCB_CLCONFIG_CCCP);
|
|
157
|
+
cccp->instance = instance;
|
|
158
|
+
pb->enabled = true;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static hostlist_t get_nodes(const clconfig_provider *pb) {
|
|
162
|
+
return static_cast<const CccpProvider*>(pb)->nodes;
|
|
163
|
+
}
|
|
164
|
+
|
|
167
165
|
/** Update the configuration from a server. */
|
|
168
166
|
lcb_error_t
|
|
169
|
-
|
|
167
|
+
lcb_cccp_update(clconfig_provider *provider, const char *host, const char *data) {
|
|
170
168
|
return static_cast<CccpProvider*>(provider)->update(host, data);
|
|
171
169
|
}
|
|
172
170
|
|
|
@@ -176,7 +174,7 @@ CccpProvider::update(const char *host, const char *data)
|
|
|
176
174
|
/** TODO: replace this with lcbvb_ names */
|
|
177
175
|
lcbvb_CONFIG* vbc;
|
|
178
176
|
int rv;
|
|
179
|
-
|
|
177
|
+
clconfig_info *new_config;
|
|
180
178
|
vbc = lcbvb_create();
|
|
181
179
|
|
|
182
180
|
if (!vbc) {
|
|
@@ -192,7 +190,7 @@ CccpProvider::update(const char *host, const char *data)
|
|
|
192
190
|
}
|
|
193
191
|
|
|
194
192
|
lcbvb_replace_host(vbc, host);
|
|
195
|
-
new_config =
|
|
193
|
+
new_config = lcb_clconfig_create(vbc, LCB_CLCONFIG_CCCP);
|
|
196
194
|
|
|
197
195
|
if (!new_config) {
|
|
198
196
|
lcbvb_destroy(vbc);
|
|
@@ -200,24 +198,25 @@ CccpProvider::update(const char *host, const char *data)
|
|
|
200
198
|
}
|
|
201
199
|
|
|
202
200
|
if (config) {
|
|
203
|
-
config
|
|
201
|
+
lcb_clconfig_decref(config);
|
|
204
202
|
}
|
|
205
203
|
|
|
206
204
|
/** TODO: Figure out the comparison vector */
|
|
205
|
+
new_config->cmpclock = gethrtime();
|
|
207
206
|
config = new_config;
|
|
208
|
-
|
|
207
|
+
lcb_confmon_provider_success(this, new_config);
|
|
209
208
|
return LCB_SUCCESS;
|
|
210
209
|
}
|
|
211
210
|
|
|
212
|
-
void
|
|
213
|
-
|
|
214
|
-
|
|
211
|
+
void lcb_cccp_update2(const void *cookie, lcb_error_t err,
|
|
212
|
+
const void *bytes, lcb_size_t nbytes,
|
|
213
|
+
const lcb_host_t *origin)
|
|
215
214
|
{
|
|
216
215
|
CccpCookie *ck = reinterpret_cast<CccpCookie*>(const_cast<void*>(cookie));
|
|
217
216
|
CccpProvider *cccp = ck->parent;
|
|
218
217
|
|
|
219
218
|
if (ck == cccp->cmdcookie) {
|
|
220
|
-
cccp->timer
|
|
219
|
+
lcbio_timer_disarm(cccp->timer);
|
|
221
220
|
cccp->cmdcookie = NULL;
|
|
222
221
|
}
|
|
223
222
|
|
|
@@ -264,53 +263,70 @@ on_connected(lcbio_SOCKET *sock, void *data, lcb_error_t err, lcbio_OSERR)
|
|
|
264
263
|
cccp->request_config();
|
|
265
264
|
}
|
|
266
265
|
|
|
267
|
-
lcb_error_t
|
|
268
|
-
|
|
266
|
+
static lcb_error_t cccp_get(clconfig_provider *pb)
|
|
267
|
+
{
|
|
268
|
+
CccpProvider *cccp = static_cast<CccpProvider *>(pb);
|
|
269
|
+
if (cccp->creq.u.p_generic || cccp->server_active || cccp->cmdcookie) {
|
|
269
270
|
return LCB_BUSY;
|
|
270
271
|
}
|
|
271
272
|
|
|
272
|
-
return schedule_next_request(LCB_SUCCESS, true);
|
|
273
|
+
return cccp->schedule_next_request(LCB_SUCCESS, true);
|
|
273
274
|
}
|
|
274
275
|
|
|
275
|
-
|
|
276
|
-
CccpProvider
|
|
276
|
+
static clconfig_info *cccp_get_cached(clconfig_provider *pb) {
|
|
277
|
+
return static_cast<CccpProvider *>(pb)->config;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
static lcb_error_t cccp_pause(clconfig_provider *pb)
|
|
277
281
|
{
|
|
278
|
-
|
|
279
|
-
|
|
282
|
+
CccpProvider *cccp = static_cast<CccpProvider *>(pb);
|
|
283
|
+
if (!cccp->server_active) {
|
|
284
|
+
return LCB_SUCCESS;
|
|
280
285
|
}
|
|
281
286
|
|
|
282
|
-
server_active = 0;
|
|
283
|
-
release_socket(false);
|
|
284
|
-
timer
|
|
285
|
-
return
|
|
287
|
+
cccp->server_active = 0;
|
|
288
|
+
cccp->release_socket(false);
|
|
289
|
+
lcbio_timer_disarm(cccp->timer);
|
|
290
|
+
return LCB_SUCCESS;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
static void cccp_cleanup(clconfig_provider *pb) {
|
|
294
|
+
delete static_cast<CccpProvider*>(pb);
|
|
286
295
|
}
|
|
287
296
|
|
|
288
297
|
CccpProvider::~CccpProvider() {
|
|
289
298
|
release_socket(false);
|
|
290
299
|
|
|
291
300
|
if (config) {
|
|
292
|
-
config
|
|
301
|
+
lcb_clconfig_decref(config);
|
|
293
302
|
}
|
|
294
303
|
if (nodes) {
|
|
295
304
|
delete nodes;
|
|
296
305
|
}
|
|
297
|
-
timer
|
|
306
|
+
if (timer) {
|
|
307
|
+
lcbio_timer_destroy(timer);
|
|
308
|
+
}
|
|
298
309
|
if (cmdcookie) {
|
|
299
310
|
cmdcookie->ignore_errors = 1;
|
|
300
311
|
}
|
|
301
312
|
}
|
|
302
313
|
|
|
303
|
-
void
|
|
304
|
-
|
|
314
|
+
static void
|
|
315
|
+
configure_nodes(clconfig_provider *pb, const hostlist_t nodes)
|
|
305
316
|
{
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
317
|
+
CccpProvider *cccp = static_cast<CccpProvider *>(pb);
|
|
318
|
+
cccp->nodes->assign(*nodes);
|
|
319
|
+
if (PROVIDER_SETTING(pb, randomize_bootstrap_nodes)) {
|
|
320
|
+
cccp->nodes->randomize();
|
|
309
321
|
}
|
|
310
322
|
}
|
|
311
323
|
|
|
324
|
+
static void config_updated(clconfig_provider *provider, lcbvb_CONFIG* vbc) {
|
|
325
|
+
static_cast<CccpProvider*>(provider)->on_config_updated(vbc);
|
|
326
|
+
}
|
|
327
|
+
|
|
312
328
|
void
|
|
313
|
-
CccpProvider::
|
|
329
|
+
CccpProvider::on_config_updated(lcbvb_CONFIG *vbc)
|
|
314
330
|
{
|
|
315
331
|
lcbvb_SVCMODE mode;
|
|
316
332
|
if (LCBVB_NSERVERS(vbc) < 1) {
|
|
@@ -318,7 +334,7 @@ CccpProvider::config_updated(lcbvb_CONFIG *vbc)
|
|
|
318
334
|
}
|
|
319
335
|
|
|
320
336
|
nodes->clear();
|
|
321
|
-
if (
|
|
337
|
+
if (PROVIDER_SETTING_T(sslopts) & LCB_SSL_ENABLED) {
|
|
322
338
|
mode = LCBVB_SVCMODE_SSL;
|
|
323
339
|
} else {
|
|
324
340
|
mode = LCBVB_SVCMODE_PLAIN;
|
|
@@ -333,7 +349,7 @@ CccpProvider::config_updated(lcbvb_CONFIG *vbc)
|
|
|
333
349
|
nodes->add(mcaddr, LCB_CONFIG_MCD_PORT);
|
|
334
350
|
}
|
|
335
351
|
|
|
336
|
-
if (
|
|
352
|
+
if (PROVIDER_SETTING_T(randomize_bootstrap_nodes)) {
|
|
337
353
|
nodes->randomize();
|
|
338
354
|
}
|
|
339
355
|
}
|
|
@@ -395,7 +411,7 @@ CccpProvider::on_io_read()
|
|
|
395
411
|
lcb_error_t err = update(hoststr.c_str(), jsonstr.c_str());
|
|
396
412
|
|
|
397
413
|
if (err == LCB_SUCCESS) {
|
|
398
|
-
timer
|
|
414
|
+
lcbio_timer_disarm(timer);
|
|
399
415
|
server_active = false;
|
|
400
416
|
} else {
|
|
401
417
|
schedule_next_request(LCB_PROTOCOL_ERROR, 0);
|
|
@@ -411,45 +427,62 @@ void CccpProvider::request_config()
|
|
|
411
427
|
lcbio_ctx_put(ioctx, req.data(), req.size());
|
|
412
428
|
lcbio_ctx_rwant(ioctx, 24);
|
|
413
429
|
lcbio_ctx_schedule(ioctx);
|
|
414
|
-
timer
|
|
430
|
+
lcbio_timer_rearm(timer, PROVIDER_SETTING(this, config_node_timeout));
|
|
415
431
|
}
|
|
416
432
|
|
|
417
|
-
void
|
|
418
|
-
|
|
433
|
+
static void do_dump(clconfig_provider *pb, FILE *fp)
|
|
434
|
+
{
|
|
435
|
+
CccpProvider *cccp = (CccpProvider *)pb;
|
|
436
|
+
|
|
437
|
+
if (!cccp->enabled) {
|
|
419
438
|
return;
|
|
420
439
|
}
|
|
421
440
|
|
|
422
441
|
fprintf(fp, "## BEGIN CCCP PROVIDER DUMP ##\n");
|
|
423
|
-
fprintf(fp, "TIMER ACTIVE: %s\n", timer
|
|
424
|
-
fprintf(fp, "PIPELINE RESPONSE COOKIE: %p\n", (void*)cmdcookie);
|
|
425
|
-
if (ioctx) {
|
|
442
|
+
fprintf(fp, "TIMER ACTIVE: %s\n", lcbio_timer_armed(cccp->timer) ? "YES" : "NO");
|
|
443
|
+
fprintf(fp, "PIPELINE RESPONSE COOKIE: %p\n", (void*)cccp->cmdcookie);
|
|
444
|
+
if (cccp->ioctx) {
|
|
426
445
|
fprintf(fp, "CCCP Owns connection:\n");
|
|
427
|
-
lcbio_ctx_dump(ioctx, fp);
|
|
428
|
-
} else if (creq.u.p_generic) {
|
|
446
|
+
lcbio_ctx_dump(cccp->ioctx, fp);
|
|
447
|
+
} else if (cccp->creq.u.p_generic) {
|
|
429
448
|
fprintf(fp, "CCCP Is connecting\n");
|
|
430
449
|
} else {
|
|
431
450
|
fprintf(fp, "CCCP does not have a dedicated connection\n");
|
|
432
451
|
}
|
|
433
452
|
|
|
434
|
-
for (size_t ii = 0; ii < nodes->size(); ii++) {
|
|
435
|
-
const lcb_host_t &curhost = (*nodes)[ii];
|
|
453
|
+
for (size_t ii = 0; ii < cccp->nodes->size(); ii++) {
|
|
454
|
+
const lcb_host_t &curhost = (*cccp->nodes)[ii];
|
|
436
455
|
fprintf(fp, "CCCP NODE: %s:%s\n", curhost.host, curhost.port);
|
|
437
456
|
}
|
|
438
457
|
fprintf(fp, "## END CCCP PROVIDER DUMP ##\n");
|
|
439
458
|
}
|
|
440
459
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
460
|
+
clconfig_provider * lcb_clconfig_create_cccp(lcb_confmon *mon)
|
|
461
|
+
{
|
|
462
|
+
return new CccpProvider(mon);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
CccpProvider::CccpProvider(lcb_confmon *mon)
|
|
466
|
+
: nodes(new lcb::Hostlist()),
|
|
444
467
|
config(NULL),
|
|
445
468
|
server_active(false),
|
|
446
|
-
timer(
|
|
469
|
+
timer(NULL),
|
|
447
470
|
instance(NULL),
|
|
448
471
|
ioctx(NULL),
|
|
449
|
-
cmdcookie(NULL)
|
|
472
|
+
cmdcookie(NULL)
|
|
473
|
+
{
|
|
474
|
+
clconfig_provider::type = LCB_CLCONFIG_CCCP;
|
|
475
|
+
clconfig_provider::refresh = cccp_get;
|
|
476
|
+
clconfig_provider::get_cached = cccp_get_cached;
|
|
477
|
+
clconfig_provider::pause = cccp_pause;
|
|
478
|
+
clconfig_provider::shutdown = cccp_cleanup;
|
|
479
|
+
clconfig_provider::config_updated = ::config_updated;
|
|
480
|
+
clconfig_provider::configure_nodes = ::configure_nodes;
|
|
481
|
+
clconfig_provider::get_nodes = ::get_nodes;
|
|
482
|
+
clconfig_provider::dump = do_dump;
|
|
483
|
+
clconfig_provider::parent = mon;
|
|
484
|
+
clconfig_provider::enabled = 0;
|
|
485
|
+
|
|
486
|
+
timer = lcbio_timer_new(mon->iot, this, socket_timeout);
|
|
450
487
|
std::memset(&creq, 0, sizeof creq);
|
|
451
488
|
}
|
|
452
|
-
|
|
453
|
-
Provider* lcb::clconfig::new_cccp_provider(Confmon *mon) {
|
|
454
|
-
return new CccpProvider(mon);
|
|
455
|
-
}
|
|
@@ -0,0 +1,347 @@
|
|
|
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
|
+
}
|