libcouchbase 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/README.md +1 -1
  4. data/ext/libcouchbase/CMakeLists.txt +8 -6
  5. data/ext/libcouchbase/README.markdown +2 -2
  6. data/ext/libcouchbase/RELEASE_NOTES.markdown +0 -86
  7. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +0 -11
  8. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +0 -2
  9. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +1 -2
  10. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  11. data/ext/libcouchbase/cmake/config-cmake.h.in +0 -2
  12. data/ext/libcouchbase/cmake/defs.mk.in +2 -0
  13. data/ext/libcouchbase/cmake/source_files.cmake +5 -21
  14. data/ext/libcouchbase/include/libcouchbase/auth.h +0 -10
  15. data/ext/libcouchbase/include/libcouchbase/cntl.h +1 -27
  16. data/ext/libcouchbase/include/libcouchbase/error.h +1 -15
  17. data/ext/libcouchbase/include/libcouchbase/n1ql.h +1 -13
  18. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
  19. data/ext/libcouchbase/include/libcouchbase/subdoc.h +0 -9
  20. data/ext/libcouchbase/include/libcouchbase/views.h +1 -7
  21. data/ext/libcouchbase/include/libcouchbase/visibility.h +0 -1
  22. data/ext/libcouchbase/include/memcached/protocol_binary.h +1131 -29
  23. data/ext/libcouchbase/include/memcached/vbucket.h +42 -0
  24. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  25. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +2 -3
  26. data/ext/libcouchbase/src/README.md +2 -0
  27. data/ext/libcouchbase/src/auth-priv.h +0 -1
  28. data/ext/libcouchbase/src/auth.cc +4 -10
  29. data/ext/libcouchbase/src/bootstrap.c +269 -0
  30. data/ext/libcouchbase/src/bootstrap.h +39 -50
  31. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +117 -84
  32. data/ext/libcouchbase/src/bucketconfig/bc_file.c +347 -0
  33. data/ext/libcouchbase/src/bucketconfig/bc_http.c +630 -0
  34. data/ext/libcouchbase/src/bucketconfig/bc_http.h +25 -50
  35. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +150 -0
  36. data/ext/libcouchbase/src/bucketconfig/clconfig.h +386 -407
  37. data/ext/libcouchbase/src/bucketconfig/confmon.c +474 -0
  38. data/ext/libcouchbase/src/cbft.cc +27 -22
  39. data/ext/libcouchbase/src/cntl.cc +19 -30
  40. data/ext/libcouchbase/src/connspec.cc +1 -48
  41. data/ext/libcouchbase/src/connspec.h +0 -27
  42. data/ext/libcouchbase/src/dump.cc +2 -2
  43. data/ext/libcouchbase/src/getconfig.cc +33 -7
  44. data/ext/libcouchbase/src/handler.cc +2 -0
  45. data/ext/libcouchbase/src/hostlist.cc +36 -0
  46. data/ext/libcouchbase/src/hostlist.h +62 -41
  47. data/ext/libcouchbase/src/http/http-priv.h +112 -125
  48. data/ext/libcouchbase/src/http/http.cc +30 -15
  49. data/ext/libcouchbase/src/http/http.h +34 -1
  50. data/ext/libcouchbase/src/http/http_io.cc +26 -22
  51. data/ext/libcouchbase/src/instance.cc +23 -94
  52. data/ext/libcouchbase/src/internal.h +26 -52
  53. data/ext/libcouchbase/src/jsparse/parser.cc +202 -146
  54. data/ext/libcouchbase/src/jsparse/parser.h +98 -91
  55. data/ext/libcouchbase/src/lcbht/lcbht.c +282 -0
  56. data/ext/libcouchbase/src/lcbht/lcbht.h +163 -174
  57. data/ext/libcouchbase/src/lcbio/connect.c +557 -0
  58. data/ext/libcouchbase/src/lcbio/connect.h +2 -9
  59. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  60. data/ext/libcouchbase/src/lcbio/iotable.h +16 -61
  61. data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
  62. data/ext/libcouchbase/src/lcbio/manager.c +2 -2
  63. data/ext/libcouchbase/src/mc/mcreq.h +2 -9
  64. data/ext/libcouchbase/src/mcserver/mcserver.cc +34 -143
  65. data/ext/libcouchbase/src/mcserver/mcserver.h +12 -7
  66. data/ext/libcouchbase/src/mcserver/negotiate.cc +38 -132
  67. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
  68. data/ext/libcouchbase/src/n1ql/n1ql.cc +32 -56
  69. data/ext/libcouchbase/src/newconfig.cc +6 -6
  70. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  71. data/ext/libcouchbase/src/operations/{cbflush.cc → cbflush.c} +15 -7
  72. data/ext/libcouchbase/src/operations/{counter.cc → counter.c} +0 -0
  73. data/ext/libcouchbase/src/operations/durability.cc +26 -6
  74. data/ext/libcouchbase/src/operations/durability_internal.h +3 -6
  75. data/ext/libcouchbase/src/operations/{get.cc → get.c} +26 -24
  76. data/ext/libcouchbase/src/operations/{observe.cc → observe.c} +93 -68
  77. data/ext/libcouchbase/src/operations/{pktfwd.cc → pktfwd.c} +0 -0
  78. data/ext/libcouchbase/src/operations/{remove.cc → remove.c} +0 -0
  79. data/ext/libcouchbase/src/operations/stats.cc +8 -3
  80. data/ext/libcouchbase/src/operations/{store.cc → store.c} +32 -27
  81. data/ext/libcouchbase/src/operations/subdoc.cc +18 -38
  82. data/ext/libcouchbase/src/operations/{touch.cc → touch.c} +0 -0
  83. data/ext/libcouchbase/src/packetutils.c +37 -0
  84. data/ext/libcouchbase/src/packetutils.h +2 -2
  85. data/ext/libcouchbase/src/probes.d +1 -1
  86. data/ext/libcouchbase/src/{retrychk.cc → retrychk.c} +3 -2
  87. data/ext/libcouchbase/src/retryq.cc +4 -4
  88. data/ext/libcouchbase/src/settings.c +0 -3
  89. data/ext/libcouchbase/src/settings.h +0 -5
  90. data/ext/libcouchbase/src/simplestring.c +211 -0
  91. data/ext/libcouchbase/src/simplestring.h +228 -0
  92. data/ext/libcouchbase/src/ssl/ssl_c.c +0 -1
  93. data/ext/libcouchbase/src/ssl/ssl_common.c +0 -2
  94. data/ext/libcouchbase/src/ssl/ssl_e.c +1 -0
  95. data/ext/libcouchbase/src/ssobuf.h +82 -0
  96. data/ext/libcouchbase/src/trace.h +4 -4
  97. data/ext/libcouchbase/src/vbucket/vbucket.c +1 -0
  98. data/ext/libcouchbase/src/views/{docreq.cc → docreq.c} +54 -48
  99. data/ext/libcouchbase/src/views/docreq.h +30 -24
  100. data/ext/libcouchbase/src/views/viewreq.c +358 -0
  101. data/ext/libcouchbase/src/views/viewreq.h +13 -43
  102. data/ext/libcouchbase/tests/basic/t_connstr.cc +50 -89
  103. data/ext/libcouchbase/tests/basic/t_host.cc +75 -67
  104. data/ext/libcouchbase/tests/basic/t_jsparse.cc +78 -27
  105. data/ext/libcouchbase/tests/basic/t_string.cc +112 -0
  106. data/ext/libcouchbase/tests/htparse/t_basic.cc +78 -58
  107. data/ext/libcouchbase/tests/iotests/mock-environment.h +1 -2
  108. data/ext/libcouchbase/tests/iotests/t_confmon.cc +114 -96
  109. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  110. data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
  111. data/lib/libcouchbase/ext/tasks.rb +6 -2
  112. data/lib/libcouchbase/query_view.rb +1 -1
  113. data/lib/libcouchbase/results_fiber.rb +6 -6
  114. data/lib/libcouchbase/version.rb +1 -1
  115. metadata +26 -26
  116. data/ext/libcouchbase/src/bootstrap.cc +0 -216
  117. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +0 -281
  118. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +0 -528
  119. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +0 -115
  120. data/ext/libcouchbase/src/bucketconfig/confmon.cc +0 -378
  121. data/ext/libcouchbase/src/dns-srv.cc +0 -142
  122. data/ext/libcouchbase/src/errmap.cc +0 -107
  123. data/ext/libcouchbase/src/errmap.h +0 -113
  124. data/ext/libcouchbase/src/lcbht/lcbht.cc +0 -177
  125. data/ext/libcouchbase/src/lcbio/connect.cc +0 -562
  126. data/ext/libcouchbase/src/lcbio/timer-cxx.h +0 -87
  127. data/ext/libcouchbase/src/mctx-helper.h +0 -51
  128. data/ext/libcouchbase/src/views/viewreq.cc +0 -318
  129. 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-cxx.h>
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
- struct CccpCookie;
37
+ #define PROVIDER_SETTING_T(fld) PROVIDER_SETTING(this, fld)
37
38
 
