コード例 #1
0
ファイル: dyn_dnode_request.c プロジェクト: amit-git/dynomite
static void
dnode_req_local_forward(struct context *ctx, struct conn *conn, struct msg *msg)
{
	struct server_pool *pool;
	uint8_t *key;
	uint32_t keylen;
	log_debug(LOG_VERB, "dnode_req_local_forward entering ");

	ASSERT(conn->dnode_client && !conn->dnode_server);

	pool = conn->owner;
	key = NULL;
	keylen = 0;

	if (!string_empty(&pool->hash_tag)) {
		struct string *tag = &pool->hash_tag;
		uint8_t *tag_start, *tag_end;

		tag_start = dn_strchr(msg->key_start, msg->key_end, tag->data[0]);
		if (tag_start != NULL) {
			tag_end = dn_strchr(tag_start + 1, msg->key_end, tag->data[1]);
			if (tag_end != NULL) {
				key = tag_start + 1;
				keylen = (uint32_t)(tag_end - key);
			}
		}
	}

	if (keylen == 0) {
		key = msg->key_start;
		keylen = (uint32_t)(msg->key_end - msg->key_start);
	}

	local_req_forward(ctx, conn, msg, key, keylen);
}
コード例 #2
0
ファイル: dyn_client.c プロジェクト: Netflix/dynomite
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
ファイル: dyn_request.c プロジェクト: chrholme/dynomite
void 
remote_req_forward(struct context *ctx, struct conn *c_conn, struct msg *msg, 
                        struct rack *rack, uint8_t *key, uint32_t keylen)
{
    struct conn *p_conn;

    ASSERT(c_conn->client || c_conn->dnode_client);

    p_conn = dnode_peer_pool_conn(ctx, c_conn->owner, rack, key, keylen, msg->msg_type);
    if (p_conn == NULL) {
        req_forward_error(ctx, c_conn, msg);
        return;
    }

    //jeb - check if s_conn is _this_ node, and if so, get conn from server_pool_conn instead
    struct server *peer = p_conn->owner;

