ext/libcouchbase/src/instance.cc in libcouchbase-0.0.7 vs ext/libcouchbase/src/instance.cc in libcouchbase-0.0.8

- old
+ new

@@ -114,21 +114,61 @@ const Spechost &dh = spec.hosts()[ii]; add_bs_host(dh, defl_http, defl_cccp); } } +lcb_error_t +lcb_st::process_dns_srv(Connspec& spec) +{ + if (!spec.can_dnssrv()) { + return LCB_SUCCESS; + } + if (spec.hosts().empty()) { + lcb_log(LOGARGS(this, ERR), "Cannot use DNS SRV without a hostname"); + return spec.is_explicit_dnssrv() ? LCB_EINVAL : LCB_SUCCESS; + } + + const Spechost& host = spec.hosts().front(); + lcb_error_t rc = LCB_ERROR; + Hostlist* hl = lcb_dnssrv_getbslist(host.hostname.c_str(), host.isSSL(), &rc); + + if (hl == NULL) { + lcb_log(LOGARGS(this, INFO), "DNS SRV lookup failed: %s. Ignore this if not relying on DNS SRV records", lcb_strerror(this, rc)); + if (spec.is_explicit_dnssrv()) { + return rc; + } else { + return LCB_SUCCESS; + } + } + + spec.clear_hosts(); + for (size_t ii = 0; ii < hl->size(); ++ii) { + const lcb_host_t& src = (*hl)[ii]; + Spechost sh; + sh.hostname = src.host; + sh.port = std::atoi(src.port); + sh.type = spec.default_port(); + spec.add_host(sh); + lcb_log(LOGARGS(this, INFO), "Found host %s:%d via DNS SRV", sh.hostname.c_str(), sh.port); + } + delete hl; + + return LCB_SUCCESS; +} + static lcb_error_t init_providers(lcb_t obj, const Connspec &spec) { - clconfig_provider *http, *cccp, *mcraw; - http = lcb_confmon_get_provider(obj->confmon, LCB_CLCONFIG_HTTP); - cccp = lcb_confmon_get_provider(obj->confmon, LCB_CLCONFIG_CCCP); - mcraw = lcb_confmon_get_provider(obj->confmon, LCB_CLCONFIG_MCRAW); + using namespace lcb::clconfig; + Provider *http, *cccp, *mcraw; + http = obj->confmon->get_provider(CLCONFIG_HTTP); + cccp = obj->confmon->get_provider(CLCONFIG_CCCP); + mcraw = obj->confmon->get_provider(CLCONFIG_MCRAW); if (spec.default_port() == LCB_CONFIG_MCCOMPAT_PORT) { - lcb_confmon_set_provider_active(obj->confmon, LCB_CLCONFIG_MCRAW, 1); - mcraw->configure_nodes(mcraw, obj->mc_nodes); + obj->confmon->set_active(CLCONFIG_MCRAW, true); + mcraw->configure_nodes(*obj->mc_nodes); return LCB_SUCCESS; } bool cccp_found = spec.is_bs_cccp(); bool http_found = spec.is_bs_http(); @@ -153,30 +193,30 @@ if (cccp_enabled == 0 && http_enabled == 0) { if (spec.is_bs_file()) { /* If the 'file_only' provider is set, just assume something else * will provide us with the config, and forget about it. */ - clconfig_provider *prov = lcb_confmon_get_provider(obj->confmon, LCB_CLCONFIG_FILE); + Provider *prov = obj->confmon->get_provider(CLCONFIG_FILE); if (prov && prov->enabled) { return LCB_SUCCESS; } } return LCB_BAD_ENVIRONMENT; } if (http_enabled) { - lcb_clconfig_http_enable(http); - lcb_clconfig_http_set_nodes(http, obj->ht_nodes); + http->enable(); + http->configure_nodes(*obj->ht_nodes); } else { - lcb_confmon_set_provider_active(obj->confmon, LCB_CLCONFIG_HTTP, 0); + obj->confmon->set_active(CLCONFIG_HTTP, false); } if (cccp_enabled && obj->type != LCB_TYPE_CLUSTER) { - lcb_clconfig_cccp_enable(cccp, obj); - lcb_clconfig_cccp_set_nodes(cccp, obj->mc_nodes); + cccp->enable(obj); + cccp->configure_nodes(*obj->mc_nodes); } else { - lcb_confmon_set_provider_active(obj->confmon, LCB_CLCONFIG_CCCP, 0); + obj->confmon->set_active(CLCONFIG_CCCP, false); } return LCB_SUCCESS; } static lcb_error_t @@ -377,14 +417,14 @@ obj->http_sockpool = lcbio_mgr_create(settings, obj->iotable); obj->memd_sockpool->maxidle = 1; obj->memd_sockpool->tmoidle = 10000000; obj->http_sockpool->maxidle = 1; obj->http_sockpool->tmoidle = 10000000; - obj->confmon = lcb_confmon_create(settings, obj->iotable); + obj->confmon = new clconfig::Confmon(settings, obj->iotable); obj->ht_nodes = new Hostlist(); obj->mc_nodes = new Hostlist(); - obj->retryq = lcb_retryq_new(&obj->cmdq, obj->iotable, obj->settings); + obj->retryq = new RetryQueue(&obj->cmdq, obj->iotable, obj->settings); obj->n1ql_cache = lcb_n1qlcache_create(); lcb_initialize_packet_handlers(obj); lcb_aspend_init(&obj->pendops); if ((err = setup_ssl(obj, spec)) != LCB_SUCCESS) { @@ -396,12 +436,19 @@ } if ((err = apply_env_options(obj)) != LCB_SUCCESS) { goto GT_DONE; } + if ((err = obj->process_dns_srv(spec)) != LCB_SUCCESS) { + goto GT_DONE; + } + obj->populate_nodes(spec); - err = init_providers(obj, spec); + if ((err = init_providers(obj, spec)) != LCB_SUCCESS) { + goto GT_DONE; + } + if (err != LCB_SUCCESS) { lcb_destroy(obj); return err; } @@ -431,23 +478,29 @@ IOT_STOP(sd->table); sd->stopped = 1; } } +extern "C" { +void lcbdur_destroy(void*); +} + LIBCOUCHBASE_API void lcb_destroy(lcb_t instance) { #define DESTROY(fn,fld) if(instance->fld){fn(instance->fld);instance->fld=NULL;} lcb_ASPEND *po = &instance->pendops; lcb_ASPEND_SETTYPE::iterator it; lcb_ASPEND_SETTYPE *pendq; - DESTROY(lcb_clconfig_decref, cur_configinfo); + if (instance->cur_configinfo) { + instance->cur_configinfo->decref(); + instance->cur_configinfo = NULL; + } instance->cmdq.config = NULL; - - lcb_bootstrap_destroy(instance); + DESTROY(delete, bs_state); DESTROY(delete, ht_nodes); DESTROY(delete, mc_nodes); if ((pendq = po->items[LCB_PENDTYPE_TIMER])) { for (it = pendq->begin(); it != pendq->end(); ++it) { @@ -456,30 +509,29 @@ } if ((pendq = po->items[LCB_PENDTYPE_DURABILITY])) { std::vector<void*> dsets(pendq->begin(), pendq->end()); for (size_t ii = 0; ii < dsets.size(); ++ii) { - lcbdur_destroy(reinterpret_cast<lcb_DURSET_st*>(dsets[ii])); + lcbdur_destroy(dsets[ii]); } pendq->clear(); } for (size_t ii = 0; ii < LCBT_NSERVERS(instance); ++ii) { - mc_SERVER *server = LCBT_GET_SERVER(instance, ii); - mcserver_close(server); + instance->get_server(ii)->close(); } if ((pendq = po->items[LCB_PENDTYPE_HTTP])) { for (it = pendq->begin(); it != pendq->end(); ++it) { - lcb_http_request_t htreq = reinterpret_cast<lcb_http_request_t>(*it); - lcb_htreq_block_callback(htreq); - lcb_htreq_finish(instance, htreq, LCB_ERROR); + http::Request *htreq = reinterpret_cast<http::Request*>(*it); + htreq->block_callback(); + htreq->finish(LCB_ERROR); } } - DESTROY(lcb_retryq_destroy, retryq); - DESTROY(lcb_confmon_destroy, confmon); + DESTROY(delete, retryq); + DESTROY(delete, confmon); DESTROY(lcbio_mgr_destroy, memd_sockpool); DESTROY(lcbio_mgr_destroy, http_sockpool); DESTROY(lcb_vbguess_destroy, vbguess); DESTROY(lcb_n1qlcache_destroy, n1ql_cache); @@ -529,14 +581,27 @@ instance->dtor_timer = lcbio_timer_new(instance->iotable, instance, destroy_cb); instance->settings->dtorarg = (void *)arg; lcbio_async_signal(instance->dtor_timer); } +lcb::Server * +lcb_st::find_server(const lcb_host_t& host) const +{ + unsigned ii; + for (ii = 0; ii < cmdq.npipelines; ii++) { + lcb::Server *server = static_cast<lcb::Server*>(cmdq.pipelines[ii]); + if (lcb_host_equals(&server->get_host(), &host)) { + return server; + } + } + return NULL; +} + LIBCOUCHBASE_API lcb_error_t lcb_connect(lcb_t instance) { - lcb_error_t err = lcb_bootstrap_common(instance, LCB_BS_REFRESH_INITIAL); + lcb_error_t err = instance->bootstrap(BS_REFRESH_INITIAL); if (err == LCB_SUCCESS) { SYNCMODE_INTERCEPT(instance); } else { return err; } @@ -711,9 +776,18 @@ LCB_XERR(X) #undef X (void)instance; return "Unknown error"; +} + +LCB_INTERNAL_API +const char *lcb_strerror_short(lcb_error_t error) +{ +#define X(c, v, t, s) if (error == c) { return #c " (" #v ")"; } + LCB_XERR(X) +#undef X + return "<FIXME: Not an LCB error>"; } LIBCOUCHBASE_API int lcb_get_errtype(lcb_error_t err) {