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 = dn_msec_now(); if (now < then) { int delta = (int)(then - now); ctx->timeout = MIN(delta, ctx->max_timeout); return; } log_warn("req %"PRIu64" on %s %d timedout, timeout was %d", msg->id, conn_get_type_string(conn), conn->sd, msg->tmo_rbe.timeout); msg_tmo_delete(msg); if (conn->dyn_mode) { if (conn->type == CONN_DNODE_PEER_SERVER) { //outgoing peer requests struct server *server = conn->owner; if (conn->same_dc) stats_pool_incr(ctx, server->owner, peer_timedout_requests); else stats_pool_incr(ctx, server->owner, remote_peer_timedout_requests); } } else { if (conn->type == CONN_SERVER) { //storage server requests stats_server_incr(ctx, conn->owner, server_dropped_requests); } } conn->err = ETIMEDOUT; core_close(ctx, conn); } }
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 = dn_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); if (conn->dyn_mode) return; //don't close dyn connection in this case conn->err = ETIMEDOUT; core_close(ctx, conn); } }
void req_server_dequeue_omsgq(struct context *ctx, struct conn *conn, struct msg *msg) { ASSERT(msg->request); ASSERT(!conn->client && !conn->proxy); msg_tmo_delete(msg); TAILQ_REMOVE(&conn->omsg_q, msg, s_tqe); stats_server_decr(ctx, conn->owner, out_queue); stats_server_decr_by(ctx, conn->owner, out_queue_bytes, msg->mlen); }
void dnode_req_peer_dequeue_omsgq(struct context *ctx, struct conn *conn, struct msg *msg) { ASSERT(msg->request); ASSERT(conn->type == CONN_DNODE_PEER_SERVER); msg_tmo_delete(msg); TAILQ_REMOVE(&conn->omsg_q, msg, s_tqe); log_debug(LOG_VVERB, "conn %p dequeue outq %p", conn, msg); //use the 1st pool struct server_pool *pool = (struct server_pool *) array_get(&ctx->pool, 0); stats_pool_decr(ctx, pool, peer_out_queue); stats_pool_decr_by(ctx, pool, peer_out_queue_bytes, msg->mlen); }
void dnode_req_peer_dequeue_omsgq(struct context *ctx, struct conn *conn, struct msg *msg) { ASSERT(msg->request); ASSERT(!conn->dnode_client && !conn->dnode_server); msg_tmo_delete(msg); TAILQ_REMOVE(&conn->omsg_q, msg, s_tqe); /* stats_server_decr(ctx, conn->owner, out_queue); */ /* stats_server_decr_by(ctx, conn->owner, out_queue_bytes, msg->mlen); */ //use the 1st pool struct server_pool *pool = (struct server_pool *) array_get(&ctx->pool, 0); stats_pool_decr(ctx, pool, peer_out_queue); stats_pool_decr_by(ctx, pool, peer_out_queue_bytes, msg->mlen); }
void req_put(struct msg *msg) { struct msg *pmsg; /* peer message (response) */ ASSERT(msg->request); pmsg = msg->peer; if (pmsg != NULL) { ASSERT(!pmsg->request && pmsg->peer == msg); msg->peer = NULL; pmsg->peer = NULL; rsp_put(pmsg); } msg_tmo_delete(msg); msg_put(msg); }
void server_close(struct context *ctx, struct conn *conn) { rstatus_t status; struct msg *msg, *nmsg; /* current and next message */ ASSERT(conn->type == CONN_SERVER); server_close_stats(ctx, conn->owner, conn->err, conn->eof, conn->connected); if (conn->sd < 0) { server_failure(ctx, conn->owner); conn_unref(conn); conn_put(conn); return; } for (msg = TAILQ_FIRST(&conn->omsg_q); msg != NULL; msg = nmsg) { nmsg = TAILQ_NEXT(msg, s_tqe); /* dequeue the message (request) from server outq */ conn_dequeue_outq(ctx, conn, msg); server_ack_err(ctx, conn, msg); } ASSERT(TAILQ_EMPTY(&conn->omsg_q)); for (msg = TAILQ_FIRST(&conn->imsg_q); msg != NULL; msg = nmsg) { nmsg = TAILQ_NEXT(msg, s_tqe); /* dequeue the message (request) from server inq */ conn_dequeue_inq(ctx, conn, msg); // We should also remove the msg from the timeout rbtree. msg_tmo_delete(msg); server_ack_err(ctx, conn, msg); stats_server_incr(ctx, conn->owner, server_dropped_requests); } ASSERT(TAILQ_EMPTY(&conn->imsg_q)); msg = conn->rmsg; if (msg != NULL) { conn->rmsg = NULL; ASSERT(!msg->request); ASSERT(msg->peer == NULL); rsp_put(msg); log_debug(LOG_INFO, "close s %d discarding rsp %"PRIu64" len %"PRIu32" " "in error", conn->sd, msg->id, msg->mlen); } ASSERT(conn->smsg == NULL); server_failure(ctx, conn->owner); conn_unref(conn); status = close(conn->sd); if (status < 0) { log_error("close s %d failed, ignored: %s", conn->sd, strerror(errno)); } conn->sd = -1; conn_put(conn); }