    if (peer->is_local) {
        local_req_forward(ctx, c_conn, msg, key, keylen);
        return;
    } else {
        dnode_peer_req_forward(ctx, c_conn, p_conn, msg, rack, key, keylen);
    }
}
コード例 #4
0
static void
dnode_req_forward(struct context *ctx, struct conn *conn, struct msg *msg)
{
    struct server_pool *pool;
    uint8_t *key;
    uint32_t keylen;

    if (log_loggable(LOG_DEBUG)) {
       log_debug(LOG_DEBUG, "dnode_req_forward entering ");
    }
    log_debug(LOG_DEBUG, "DNODE REQ RECEIVED %s %d dmsg->id %u",
              conn_get_type_string(conn), conn->sd, msg->dmsg->id);

    ASSERT(conn->type == CONN_DNODE_PEER_CLIENT);

    pool = conn->owner;
    key = NULL;
    keylen = 0;

    log_debug(LOG_DEBUG, "conn %p adding message %d:%d", conn, msg->id, msg->parent_id);
    dictAdd(conn->outstanding_msgs_dict, &msg->id, msg);

    if (!string_empty(&pool->hash_tag)) {
        struct string *tag = &pool->hash_tag;
        uint8_t *tag_start, *tag_end;

        tag_start = dn_strchr(msg->key_start, msg->key_end, tag->data[0]);
        if (tag_start != NULL) {
            tag_end = dn_strchr(tag_start + 1, msg->key_end, tag->data[1]);
            if (tag_end != NULL) {
                key = tag_start + 1;
                keylen = (uint32_t)(tag_end - key);
            }
        }
    }

    if (keylen == 0) {
        key = msg->key_start;
        keylen = (uint32_t)(msg->key_end - msg->key_start);
    }

    ASSERT(msg->dmsg != NULL);
    if (msg->dmsg->type == DMSG_REQ) {
       local_req_forward(ctx, conn, msg, key, keylen);
    } else if (msg->dmsg->type == DMSG_REQ_FORWARD) {
        struct mbuf *orig_mbuf = STAILQ_FIRST(&msg->mhdr);
        struct datacenter *dc = server_get_dc(pool, &pool->dc);
        uint32_t rack_cnt = array_n(&dc->racks);
        uint32_t rack_index;
        for(rack_index = 0; rack_index < rack_cnt; rack_index++) {
            struct rack *rack = array_get(&dc->racks, rack_index);
            //log_debug(LOG_DEBUG, "forwarding to rack  '%.*s'",
            //            rack->name->len, rack->name->data);
            struct msg *rack_msg;
            if (string_compare(rack->name, &pool->rack) == 0 ) {
                rack_msg = msg;
            } else {
                rack_msg = msg_get(conn, msg->request, __FUNCTION__);
                if (rack_msg == NULL) {
                    log_debug(LOG_VERB, "whelp, looks like yer screwed now, buddy. no inter-rack messages for you!");
                    continue;
                }

                if (msg_clone(msg, orig_mbuf, rack_msg) != DN_OK) {
                    msg_put(rack_msg);
                    continue;
                }
                rack_msg->swallow = true;
            }

            if (log_loggable(LOG_DEBUG)) {
               log_debug(LOG_DEBUG, "forwarding request from conn '%s' to rack '%.*s' dc '%.*s' ",
                           dn_unresolve_peer_desc(conn->sd), rack->name->len, rack->name->data, rack->dc->len, rack->dc->data);
            }

            remote_req_forward(ctx, conn, rack_msg, rack, key, keylen);
        }
    }
}
コード例 #5
0
ファイル: dyn_client.c プロジェクト: Netflix/dynomite
static void
req_forward(struct context *ctx, struct conn *c_conn, struct msg *msg)
{
    struct server_pool *pool = c_conn->owner;
    uint8_t *key;
    uint32_t keylen;

    ASSERT(c_conn->type == CONN_CLIENT);

    if (msg->is_read) {
        if (msg->type != MSG_REQ_REDIS_PING)
            stats_pool_incr(ctx, client_read_requests);
    } else
        stats_pool_incr(ctx, client_write_requests);

    key = NULL;
    keylen = 0;

    // add the message to the dict
    log_debug(LOG_DEBUG, "conn %p adding message %d:%d", c_conn, msg->id, msg->parent_id);
    dictAdd(c_conn->outstanding_msgs_dict, &msg->id, msg);

    if (!string_empty(&pool->hash_tag)) {
        struct string *tag = &pool->hash_tag;
        uint8_t *tag_start, *tag_end;

        tag_start = dn_strchr(msg->key_start, msg->key_end, tag->data[0]);
        if (tag_start != NULL) {
            tag_end = dn_strchr(tag_start + 1, msg->key_end, tag->data[1]);
            if (tag_end != NULL) {
                key = tag_start + 1;
                keylen = (uint32_t)(tag_end - key);
            }
        }
    }

    if (keylen == 0) {
        key = msg->key_start;
        keylen = (uint32_t)(msg->key_end - msg->key_start);
    }

    // need to capture the initial mbuf location as once we add in the dynomite
    // headers (as mbufs to the src msg), that will bork the request sent to
    // secondary racks
    struct mbuf *orig_mbuf = STAILQ_FIRST(&msg->mhdr);

    if (ctx->admin_opt == 1) {
        if (msg->type == MSG_REQ_REDIS_DEL || msg->type == MSG_REQ_MC_DELETE) {
          struct rack * rack = server_get_rack_by_dc_rack(pool, &pool->rack, &pool->dc);
          admin_local_req_forward(ctx, c_conn, msg, rack, key, keylen);
          return;
        }
    }

    if (msg->msg_routing == ROUTING_LOCAL_NODE_ONLY) {
        // Strictly local host only
        msg->consistency = DC_ONE;
        msg->rsp_handler = msg_local_one_rsp_handler;
        local_req_forward(ctx, c_conn, msg, key, keylen);
        return;
    }

    if (msg->is_read) {
        msg->consistency = conn_get_read_consistency(c_conn);
    } else {
        msg->consistency = conn_get_write_consistency(c_conn);
    }

    /* forward the request */
    uint32_t dc_cnt = array_n(&pool->datacenters);
    uint32_t dc_index;

    for(dc_index = 0; dc_index < dc_cnt; dc_index++) {

        struct datacenter *dc = array_get(&pool->datacenters, dc_index);
        if (dc == NULL) {
            log_error("Wow, this is very bad, dc is NULL");
            return;
        }

        if (string_compare(dc->name, &pool->dc) == 0)
            req_forward_local_dc(ctx, c_conn, msg, orig_mbuf, key, keylen, dc);
        else if (request_send_to_all_dcs(msg)) {
            req_forward_remote_dc(ctx, c_conn, msg, orig_mbuf, key, keylen, dc);
        }
    }
}
コード例 #6
0
ファイル: dyn_client.c プロジェクト: Netflix/dynomite
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);
}