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;
}
示例#2
0
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);
}
示例#3
0
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);
}