Exemplo n.º 1
0
static void connection_error(lcb_server_t *server, lcb_error_t err)
{
    lcb_failout_server(server, err);
    if (server->instance->compat.type == LCB_CACHED_CONFIG) {
        /* Try to update the cache :S */
        lcb_schedule_config_cache_refresh(server->instance);
        return;
    }

}
Exemplo n.º 2
0
static int do_read_data(lcb_server_t *c, int allow_read)
{
    lcb_sockrw_status_t status;
    lcb_size_t processed = 0;
    int rv = 0;

    /*
    ** The timers isn't supposed to be _that_ accurate.. it's better
    ** to shave off system calls :)
    */
    hrtime_t stop = gethrtime();

    if (allow_read) {
        status = lcb_sockrw_v0_slurp(&c->connection, c->connection.input);

    } else {
        status = LCB_SOCKRW_WOULDBLOCK;
    }

    while ((rv = lcb_proto_parse_single(c, stop)) > 0) {
        processed++;
    }

    if (rv == -1) {
        return -1;
    }

    if (processed) {
        lcb_connection_delay_timer(&c->connection);
    }

    if (status == LCB_SOCKRW_WOULDBLOCK || status == LCB_SOCKRW_READ) {
        return 0;
    }

    if (c->instance->compat.type == LCB_CACHED_CONFIG) {
        lcb_schedule_config_cache_refresh(c->instance);
        return 0;
    }

    return -1;
}
Exemplo n.º 3
0
/**
 * Returns 1 if retried, 0 if the command should fail, -1 for an internal
 * error
 */
static int handle_not_my_vbucket(lcb_server_t *c,
                                 protocol_binary_request_header *oldreq,
                                 struct lcb_command_data_st *oldct)
{
    int idx;
    char *body;
    lcb_size_t nbody, nr;
    lcb_server_t *new_srv;
    struct lcb_command_data_st ct;
    protocol_binary_request_header req;
    hrtime_t now;

    if (c->instance->compat.type == LCB_CACHED_CONFIG) {
        lcb_schedule_config_cache_refresh(c->instance);
    }

    /* re-schedule command to new server */
    idx = vbucket_found_incorrect_master(c->instance->vbucket_config,
                                         ntohs(oldreq->request.vbucket),
                                         (int)c->index);

    if (idx == -1) {
        return 0;
    }

    now = gethrtime();

    if (oldct->real_start) {
        hrtime_t min_ok = now - (c->connection.timeout.usec * 1000);
        if (oldct->real_start < min_ok) {
            /** Timed out in a 'natural' manner */
            return 0;
        }
    }

    req = *oldreq;

    lcb_assert((lcb_size_t)idx < c->instance->nservers);
    new_srv = c->instance->servers + idx;

    nr = lcb_ringbuffer_read(&c->cmd_log, req.bytes, sizeof(req));
    lcb_assert(nr == sizeof(req));

    req.request.opaque = ++c->instance->seqno;
    nbody = ntohl(req.request.bodylen);
    body = malloc(nbody);
    if (body == NULL) {
        lcb_error_handler(c->instance, LCB_CLIENT_ENOMEM, NULL);
        return -1;
    }
    nr = lcb_ringbuffer_read(&c->cmd_log, body, nbody);
    lcb_assert(nr == nbody);
    nr = lcb_ringbuffer_read(&c->output_cookies, &ct, sizeof(ct));
    lcb_assert(nr == sizeof(ct));

    /* Preserve the cookie and reset timestamp for the command. This
     * means that the library will retry the command until it will
     * get code different from LCB_NOT_MY_VBUCKET */
    if (!ct.real_start) {
        ct.real_start = ct.start;
    }
    ct.start = now;

    lcb_server_retry_packet(new_srv, &ct, &req, sizeof(req));
    /* FIXME dtrace instrumentation */
    lcb_server_write_packet(new_srv, body, nbody);
    lcb_server_end_packet(new_srv);
    lcb_server_send_packets(new_srv);
    free(body);

    return 1;
}