예제 #1
0
파일: nc_core.c 프로젝트: dzch/twemproxy
rstatus_t
core_loop(struct context *ctx)
{
    int nsd, delta;
    int64_t now;

    now = nc_msec_now();
    while (now >= ctx->next_tick) {
        core_tick(ctx);
        ctx->next_tick += NC_TICK_INTERVAL;
    }

    delta = (int)(ctx->next_tick - now);

    ASSERT(delta > 0);
    
    ctx->timeout = MIN(delta, ctx->timeout);

    nsd = event_wait(ctx->evb, ctx->timeout);
    if (nsd < 0) {
        return nsd;
    }
    
    core_timeout(ctx);
    
    stats_swap(ctx->stats);

    return NC_OK;
}
예제 #2
0
static void
core_timeout(struct context *ctx)
{
    for (;;) {
        struct msg *msg;
        struct conn *conn;
        int64_t now, then;

        msg = msg_tmo_min();
        if (msg == NULL) {
            ctx->timeout = ctx->max_timeout;
            return;
        }

        /* skip over req that are in-error or done */

        if (msg->error || msg->done) {
            msg_tmo_delete(msg);
            continue;
        }

        /*
         * timeout expired req and all the outstanding req on the timing
         * out server
         */

        conn = msg->tmo_rbe.data;
        then = msg->tmo_rbe.key;

        now = nc_msec_now();
        if (now < then) {
            int delta = (int)(then - now);
            ctx->timeout = MIN(delta, ctx->max_timeout);
            return;
        }

        log_debug(LOG_INFO, "req %"PRIu64" on s %d timedout", msg->id, conn->sd);

        msg_tmo_delete(msg);
        conn->err = ETIMEDOUT;

        core_close(ctx, conn);
    }
}
예제 #3
0
파일: nc_core.c 프로젝트: dzch/twemproxy
static struct context *
core_ctx_create(struct instance *nci)
{
    rstatus_t status;
    struct context *ctx;
    int64_t now;
    uint32_t npool;

    ctx = nc_alloc(sizeof(*ctx));
    if (ctx == NULL) {
        return NULL;
    }

    now = nc_msec_now();
    if (now < 0) {
        nc_free(ctx);
        return NULL;
    }

    ctx->id = ++ctx_id;
    ctx->cf = NULL;
    ctx->stats = NULL;
    ctx->evb = NULL;
    array_null(&ctx->pool);
    ctx->max_timeout = nci->stats_interval;
    ctx->timeout = ctx->max_timeout;
    ctx->next_tick = now + NC_TICK_INTERVAL;

    /* parse and create configuration */
    ctx->cf = conf_create(nci->conf_filename);
    if (ctx->cf == NULL) {
        nc_free(ctx);
        return NULL;
    }

    npool = array_n(&ctx->cf->pool);
    
    /* initialize server pool from configuration */
    if (npool != 0) {
        status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx);
        if (status != NC_OK) {
            conf_destroy(ctx->cf);
            nc_free(ctx);
            return NULL;
        }
    }

    /* create stats per server pool */
    if (npool != 0) {
        ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval,
                                  nci->hostname, &ctx->pool);
        if (ctx->stats == NULL) {
            server_pool_deinit(&ctx->pool);
            conf_destroy(ctx->cf);
            nc_free(ctx);
            return NULL;
        }
    }

    /* initialize event handling for client, proxy and server */
    ctx->evb = evbase_create(NC_EVENT_SIZE, &core_core);
    if (ctx->evb == NULL) {
        stats_destroy(ctx->stats);
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* preconnect? servers in server pool */
    if (npool != 0) {
        status = server_pool_preconnect(ctx);
        if (status != NC_OK) {
            server_pool_disconnect(ctx);
            evbase_destroy(ctx->evb);
            stats_destroy(ctx->stats);
            server_pool_deinit(&ctx->pool);
            conf_destroy(ctx->cf);
            nc_free(ctx);
            return NULL;
        }
    }

    /* initialize proxy per server pool */
    if (npool != 0) {
        status = proxy_init(ctx);
        if (status != NC_OK) {
            server_pool_disconnect(ctx);
            evbase_destroy(ctx->evb);
            stats_destroy(ctx->stats);
            server_pool_deinit(&ctx->pool);
            conf_destroy(ctx->cf);
            nc_free(ctx);
            return NULL;
        }
    }

    log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id);

    return ctx;
}