Exemplo n.º 1
0
static lcb_error_t
obs_ctxadd(lcb_MULTICMD_CTX *mctx, const lcb_CMDBASE *cmdbase)
{
    int vbid, srvix_dummy;
    unsigned ii;
    const lcb_CMDOBSERVE *cmd = (const lcb_CMDOBSERVE *)cmdbase;
    OBSERVECTX *ctx = CTX_FROM_MULTI(mctx);
    lcb_t instance = ctx->instance;
    mc_CMDQUEUE *cq = &instance->cmdq;
    lcb_U16 servers_s[4];
    const lcb_U16 *servers;
    size_t nservers;

    if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) {
        return LCB_EMPTY_KEY;
    }

    if (cq->config == NULL) {
        return LCB_CLIENT_ETMPFAIL;
    }

    if (LCBVB_DISTTYPE(LCBT_VBCONFIG(instance)) != LCBVB_DIST_VBUCKET) {
        return LCB_NOT_SUPPORTED;
    }

    mcreq_map_key(cq, &cmd->key, &cmd->_hashkey, 24, &vbid, &srvix_dummy);

    if (cmd->servers_) {
        servers = cmd->servers_;
        nservers = cmd->nservers_;
    } else {
        nservers = 0;
        servers = servers_s;
        /* Replicas are always < 4 */
        for (ii = 0; ii < LCBVB_NREPLICAS(cq->config) + 1; ii++) {
            int ix = lcbvb_vbserver(cq->config, vbid, ii);
            if (ix < 0) {
                if (ii == 0) {
                    return LCB_NO_MATCHING_SERVER;
                } else {
                    continue;
                }
            }
            servers_s[nservers++] = ix;
            if (cmd->cmdflags & LCB_CMDOBSERVE_F_MASTER_ONLY) {
                break; /* Only a single server! */
            }
        }
    }

    if (nservers == 0) {
        return LCB_NO_MATCHING_SERVER;
    }

    for (ii = 0; ii < nservers; ii++) {
        lcb_string *rr;
        lcb_U16 vb16, klen16;
        lcb_U16 ix = servers[ii];

        lcb_assert(ix < ctx->nrequests);
        rr = ctx->requests + ix;
        if (0 != lcb_string_reserve(rr, 4 + cmd->key.contig.nbytes)) {
            return LCB_CLIENT_ENOMEM;
        }

        vb16 = htons((lcb_U16)vbid);
        klen16 = htons((lcb_U16)cmd->key.contig.nbytes);
        lcb_string_append(rr, &vb16, sizeof vb16);
        lcb_string_append(rr, &klen16, sizeof klen16);
        lcb_string_append(rr, cmd->key.contig.bytes, cmd->key.contig.nbytes);

        ctx->remaining++;
    }
    return LCB_SUCCESS;
}
Exemplo n.º 2
0
static lcb_error_t
obs_ctxadd(lcb_MULTICMD_CTX *mctx, const lcb_CMDOBSERVE *cmd)
{
    const void *hk;
    lcb_SIZE nhk;
    int vbid;
    unsigned maxix;
    int ii;
    OBSERVECTX *ctx = CTX_FROM_MULTI(mctx);
    lcb_t instance = ctx->instance;
    mc_CMDQUEUE *cq = &instance->cmdq;

    if (LCB_KEYBUF_IS_EMPTY(&cmd->key)) {
        return LCB_EMPTY_KEY;
    }

    if (cq->config == NULL) {
        return LCB_CLIENT_ETMPFAIL;
    }

    if (LCBVB_DISTTYPE(LCBT_VBCONFIG(instance)) != LCBVB_DIST_VBUCKET) {
        return LCB_NOT_SUPPORTED;
    }

    mcreq_extract_hashkey(&cmd->key, &cmd->_hashkey, 24, &hk, &nhk);
    vbid = lcbvb_k2vb(cq->config, hk, nhk);
    maxix = LCBVB_NREPLICAS(cq->config);

    for (ii = -1; ii < (int)maxix; ++ii) {
        struct observe_st *rr;
        lcb_U16 vb16, klen16;
        int ix;

        if (ii == -1) {
            ix = lcbvb_vbmaster(cq->config, vbid);
            if (ix < 0) {
                return LCB_NO_MATCHING_SERVER;
            }
        } else {
            ix = lcbvb_vbreplica(cq->config, vbid, ii);
            if (ix < 0) {
                continue;
            }
        }

        lcb_assert(ix < (int)ctx->nrequests);
        rr = ctx->requests + ix;
        if (!rr->allocated) {
            if (!init_request(rr)) {
                return LCB_CLIENT_ENOMEM;
            }
        }

        vb16 = htons((lcb_U16)vbid);
        klen16 = htons((lcb_U16)cmd->key.contig.nbytes);
        lcb_string_append(&rr->body, &vb16, sizeof vb16);
        lcb_string_append(&rr->body, &klen16, sizeof klen16);
        lcb_string_append(&rr->body, cmd->key.contig.bytes, cmd->key.contig.nbytes);

        ctx->remaining++;
        if (cmd->cmdflags & LCB_CMDOBSERVE_F_MASTER_ONLY) {
            break;
        }
    }
    return LCB_SUCCESS;
}
Exemplo n.º 3
0
/**
 * This function is where the configuration actually takes place. We ensure
 * in other functions that this is only ever called directly from an event
 * loop stack frame (or one of the small mini functions here) so that we
 * don't accidentally end up destroying resources underneath us.
 */
