struct conn * dnode_peer_pool_conn(struct context *ctx, struct server_pool *pool, struct rack *rack, uint8_t *key, uint32_t keylen, uint8_t msg_type) { rstatus_t status; struct server *server; struct conn *conn; //status = dnode_peer_pool_update(pool); status = dnode_peer_pool_run(pool); if (status != DN_OK) { return NULL; } if (msg_type == 1) { //always local server = array_get(&pool->peers, 0); } else { /* from a given {key, keylen} pick a server from pool */ server = dnode_peer_pool_server(pool, rack, key, keylen); if (server == NULL) { return NULL; } } /* pick a connection to a given server */ conn = dnode_peer_conn(server); if (conn == NULL) { return NULL; } if (server->is_local) return conn; //Don't bother to connect status = dnode_peer_connect(ctx, server, conn); if (status != DN_OK) { dnode_peer_close(ctx, conn); return NULL; } return conn; }
static void admin_local_req_forward(struct context *ctx, struct conn *c_conn, struct msg *msg, struct rack *rack, uint8_t *key, uint32_t keylen) { ASSERT((c_conn->type == CONN_CLIENT) || (c_conn->type == CONN_DNODE_PEER_CLIENT)); struct node *peer = dnode_peer_pool_server(ctx, c_conn->owner, rack, key, keylen, msg->msg_routing); if (!peer->is_local) { send_rsp_integer(ctx, c_conn, msg); return; } struct conn *p_conn = dnode_peer_pool_server_conn(ctx, peer); if (p_conn == NULL) { c_conn->err = EHOSTDOWN; req_forward_error(ctx, c_conn, msg, c_conn->err); return; } log_debug(LOG_NOTICE, "Need to delete [%.*s] ", keylen, key); local_req_forward(ctx, c_conn, msg, key, keylen); }
void remote_req_forward(struct context *ctx, struct conn *c_conn, struct msg *msg, struct rack *rack, uint8_t *key, uint32_t keylen) { ASSERT((c_conn->type == CONN_CLIENT) || (c_conn->type == CONN_DNODE_PEER_CLIENT)); struct node * peer = dnode_peer_pool_server(ctx, c_conn->owner, rack, key, keylen, msg->msg_routing); if (peer->is_local) { log_debug(LOG_VERB, "c_conn: %p forwarding %d:%d is local", c_conn, msg->id, msg->parent_id); local_req_forward(ctx, c_conn, msg, key, keylen); return; } /* enqueue message (request) into client outq, if response is expected */ if (msg->expect_datastore_reply && !msg->swallow) { conn_enqueue_outq(ctx, c_conn, msg); } // now get a peer connection struct conn *p_conn = dnode_peer_pool_server_conn(ctx, peer); if ((p_conn == NULL) || (p_conn->connecting)) { if (p_conn) { usec_t now = dn_usec_now(); static usec_t next_log = 0; // Log every 1 sec if (now > next_log) { log_warn("still connecting to peer '%.*s'......", peer->endpoint.pname.len, peer->endpoint.pname.data); next_log = now + 1000 * 1000; } } // No response for DC_ONE & swallow if ((msg->consistency == DC_ONE) && (msg->swallow)) { msg_put(msg); return; } // No response for remote dc struct server_pool *pool = c_conn->owner; bool same_dc = is_same_dc(pool, peer)? 1 : 0; if (!same_dc) { msg_put(msg); return; } // All other cases return a response struct msg *rsp = msg_get(c_conn, false, __FUNCTION__); msg->done = 1; rsp->error = msg->error = 1; rsp->err = msg->err = (p_conn ? PEER_HOST_NOT_CONNECTED : PEER_HOST_DOWN); rsp->dyn_error = msg->dyn_error = (p_conn ? PEER_HOST_NOT_CONNECTED: PEER_HOST_DOWN); rsp->dmsg = dmsg_get(); rsp->peer = msg; rsp->dmsg->id = msg->id; log_info("%lu:%lu <-> %lu:%lu Short circuit....", msg->id, msg->parent_id, rsp->id, rsp->parent_id); conn_handle_response(c_conn, msg->parent_id ? msg->parent_id : msg->id, rsp); if (msg->swallow) msg_put(msg); return; } log_debug(LOG_VERB, "c_conn: %p forwarding %d:%d to p_conn %p", c_conn, msg->id, msg->parent_id, p_conn); dnode_peer_req_forward(ctx, c_conn, p_conn, msg, rack, key, keylen); }