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); }
lcb_error_t lcb_bootstrap_initial(lcb_t instance) { lcb_confmon_prepare(instance->confmon); return bootstrap_common(instance, 1); }