Ejemplo n.º 1
0
int main(int argc, const char *argv[])
{
    if(setup_cli(argc, argv) == -1) {
        usage(argv[0]);
        return EXIT_FAILURE;
    }

    config.syslog = 0;
    config.loglevel = CRIT;
    config.bufsize = 16384;

    struct node_conf conf = {NULL, 0};
    struct context ctx;
    context_init(&ctx);
    memcpy(&config.node, &conf, sizeof(config.node));
    slot_init_updater(&ctx);

    RUN_CASE(test_slot);
    RUN_CASE(test_hash);
    RUN_CASE(test_parser);
    RUN_CASE(test_cmd);
    RUN_CASE(test_server);
    RUN_CASE(test_dict);
    RUN_CASE(test_socket);
    RUN_CASE(test_client);
    RUN_CASE(test_timer);
    RUN_CASE(test_config);

    usleep(10000);
    slot_create_job(SLOT_UPDATER_QUIT);
    pthread_join(ctx.thread, NULL);

    report();
    return manager.failed == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
Ejemplo n.º 2
0
int main(int argc, const char *argv[])
{
    if(setup_cli(argc, argv) == -1) {
        usage(argv[0]);
        return EXIT_FAILURE;
    }

    config.syslog = 0;
    config.loglevel = CRIT;
    config.bufsize = 16384;
    config.thread = 1;

    struct node_conf conf = {NULL, 0};
    build_contexts();
    struct context *contexts = get_contexts();

    memcpy(&config.node, &conf, sizeof(config.node));
    slot_start_manager(&contexts[config.thread]);

    RUN_CASE(test_slot);
    RUN_CASE(test_hash);
    RUN_CASE(test_parser);
    RUN_CASE(test_cmd);
    RUN_CASE(test_server);
    RUN_CASE(test_dict);
    RUN_CASE(test_socket);
    RUN_CASE(test_client);
    RUN_CASE(test_timer);
    RUN_CASE(test_config);
    RUN_CASE(test_stats);
    RUN_CASE(test_mbuf);
    RUN_CASE(test_slowlog);

    usleep(10000);
    slot_create_job(SLOT_UPDATER_QUIT);
    pthread_join(contexts[config.thread].thread, NULL);

    for (int i = 0; i <= config.thread; i++) {
        context_free(&contexts[i]);
    }

    destroy_contexts();

    report();
    return manager.failed == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
Ejemplo n.º 3
0
void server_eof(struct connection *server, const char *reason)
{
    LOG(WARN, "server eof");

    struct command *c;
    while (!STAILQ_EMPTY(&server->info->ready_queue)) {
        c = STAILQ_FIRST(&server->info->ready_queue);
        STAILQ_REMOVE_HEAD(&server->info->ready_queue, ready_next);
        STAILQ_NEXT(c, ready_next) = NULL;
        if (c->stale) {
            cmd_free(c);
        } else {
            cmd_mark_fail(c, reason);
        }
    }

    // remove unprocessed data
    struct mbuf *b = TAILQ_LAST(&server->info->data, mhdr);
    if (b != NULL && b->pos < b->last) {
        b->pos = b->last;
    }

    while (!STAILQ_EMPTY(&server->info->waiting_queue)) {
        c = STAILQ_FIRST(&server->info->waiting_queue);
        STAILQ_REMOVE_HEAD(&server->info->waiting_queue, waiting_next);
        STAILQ_NEXT(c, waiting_next) = NULL;
        mbuf_range_clear(server->ctx, c->rep_buf);
        if (c->stale) {
            cmd_free(c);
        } else {
            cmd_mark_fail(c, reason);
        }
    }

    event_deregister(&server->ctx->loop, server);

    // drop all unsent requests
    cmd_iov_free(&server->info->iov);
    conn_free(server);
    slot_create_job(SLOT_UPDATE);
}
Ejemplo n.º 4
0
int server_read_reply(struct connection *server, struct command *cmd)
{
    int status = cmd_read_rep(cmd, server);
    if (status != CORVUS_OK) return status;

    ATOMIC_INC(server->info->completed_commands, 1);

    if (server->info->readonly_sent) {
        return CORVUS_READONLY;
    }

    if (cmd->asking) return CORVUS_ASKING;

    if (cmd->stale) {
        mbuf_range_clear(cmd->ctx, cmd->rep_buf);
        return CORVUS_OK;
    }

    if (cmd->reply_type != REP_ERROR) {
        cmd_mark_done(cmd);
        return CORVUS_OK;
    }

    struct redirect_info info = {.type = CMD_ERR, .slot = -1};
    memset(info.addr, 0, sizeof(info.addr));

    if (cmd_parse_redirect(cmd, &info) == CORVUS_ERR) {
        mbuf_range_clear(cmd->ctx, cmd->rep_buf);
        cmd_mark_fail(cmd, rep_redirect_err);
        return CORVUS_OK;
    }
    switch (info.type) {
        case CMD_ERR_MOVED:
            slot_create_job(SLOT_UPDATE);
            CHECK_REDIRECTED(cmd, info.addr, rep_redirect_err);
            return server_redirect(cmd, &info);
        case CMD_ERR_ASK:
            CHECK_REDIRECTED(cmd, info.addr, rep_redirect_err);
            cmd->asking = 1;
            return server_redirect(cmd, &info);
        case CMD_ERR_CLUSTERDOWN:
            slot_create_job(SLOT_UPDATE);
            CHECK_REDIRECTED(cmd, NULL, NULL);
            return server_retry(cmd);
        default:
            cmd_mark_done(cmd);
            break;
    }
    return CORVUS_OK;
}

int server_read(struct connection *server)
{
    int status = CORVUS_OK;
    struct command *cmd;
    struct conn_info *info = server->info;
    int64_t now = get_time();

    while (!STAILQ_EMPTY(&info->waiting_queue)) {
        cmd = STAILQ_FIRST(&info->waiting_queue);
        status = server_read_reply(server, cmd);

        cmd->rep_time[1] = now;

        switch (status) {
            case CORVUS_ASKING:
                LOG(DEBUG, "recv asking");
                mbuf_range_clear(cmd->ctx, cmd->rep_buf);
                cmd->asking = 0;
                continue;
            case CORVUS_READONLY:
                LOG(DEBUG, "recv readonly");
                mbuf_range_clear(cmd->ctx, cmd->rep_buf);
                server->info->readonly_sent = false;
                continue;
            case CORVUS_OK:
                STAILQ_REMOVE_HEAD(&info->waiting_queue, waiting_next);
                STAILQ_NEXT(cmd, waiting_next) = NULL;
                if (cmd->stale) cmd_free(cmd);
                continue;
        }
        break;
    }
    info->last_active = -1;
    return status;
}