Esempio n. 1
0
static void
core_close(struct context *ctx, struct conn *conn)
{
    rstatus_t status;
    char type, *addrstr;

    ASSERT(conn->sd > 0);

    if (conn->client) {
        type = 'c';
        addrstr = nc_unresolve_peer_desc(conn->sd);
    } else {
        type = conn->proxy ? 'p' : 's';
        addrstr = nc_unresolve_addr(conn->addr, conn->addrlen);
    }
    log_debug(LOG_NOTICE, "close %c %d '%s' on event %04"PRIX32" eof %d done "
              "%d rb %zu sb %zu%c %s", type, conn->sd, addrstr, conn->events,
              conn->eof, conn->done, conn->recv_bytes, conn->send_bytes,
              conn->err ? ':' : ' ', conn->err ? strerror(conn->err) : "");

    status = event_del_conn(ctx->ep, conn);
    if (status < 0) {
        log_warn("event del conn e %d %c %d failed, ignored: %s", ctx->ep,
                 type, conn->sd, strerror(errno));
    }

    conn->close(ctx, conn);
}
Esempio n. 2
0
static void
core_close(struct context *ctx, struct conn *conn)
{
	rstatus_t status;

	ASSERT(conn->sd > 0);

    core_close_log(conn);

	status = event_del_conn(ctx->evb, conn);
	if (status < 0) {
		log_warn("event del conn %d failed, ignored: %s",
		          conn->sd, strerror(errno));
	}

	conn_close(ctx, conn);
}
Esempio n. 3
0
void conn_close(conn_t *c)
{
    if (!c) {
        return;
    }
    if (c->fd > 0) {
        close(c->fd);
        c->fd = FAST_INVALID_FILE;
    
        //remove timers
        if (c->read->timer_set && c->ev_timer) {
            event_timer_del(c->ev_timer, c->read);
        }

        if (c->write->timer_set && c->ev_timer) {
            event_timer_del(c->ev_timer, c->write);
        }

        if (c->ev_base) {
            event_del_conn(c->ev_base, c, EVENT_CLOSE_EVENT);
        }

    } 
}
Esempio n. 4
0
static void
rsp_forward(struct context *ctx, struct conn *s_conn, struct msg *msg)
{
    rstatus_t status;
    struct msg *pmsg;
    struct conn *c_conn;

    ASSERT(!s_conn->client && !s_conn->proxy);

    /* response from server implies that server is ok and heartbeating */
    server_ok(ctx, s_conn);

    /* dequeue peer message (request) from server */
    pmsg = TAILQ_FIRST(&s_conn->omsg_q);
    ASSERT(pmsg != NULL && pmsg->peer == NULL);
    ASSERT(pmsg->request && !pmsg->done);

    s_conn->dequeue_outq(ctx, s_conn, pmsg);
	
    pmsg->done = 1;

    /* establish msg <-> pmsg (response <-> request) link */
    pmsg->peer = msg;
    msg->peer = pmsg;

#if 1 //shenzheng 2015-6-25 replace server
	if(pmsg->replace_server)
	{
		log_debug(LOG_DEBUG, "msg->error : %d", msg->error);
		struct server_pool *sp;
		struct conf_server *cs;
		struct server *ser_curr, *ser_new;
		struct conf_pool *cp;
		struct string host;
		struct stats_pool *stp;
		struct stats_server *sts;
		uint32_t p_idx, s_idx;
		uint8_t *p, *q, *last;
		int k = 0;

		ser_new = s_conn->owner;

		ASSERT(pmsg->server == ser_new);

		ASSERT(pmsg->conf_version_curr == ctx->conf_version);
		
		while(msg->error == 0 && k < 1)
		{			
			string_init(&host);
			
			sp = ser_new->owner;
			
			p_idx = sp->idx;
			cp = array_get(&(ctx->cf->pool), p_idx);

			s_idx = ser_new->idx;
			
			ser_curr = array_get(&sp->server, s_idx);
			cs = array_get(&cp->server, s_idx);
			
			ASSERT(ser_curr->idx == ser_new->idx);
			ASSERT(ser_curr->owner == ser_new->owner);
			ASSERT(ser_curr->weight == ser_new->weight);
			ASSERT(ser_curr->name_null == ser_new->name_null);
			
			p = ser_new->pname.data;
			last = ser_new->pname.data + ser_new->pname.len;
			q = nc_strchr(p, last, ':');
			if(q == NULL || q >= last || q <= ser_new->pname.data)
			{
				log_debug(LOG_DEBUG, "new server address(%s) error", ser_new->pname.data);
				break;
			}
			
			string_copy(&host, ser_new->pname.data, (uint32_t)(q - ser_new->pname.data));
			log_debug(LOG_DEBUG, "new server host : %.*s", host.len, host.data);
			log_debug(LOG_DEBUG, "new server port : %d", ser_new->port);
			status = nc_resolve(&host, ser_new->port, &cs->info);
		    if (status != NC_OK) 
			{
				log_debug(LOG_DEBUG, "resolve new server address error(%d)", status);
				string_deinit(&host);
				break;
		    }
			
			k ++;
			while (!TAILQ_EMPTY(&ser_curr->s_conn_q)) {
				struct conn *conn;

				ASSERT(ser_curr->ns_conn_q > 0);		
				conn = TAILQ_FIRST(&ser_curr->s_conn_q);
				conn->err = ERROR_REPLACE_SERVER_TRY_AGAIN;
				status = event_del_conn(ctx->evb, conn);
				if (status < 0) {
					log_warn("event del conn s %d failed, ignored: %s",
				         conn->sd, strerror(errno));
				}

				conn->close(ctx, conn);
			}
			
			log_debug(LOG_DEBUG, "ser_curr->pname : %.*s", ser_curr->pname.len, ser_curr->pname.data);
			log_debug(LOG_DEBUG, "ser_new->pname : %.*s", ser_new->pname.len, ser_new->pname.data);
			status = conf_write_back_yaml(ctx, &ser_curr->pname, &ser_new->pname);
			if(status != NC_OK)
			{
				log_warn("warning: conf file write back error, but replace_server %.*s %.*s success.", 
					ser_curr->pname.len, ser_curr->pname.data,
					ser_new->pname.len, ser_new->pname.data);
			}
			
			string_deinit(&cs->pname);
			cs->pname = ser_new->pname;
			string_init(&ser_new->pname);
			ser_curr->pname = cs->pname;
			
			if(ser_curr->name_null)
			{
				string_deinit(&cs->name);
				cs->name = ser_new->name;
				string_init(&ser_new->name);
				ser_curr->name = cs->name;

				stp = array_get(&ctx->stats->current, p_idx);
				sts = array_get(&stp->server, s_idx);
				sts->name = ser_curr->name;

				stp = array_get(&ctx->stats->shadow, p_idx);
				sts = array_get(&stp->server, s_idx);
				sts->name = ser_curr->name;

				stp = array_get(&ctx->stats->sum, p_idx);
				sts = array_get(&stp->server, s_idx);
				sts->name = ser_curr->name;
			}
			
			ser_curr->port = ser_new->port;			
			
			ser_curr->family = cs->info.family;
		    ser_curr->addrlen = cs->info.addrlen;
		    ser_curr->addr = (struct sockaddr *)&cs->info.addr;
			
			ser_curr->next_retry = 0;
			ser_curr->failure_count = 0;
			
			string_deinit(&host);

			while (!TAILQ_EMPTY(&ser_new->s_conn_q)) {
				struct conn *conn;

				ASSERT(ser_new->ns_conn_q > 0);		
				conn = TAILQ_FIRST(&ser_new->s_conn_q);

				ASSERT(conn->replace_server == 1);
				conn->replace_server = 0;
				conn->conf_version_curr = -1;
				conn->ctx = NULL;
				
				conn->unref(conn);
				conn->ref(conn, ser_curr);
			}
		}
		
		
	}
#endif //shenzheng 2015-6-25 replace server

    msg->pre_coalesce(msg);

    c_conn = pmsg->owner;
    ASSERT(c_conn->client && !c_conn->proxy);

    if (req_done(c_conn, TAILQ_FIRST(&c_conn->omsg_q))) {
        status = event_add_out(ctx->evb, c_conn);
        if (status != NC_OK) {
            c_conn->err = errno;
        }
    }

    rsp_forward_stats(ctx, s_conn->owner, msg);
}