static void dnode_req_forward_error(struct context *ctx, struct conn *conn, struct msg *msg) { rstatus_t status; ASSERT(conn->dnode_client && !conn->dnode_server); log_debug(LOG_INFO, "dyn: forward req %"PRIu64" len %"PRIu32" type %d from " "c %d failed: %s", msg->id, msg->mlen, msg->type, conn->sd, strerror(errno)); msg->done = 1; msg->error = 1; msg->err = errno; /* noreply request don't expect any response */ if (msg->noreply) { dnode_req_put(msg); return; } if (dnode_req_done(conn, TAILQ_FIRST(&conn->omsg_q))) { status = event_add_out(ctx->evb, conn); if (status != DN_OK) { conn->err = errno; } } }
/* Description: link data from a peer connection to a client-facing connection * peer_conn: a peer connection * msg : msg with data from the peer connection after parsing */ static void dnode_rsp_forward(struct context *ctx, struct conn *peer_conn, struct msg *msg) { rstatus_t status; struct msg *pmsg; struct conn *c_conn; log_debug(LOG_VERB, "dnode_rsp_forward entering ..."); ASSERT(!peer_conn->dnode_client && !peer_conn->dnode_server); /* response from a peer implies that peer is ok and heartbeating */ dnode_peer_ok(ctx, peer_conn); /* dequeue peer message (request) from peer conn */ pmsg = TAILQ_FIRST(&peer_conn->omsg_q); ASSERT(pmsg != NULL && pmsg->peer == NULL); ASSERT(pmsg->request && !pmsg->done); if (TRACING_LEVEL >= LOG_VVERB) { loga("Dumping content for msg: "); msg_dump(msg); loga("msg id %d", msg->id); loga("Dumping content for pmsg :"); msg_dump(pmsg); loga("pmsg id %d", pmsg->id); } peer_conn->dequeue_outq(ctx, peer_conn, pmsg); pmsg->done = 1; /* establish msg <-> pmsg (response <-> request) link */ pmsg->peer = msg; msg->peer = pmsg; msg->pre_coalesce(msg); c_conn = pmsg->owner; ASSERT(c_conn->client && !c_conn->proxy); if (TAILQ_FIRST(&c_conn->omsg_q) != NULL && dnode_req_done(c_conn, TAILQ_FIRST(&c_conn->omsg_q))) { status = event_add_out(ctx->evb, c_conn); if (status != DN_OK) { c_conn->err = errno; } } dnode_rsp_forward_stats(ctx, peer_conn->owner, msg); }
bool dnode_req_error(struct conn *conn, struct msg *msg) { ASSERT(msg->request && dnode_req_done(conn, msg)); return req_error(conn, msg); }
/* Description: link data from a peer connection to a client-facing connection * peer_conn: a peer connection * msg : msg with data from the peer connection after parsing */ static void dnode_rsp_forward_match(struct context *ctx, struct conn *peer_conn, struct msg *rsp) { rstatus_t status; struct msg *req; struct conn *c_conn; req = TAILQ_FIRST(&peer_conn->omsg_q); c_conn = req->owner; /* if client consistency is dc_one forward the response from only the local node. Since dyn_dnode_peer is always a remote node, drop the rsp */ if (req->consistency == DC_ONE) { if (req->swallow) { dnode_rsp_swallow(ctx, peer_conn, req, rsp); return; } log_warn("req %d:%d with DC_ONE consistency is not being swallowed"); } /* if client consistency is dc_quorum, forward the response from only the local region/DC. */ if ((req->consistency == DC_QUORUM) && !peer_conn->same_dc) { if (req->swallow) { dnode_rsp_swallow(ctx, peer_conn, req, rsp); return; } log_warn("req %d:%d with DC_QUORUM consistency is not being swallowed"); } log_debug(LOG_DEBUG, "DNODE RSP RECEIVED %c %d dmsg->id %u req %u:%u rsp %u:%u, ", peer_conn->dnode_client ? 'c' : (peer_conn->dnode_server ? 's' : 'p'), peer_conn->sd, rsp->dmsg->id, req->id, req->parent_id, rsp->id, rsp->parent_id); ASSERT(req != NULL && req->peer == NULL); ASSERT(req->request && !req->done); if (log_loggable(LOG_VVERB)) { loga("Dumping content for response: "); msg_dump(rsp); loga("rsp id %d", rsp->id); loga("Dumping content for request:"); msg_dump(req); loga("req id %d", req->id); } peer_conn->dequeue_outq(ctx, peer_conn, req); req->done = 1; log_debug(LOG_VERB, "%p <-> %p", req, rsp); /* establish rsp <-> req (response <-> request) link */ req->peer = rsp; rsp->peer = req; rsp->pre_coalesce(rsp); ASSERT((c_conn->client && !c_conn->proxy) || (c_conn->dnode_client && !c_conn->dnode_server)); dnode_rsp_forward_stats(ctx, peer_conn->owner, rsp); if (TAILQ_FIRST(&c_conn->omsg_q) != NULL && dnode_req_done(c_conn, req)) { log_debug(LOG_INFO, "handle rsp %d:%d for req %d:%d conn %p", rsp->id, rsp->parent_id, req->id, req->parent_id, c_conn); // c_conn owns respnse now rstatus_t status = conn_handle_response(c_conn, req->parent_id ? req->parent_id : req->id, rsp); if (req->swallow) { log_debug(LOG_INFO, "swallow request %d:%d", req->id, req->parent_id); req_put(req); } } }