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
|
@@ -0,0 +1,474 @@
|
|
|
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
|
+
#define LOGARGS(mon, lvlbase) mon->settings, "confmon", LCB_LOG_##lvlbase, __FILE__, __LINE__
|
|
21
|
+
#define LOG(mon, lvlbase, msg) lcb_log(mon->settings, "confmon", LCB_LOG_##lvlbase, __FILE__, __LINE__, msg)
|
|
22
|
+
|
|
23
|
+
static void async_stop(void *);
|
|
24
|
+
static void async_start(void *);
|
|
25
|
+
static int do_next_provider(lcb_confmon *mon);
|
|
26
|
+
static void invoke_listeners(lcb_confmon *mon,
|
|
27
|
+
clconfig_event_t event,
|
|
28
|
+
clconfig_info *info);
|
|
29
|
+
|
|
30
|
+
#define IS_REFRESHING(mon) ((mon)->state & CONFMON_S_ACTIVE)
|
|
31
|
+
|
|
32
|
+
static clconfig_provider *next_active(lcb_confmon *mon, clconfig_provider *cur)
|
|
33
|
+
{
|
|
34
|
+
if (!LCB_LIST_HAS_NEXT((lcb_list_t *)&mon->active_providers, &cur->ll)) {
|
|
35
|
+
return NULL;
|
|
36
|
+
}
|
|
37
|
+
return LCB_LIST_ITEM(cur->ll.next, clconfig_provider, ll);
|
|
38
|
+
}
|
|
39
|
+
static clconfig_provider *first_active(lcb_confmon *mon)
|
|
40
|
+
{
|
|
41
|
+
if (LCB_LIST_IS_EMPTY((lcb_list_t *)&mon->active_providers)) {
|
|
42
|
+
return NULL;
|
|
43
|
+
}
|
|
44
|
+
return LCB_LIST_ITEM(mon->active_providers.next, clconfig_provider, ll);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static const char *
|
|
48
|
+
provider_string(clconfig_method_t type) {
|
|
49
|
+
if (type == LCB_CLCONFIG_HTTP) { return "HTTP"; }
|
|
50
|
+
if (type == LCB_CLCONFIG_CCCP) { return "CCCP"; }
|
|
51
|
+
if (type == LCB_CLCONFIG_FILE) { return "FILE"; }
|
|
52
|
+
if (type == LCB_CLCONFIG_MCRAW) { return "MCRAW"; }
|
|
53
|
+
if (type == LCB_CLCONFIG_USER) { return "USER"; }
|
|
54
|
+
return "";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
lcb_confmon* lcb_confmon_create(lcb_settings *settings, lcbio_pTABLE iot)
|
|
58
|
+
{
|
|
59
|
+
int ii;
|
|
60
|
+
lcb_confmon * mon = calloc(1, sizeof(*mon));
|
|
61
|
+
mon->settings = settings;
|
|
62
|
+
mon->iot = iot;
|
|
63
|
+
lcb_list_init(&mon->listeners);
|
|
64
|
+
lcb_clist_init(&mon->active_providers);
|
|
65
|
+
lcbio_table_ref(mon->iot);
|
|
66
|
+
lcb_settings_ref(mon->settings);
|
|
67
|
+
|
|
68
|
+
mon->all_providers[LCB_CLCONFIG_FILE] = lcb_clconfig_create_file(mon);
|
|
69
|
+
mon->all_providers[LCB_CLCONFIG_CCCP] = lcb_clconfig_create_cccp(mon);
|
|
70
|
+
mon->all_providers[LCB_CLCONFIG_HTTP] = lcb_clconfig_create_http(mon);
|
|
71
|
+
mon->all_providers[LCB_CLCONFIG_USER] = lcb_clconfig_create_user(mon);
|
|
72
|
+
mon->all_providers[LCB_CLCONFIG_MCRAW] = lcb_clconfig_create_mcraw(mon);
|
|
73
|
+
|
|
74
|
+
for (ii = 0; ii < LCB_CLCONFIG_MAX; ii++) {
|
|
75
|
+
mon->all_providers[ii]->parent = mon;
|
|
76
|
+
}
|
|
77
|
+
mon->as_stop = lcbio_timer_new(iot, mon, async_stop);
|
|
78
|
+
mon->as_start = lcbio_timer_new(iot, mon, async_start);
|
|
79
|
+
return mon;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
void lcb_confmon_prepare(lcb_confmon *mon)
|
|
83
|
+
{
|
|
84
|
+
int ii;
|
|
85
|
+
|
|
86
|
+
memset(&mon->active_providers, 0, sizeof(mon->active_providers));
|
|
87
|
+
lcb_clist_init(&mon->active_providers);
|
|
88
|
+
|
|
89
|
+
lcb_log(LOGARGS(mon, DEBUG), "Preparing providers (this may be called multiple times)");
|
|
90
|
+
|
|
91
|
+
for (ii = 0; ii < LCB_CLCONFIG_MAX; ii++) {
|
|
92
|
+
clconfig_provider *cur = mon->all_providers[ii];
|
|
93
|
+
if (cur) {
|
|
94
|
+
if (cur->enabled) {
|
|
95
|
+
lcb_clist_append(&mon->active_providers, &cur->ll);
|
|
96
|
+
lcb_log(LOGARGS(mon, DEBUG), "Provider %s is ENABLED", provider_string(cur->type));
|
|
97
|
+
} else if (cur->pause){
|
|
98
|
+
cur->pause(cur);
|
|
99
|
+
lcb_log(LOGARGS(mon, DEBUG), "Provider %s is DISABLED", provider_string(cur->type));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
lcb_assert(LCB_CLIST_SIZE(&mon->active_providers));
|
|
105
|
+
mon->cur_provider = first_active(mon);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
void lcb_confmon_destroy(lcb_confmon *mon)
|
|
109
|
+
{
|
|
110
|
+
unsigned int ii;
|
|
111
|
+
|
|
112
|
+
if (mon->as_start) {
|
|
113
|
+
lcbio_timer_destroy(mon->as_start);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (mon->as_stop) {
|
|
117
|
+
lcbio_timer_destroy(mon->as_stop);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
mon->as_start = NULL;
|
|
121
|
+
mon->as_stop = NULL;
|
|
122
|
+
|
|
123
|
+
if (mon->config) {
|
|
124
|
+
lcb_clconfig_decref(mon->config);
|
|
125
|
+
mon->config = NULL;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
for (ii = 0; ii < LCB_CLCONFIG_MAX; ii++) {
|
|
129
|
+
clconfig_provider *provider = mon->all_providers[ii];
|
|
130
|
+
if (provider == NULL) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
provider->shutdown(provider);
|
|
135
|
+
mon->all_providers[ii] = NULL;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
lcbio_table_unref(mon->iot);
|
|
139
|
+
lcb_settings_unref(mon->settings);
|
|
140
|
+
|
|
141
|
+
free(mon);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static int do_set_next(lcb_confmon *mon, clconfig_info *info, int notify_miss)
|
|
145
|
+
{
|
|
146
|
+
unsigned ii;
|
|
147
|
+
|
|
148
|
+
if (mon->config) {
|
|
149
|
+
lcbvb_CHANGETYPE chstatus = LCBVB_NO_CHANGES;
|
|
150
|
+
lcbvb_CONFIGDIFF *diff = lcbvb_compare(mon->config->vbc, info->vbc);
|
|
151
|
+
|
|
152
|
+
if (!diff) {
|
|
153
|
+
lcb_log(LOGARGS(mon, DEBUG), "Couldn't create vbucket diff");
|
|
154
|
+
return 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
chstatus = lcbvb_get_changetype(diff);
|
|
158
|
+
lcbvb_free_diff(diff);
|
|
159
|
+
|
|
160
|
+
if (chstatus == 0 || lcb_clconfig_compare(mon->config, info) >= 0) {
|
|
161
|
+
const lcbvb_CONFIG *ca, *cb;
|
|
162
|
+
|
|
163
|
+
ca = mon->config->vbc;
|
|
164
|
+
cb = info->vbc;
|
|
165
|
+
|
|
166
|
+
lcb_log(LOGARGS(mon, INFO), "Not applying configuration received via %s. No changes detected. A.rev=%d, B.rev=%d", provider_string(info->origin), ca->revid, cb->revid);
|
|
167
|
+
if (notify_miss) {
|
|
168
|
+
invoke_listeners(mon, CLCONFIG_EVENT_GOT_ANY_CONFIG, info);
|
|
169
|
+
}
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
lcb_log(LOGARGS(mon, INFO), "Setting new configuration. Received via %s", provider_string(info->origin));
|
|
175
|
+
|
|
176
|
+
if (mon->config) {
|
|
177
|
+
/** DECREF the old one */
|
|
178
|
+
lcb_clconfig_decref(mon->config);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
for (ii = 0; ii < LCB_CLCONFIG_MAX; ii++) {
|
|
182
|
+
clconfig_provider *cur = mon->all_providers[ii];
|
|
183
|
+
if (cur && cur->enabled && cur->config_updated) {
|
|
184
|
+
cur->config_updated(cur, info->vbc);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
lcb_clconfig_incref(info);
|
|
189
|
+
mon->config = info;
|
|
190
|
+
lcb_confmon_stop(mon);
|
|
191
|
+
|
|
192
|
+
invoke_listeners(mon, CLCONFIG_EVENT_GOT_NEW_CONFIG, info);
|
|
193
|
+
|
|
194
|
+
return 1;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
void lcb_confmon_provider_failed(clconfig_provider *provider,
|
|
198
|
+
lcb_error_t reason)
|
|
199
|
+
{
|
|
200
|
+
lcb_confmon *mon = provider->parent;
|
|
201
|
+
|
|
202
|
+
lcb_log(LOGARGS(mon, INFO), "Provider '%s' failed", provider_string(provider->type));
|
|
203
|
+
|
|
204
|
+
if (provider != mon->cur_provider) {
|
|
205
|
+
lcb_log(LOGARGS(mon, TRACE), "Ignoring failure. Current=%p (%s)", (void*)mon->cur_provider, provider_string(mon->cur_provider->type));
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
if (!lcb_confmon_is_refreshing(mon)) {
|
|
209
|
+
lcb_log(LOGARGS(mon, DEBUG), "Ignoring failure. Refresh not active");
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (reason != LCB_SUCCESS) {
|
|
213
|
+
if (mon->settings->detailed_neterr && mon->last_error != LCB_SUCCESS) {
|
|
214
|
+
/* Filter out any artificial 'connect error' or 'network error' codes */
|
|
215
|
+
if (reason != LCB_CONNECT_ERROR && reason != LCB_NETWORK_ERROR) {
|
|
216
|
+
mon->last_error = reason;
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
mon->last_error = reason;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
mon->cur_provider = next_active(mon, mon->cur_provider);
|
|
224
|
+
|
|
225
|
+
if (!mon->cur_provider) {
|
|
226
|
+
LOG(mon, TRACE, "Maximum provider reached. Resetting index");
|
|
227
|
+
invoke_listeners(mon, CLCONFIG_EVENT_PROVIDERS_CYCLED, NULL);
|
|
228
|
+
mon->cur_provider = first_active(mon);
|
|
229
|
+
lcb_confmon_stop(mon);
|
|
230
|
+
} else {
|
|
231
|
+
uint32_t interval = 0;
|
|
232
|
+
if (mon->config) {
|
|
233
|
+
/* Not first */
|
|
234
|
+
interval = PROVIDER_SETTING(provider, grace_next_provider);
|
|
235
|
+
}
|
|
236
|
+
lcb_log(LOGARGS(mon, DEBUG), "Will try next provider in %uus", interval);
|
|
237
|
+
mon->state |= CONFMON_S_ITERGRACE;
|
|
238
|
+
lcbio_timer_rearm(mon->as_start, interval);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
void lcb_confmon_provider_success(clconfig_provider *provider,
|
|
243
|
+
clconfig_info *config)
|
|
244
|
+
{
|
|
245
|
+
do_set_next(provider->parent, config, 1);
|
|
246
|
+
lcb_confmon_stop(provider->parent);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
static int do_next_provider(lcb_confmon *mon)
|
|
251
|
+
{
|
|
252
|
+
lcb_list_t *ii;
|
|
253
|
+
mon->state &= ~CONFMON_S_ITERGRACE;
|
|
254
|
+
|
|
255
|
+
LCB_LIST_FOR(ii, (lcb_list_t *)&mon->active_providers) {
|
|
256
|
+
clconfig_info *info;
|
|
257
|
+
clconfig_provider *cached_provider;
|
|
258
|
+
|
|
259
|
+
cached_provider = LCB_LIST_ITEM(ii, clconfig_provider, ll);
|
|
260
|
+
info = cached_provider->get_cached(cached_provider);
|
|
261
|
+
if (!info) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (do_set_next(mon, info, 0)) {
|
|
266
|
+
LOG(mon, DEBUG, "Using cached configuration");
|
|
267
|
+
return 1;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
lcb_log(LOGARGS(mon, TRACE), "Current provider is %s", provider_string(mon->cur_provider->type));
|
|
272
|
+
|
|
273
|
+
mon->cur_provider->refresh(mon->cur_provider);
|
|
274
|
+
return 0;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
static void async_start(void *arg)
|
|
278
|
+
{
|
|
279
|
+
do_next_provider(arg);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
lcb_error_t lcb_confmon_start(lcb_confmon *mon)
|
|
283
|
+
{
|
|
284
|
+
lcb_U32 tmonext = 0;
|
|
285
|
+
|
|
286
|
+
lcbio_async_cancel(mon->as_stop);
|
|
287
|
+
if (IS_REFRESHING(mon)) {
|
|
288
|
+
LOG(mon, DEBUG, "Refresh already in progress...");
|
|
289
|
+
return LCB_SUCCESS;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
LOG(mon, TRACE, "Start refresh requested");
|
|
293
|
+
lcb_assert(mon->cur_provider);
|
|
294
|
+
mon->state = CONFMON_S_ACTIVE|CONFMON_S_ITERGRACE;
|
|
295
|
+
|
|
296
|
+
if (mon->last_stop_us > 0) {
|
|
297
|
+
lcb_U32 diff = LCB_NS2US(gethrtime()) - mon->last_stop_us;
|
|
298
|
+
if (diff <= mon->settings->grace_next_cycle) {
|
|
299
|
+
tmonext = mon->settings->grace_next_cycle - diff;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
lcbio_timer_rearm(mon->as_start, tmonext);
|
|
304
|
+
return LCB_SUCCESS;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
static void async_stop(void *arg)
|
|
308
|
+
{
|
|
309
|
+
lcb_confmon *mon = arg;
|
|
310
|
+
lcb_list_t *ii;
|
|
311
|
+
|
|
312
|
+
LCB_LIST_FOR(ii, (lcb_list_t *)&mon->active_providers) {
|
|
313
|
+
clconfig_provider *provider = LCB_LIST_ITEM(ii, clconfig_provider, ll);
|
|
314
|
+
if (!provider->pause) {
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
provider->pause(provider);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
mon->last_stop_us = LCB_NS2US(gethrtime());
|
|
321
|
+
invoke_listeners(mon, CLCONFIG_EVENT_MONITOR_STOPPED, NULL);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
lcb_error_t lcb_confmon_stop(lcb_confmon *mon)
|
|
325
|
+
{
|
|
326
|
+
if (!IS_REFRESHING(mon)) {
|
|
327
|
+
return LCB_SUCCESS;
|
|
328
|
+
}
|
|
329
|
+
lcbio_timer_disarm(mon->as_start);
|
|
330
|
+
lcbio_async_signal(mon->as_stop);
|
|
331
|
+
mon->state = CONFMON_S_INACTIVE;
|
|
332
|
+
return LCB_SUCCESS;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
void lcb_clconfig_decref(clconfig_info *info)
|
|
336
|
+
{
|
|
337
|
+
lcb_assert(info->refcount);
|
|
338
|
+
|
|
339
|
+
if (--info->refcount) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (info->vbc) {
|
|
344
|
+
lcbvb_destroy(info->vbc);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
free(info);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
int lcb_clconfig_compare(const clconfig_info *a, const clconfig_info *b)
|
|
351
|
+
{
|
|
352
|
+
/** First check if both have revisions */
|
|
353
|
+
int rev_a, rev_b;
|
|
354
|
+
rev_a = lcbvb_get_revision(a->vbc);
|
|
355
|
+
rev_b = lcbvb_get_revision(b->vbc);
|
|
356
|
+
if (rev_a >= 0 && rev_b >= 0) {
|
|
357
|
+
return rev_a - rev_b;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (a->cmpclock == b->cmpclock) {
|
|
361
|
+
return 0;
|
|
362
|
+
|
|
363
|
+
} else if (a->cmpclock < b->cmpclock) {
|
|
364
|
+
return -1;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return 1;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
clconfig_info *
|
|
371
|
+
lcb_clconfig_create(lcbvb_CONFIG* config, clconfig_method_t origin)
|
|
372
|
+
{
|
|
373
|
+
clconfig_info *info = calloc(1, sizeof(*info));
|
|
374
|
+
if (!info) {
|
|
375
|
+
return NULL;
|
|
376
|
+
}
|
|
377
|
+
info->refcount = 1;
|
|
378
|
+
info->vbc = config;
|
|
379
|
+
info->origin = origin;
|
|
380
|
+
return info;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
void lcb_confmon_add_listener(lcb_confmon *mon, clconfig_listener *listener)
|
|
384
|
+
{
|
|
385
|
+
listener->parent = mon;
|
|
386
|
+
lcb_list_append(&mon->listeners, &listener->ll);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
void lcb_confmon_remove_listener(lcb_confmon *mon, clconfig_listener *listener)
|
|
390
|
+
{
|
|
391
|
+
lcb_list_delete(&listener->ll);
|
|
392
|
+
(void)mon;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
static void invoke_listeners(lcb_confmon *mon,
|
|
396
|
+
clconfig_event_t event,
|
|
397
|
+
clconfig_info *info)
|
|
398
|
+
{
|
|
399
|
+
lcb_list_t *ll, *ll_next;
|
|
400
|
+
LCB_LIST_SAFE_FOR(ll, ll_next, &mon->listeners) {
|
|
401
|
+
clconfig_listener *lsn = LCB_LIST_ITEM(ll, clconfig_listener, ll);
|
|
402
|
+
lsn->callback(lsn, event, info);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
static void generic_shutdown(clconfig_provider *provider)
|
|
407
|
+
{
|
|
408
|
+
free(provider);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
clconfig_provider * lcb_clconfig_create_user(lcb_confmon *mon)
|
|
412
|
+
{
|
|
413
|
+
clconfig_provider *provider = calloc(1, sizeof(*provider));
|
|
414
|
+
provider->type = LCB_CLCONFIG_USER;
|
|
415
|
+
provider->shutdown = generic_shutdown;
|
|
416
|
+
|
|
417
|
+
(void)mon;
|
|
418
|
+
return provider;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
LCB_INTERNAL_API
|
|
422
|
+
int lcb_confmon_is_refreshing(lcb_confmon *mon)
|
|
423
|
+
{
|
|
424
|
+
return IS_REFRESHING(mon);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
LCB_INTERNAL_API
|
|
428
|
+
void
|
|
429
|
+
lcb_confmon_set_provider_active(lcb_confmon *mon,
|
|
430
|
+
clconfig_method_t type, int enabled)
|
|
431
|
+
{
|
|
432
|
+
clconfig_provider *provider = mon->all_providers[type];
|
|
433
|
+
if (provider->enabled == enabled) {
|
|
434
|
+
return;
|
|
435
|
+
} else {
|
|
436
|
+
provider->enabled = enabled;
|
|
437
|
+
}
|
|
438
|
+
lcb_confmon_prepare(mon);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
void
|
|
442
|
+
lcb_confmon_dump(lcb_confmon *mon, FILE *fp)
|
|
443
|
+
{
|
|
444
|
+
unsigned ii;
|
|
445
|
+
fprintf(fp, "CONFMON=%p\n", (void*)mon);
|
|
446
|
+
fprintf(fp, "STATE= (0x%x)", mon->state);
|
|
447
|
+
if (mon->state & CONFMON_S_ACTIVE) {
|
|
448
|
+
fprintf(fp, "ACTIVE|");
|
|
449
|
+
}
|
|
450
|
+
if (mon->state == CONFMON_S_INACTIVE) {
|
|
451
|
+
fprintf(fp, "INACTIVE/IDLE");
|
|
452
|
+
}
|
|
453
|
+
if (mon->state & CONFMON_S_ITERGRACE) {
|
|
454
|
+
fprintf(fp, "ITERGRACE");
|
|
455
|
+
}
|
|
456
|
+
fprintf(fp, "\n");
|
|
457
|
+
fprintf(fp, "LAST ERROR: 0x%x\n", mon->last_error);
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
for (ii = 0; ii < LCB_CLCONFIG_MAX; ii++) {
|
|
461
|
+
clconfig_provider *cur = mon->all_providers[ii];
|
|
462
|
+
if (!cur) {
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
fprintf(fp, "** PROVIDER: 0x%x (%s) %p\n", cur->type, provider_string(cur->type), (void*)cur);
|
|
467
|
+
fprintf(fp, "** ENABLED: %s\n", cur->enabled ? "YES" : "NO");
|
|
468
|
+
fprintf(fp, "** CURRENT: %s\n", cur == mon->cur_provider ? "YES" : "NO");
|
|
469
|
+
if (cur->dump) {
|
|
470
|
+
cur->dump(cur, fp);
|
|
471
|
+
}
|
|
472
|
+
fprintf(fp, "\n");
|
|
473
|
+
}
|
|
474
|
+
}
|