static void
config_callback(clconfig_listener *listener, clconfig_event_t event,
    clconfig_info *info)
{
    struct lcb_BOOTSTRAP *bs = (struct lcb_BOOTSTRAP *)listener;
    lcb_t instance = bs->parent;

    if (event != CLCONFIG_EVENT_GOT_NEW_CONFIG) {
        if (event == CLCONFIG_EVENT_PROVIDERS_CYCLED) {
            if (!LCBT_VBCONFIG(instance)) {
                initial_bootstrap_error(
                    instance, LCB_ERROR, "No more bootstrap providers remain");
            }
        }
        return;
    }

    instance->last_error = LCB_SUCCESS;
    /** Ensure we're not called directly twice again */
    listener->callback = async_step_callback;
    lcbio_timer_disarm(bs->tm);

    lcb_log(LOGARGS(instance, DEBUG), "Instance configured!");

    if (info->origin != LCB_CLCONFIG_FILE) {
        /* Set the timestamp for the current config to control throttling,
         * but only if it's not an initial file-based config. See CCBC-482 */
        bs->last_refresh = gethrtime();
        bs->errcounter = 0;
    }

    if (info->origin == LCB_CLCONFIG_CCCP) {
        /* Disable HTTP provider if we've received something via CCCP */

        if (instance->cur_configinfo == NULL ||
                instance->cur_configinfo->origin != LCB_CLCONFIG_HTTP) {
            /* Never disable HTTP if it's still being used */
            lcb_confmon_set_provider_active(
                instance->confmon, LCB_CLCONFIG_HTTP, 0);
        }
    }

    if (instance->type != LCB_TYPE_CLUSTER) {
        lcb_update_vbconfig(instance, info);
    }

    if (!bs->bootstrapped) {
        bs->bootstrapped = 1;
        lcb_aspend_del(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL);

        if (instance->type == LCB_TYPE_BUCKET &&
                LCBVB_DISTTYPE(LCBT_VBCONFIG(instance)) == LCBVB_DIST_KETAMA &&
                instance->cur_configinfo->origin != LCB_CLCONFIG_MCRAW) {

            lcb_log(LOGARGS(instance, INFO), "Reverting to HTTP Config for memcached buckets");
            instance->settings->bc_http_stream_time = -1;
            lcb_confmon_set_provider_active(
                instance->confmon, LCB_CLCONFIG_HTTP, 1);
            lcb_confmon_set_provider_active(
                instance->confmon, LCB_CLCONFIG_CCCP, 0);
        }
        instance->callbacks.bootstrap(instance, LCB_SUCCESS);
    }

    lcb_maybe_breakout(instance);
}