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); }
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); }
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); } } }
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); }