lcb_error_t lcb_bootstrap_common(lcb_t instance, int options) { struct lcb_BOOTSTRAP *bs = instance->bootstrap; hrtime_t now = gethrtime(); if (!bs) { bs = calloc(1, sizeof(*instance->bootstrap)); if (!bs) { return LCB_CLIENT_ENOMEM; } bs->tm = lcbio_timer_new(instance->iotable, bs, initial_timeout); instance->bootstrap = bs; bs->parent = instance; lcb_confmon_add_listener(instance->confmon, &bs->listener); } if (lcb_confmon_is_refreshing(instance->confmon)) { return LCB_SUCCESS; } if (options & LCB_BS_REFRESH_THROTTLE) { /* Refresh throttle requested. This is not true if options == ALWAYS */ hrtime_t next_ts; unsigned errthresh = LCBT_SETTING(instance, weird_things_threshold); if (options & LCB_BS_REFRESH_INCRERR) { bs->errcounter++; } next_ts = bs->last_refresh; next_ts += LCB_US2NS(LCBT_SETTING(instance, weird_things_delay)); if (now < next_ts && bs->errcounter < errthresh) { lcb_log(LOGARGS(instance, INFO), "Not requesting a config refresh because of throttling parameters. Next refresh possible in %ums or %u errors. " "See LCB_CNTL_CONFDELAY_THRESH and LCB_CNTL_CONFERRTHRESH to modify the throttling settings", LCB_NS2US(next_ts-now)/1000, (unsigned)errthresh-bs->errcounter); return LCB_SUCCESS; } } if (options == LCB_BS_REFRESH_INITIAL) { lcb_confmon_prepare(instance->confmon); bs->listener.callback = config_callback; lcbio_timer_set_target(bs->tm, initial_timeout); lcbio_timer_rearm(bs->tm, LCBT_SETTING(instance, config_timeout)); lcb_aspend_add(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL); } else { /** No initial timer */ bs->listener.callback = async_step_callback; } /* Reset the counters */ bs->errcounter = 0; if (options != LCB_BS_REFRESH_INITIAL) { bs->last_refresh = now; } return lcb_confmon_start(instance->confmon); }
clconfig_provider * lcb_clconfig_create_file(lcb_confmon *parent) { file_provider *provider = calloc(1, sizeof(*provider)); if (!provider) { return NULL; } provider->base.get_cached = get_cached; provider->base.refresh = refresh_file; provider->base.pause = pause_file; provider->base.shutdown = shutdown_file; provider->base.type = LCB_CLCONFIG_FILE; provider->listener.callback = config_listener; lcb_confmon_add_listener(parent, &provider->listener); return &provider->base; }
static lcb_error_t bootstrap_common(lcb_t instance, int initial) { struct lcb_bootstrap_st *bs = instance->bootstrap; if (bs && bs->active) { return LCB_SUCCESS; } if (!bs) { bs = calloc(1, sizeof(*instance->bootstrap)); if (!bs) { return LCB_CLIENT_ENOMEM; } instance->bootstrap = bs; bs->parent = instance; lcb_confmon_add_listener(instance->confmon, &bs->listener); } bs->last_refresh = gethrtime(); bs->active = 1; if (initial) { lcb_error_t err; bs->listener.callback = config_callback; bs->timer = lcb_timer_create(instance, NULL, instance->settings.config_timeout, 0, initial_timeout, &err); if (err != LCB_SUCCESS) { return err; } } else { /** No initial timer */ bs->listener.callback = async_step_callback; } return lcb_confmon_start(instance->confmon); }