38
- using namespace lcb::clconfig;
39
+ struct CccpCookie;
39
40
 
40
- struct CccpProvider : public Provider {
41
- CccpProvider(Confmon *);
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
- ConfigInfo *config;
54
+ clconfig_info *config;
73
55
  bool server_active;
74
- lcb::io::Timer<CccpProvider, &CccpProvider::on_timeout> timer;
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.cancel();
128
- parent->provider_failed(this, err);
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->find_server(*next_host);
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.rearm(settings().config_node_timeout);
139
- instance->request_config(cookie, server);
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
- settings().config_node_timeout,
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 "Could not get configuration: %s", LOGID(this), lcb_strerror_short(err));
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
- lcb::clconfig::cccp_update(Provider *provider, const char *host, const char *data) {
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
- ConfigInfo *new_config;
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 = ConfigInfo::create(vbc, CLCONFIG_CCCP);
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->decref();
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
- parent->provider_got_config(this, new_config);
207
+ lcb_confmon_provider_success(this, new_config);
209
208
  return LCB_SUCCESS;
210
209
  }
211
210
 
212
- void lcb::clconfig::cccp_update(
213
- const void *cookie, lcb_error_t err,
214
- const void *bytes, size_t nbytes, const lcb_host_t *origin)
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.cancel();
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 CccpProvider::refresh() {
268
- if (creq.u.p_generic || server_active || cmdcookie) {
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
- bool
276
- CccpProvider::pause()
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
- if (!server_active) {
279
- return true;
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.cancel();
285
- return true;
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->decref();
301
+ lcb_clconfig_decref(config);
293
302
  }
294
303
  if (nodes) {
295
304
  delete nodes;
296
305
  }
297
- timer.release();
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
- CccpProvider::configure_nodes(const lcb::Hostlist& nodes_)
314
+ static void
315
+ configure_nodes(clconfig_provider *pb, const hostlist_t nodes)
305
316
  {
306
- nodes->assign(nodes_);
307
- if (parent->settings->randomize_bootstrap_nodes) {
308
- nodes->randomize();
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::config_updated(lcbvb_CONFIG *vbc)
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 (settings().sslopts & LCB_SSL_ENABLED) {
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 (settings().randomize_bootstrap_nodes) {
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.cancel();
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.rearm(settings().config_node_timeout);
430
+ lcbio_timer_rearm(timer, PROVIDER_SETTING(this, config_node_timeout));
415
431
  }
416
432
 
417
- void CccpProvider::dump(FILE *fp) const {
418
- if (!enabled) {
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.is_armed() ? "YES" : "NO");
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
- CccpProvider::CccpProvider(Confmon *mon)
442
- : Provider(mon, CLCONFIG_CCCP),
443
- nodes(new lcb::Hostlist()),
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(mon->iot, this),
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
+ }