Beispiel #1
0
static rstatus_t
dnode_peer_add_node(struct server_pool *sp, struct node *node)
{
	rstatus_t status;
	struct array *peers = &sp->peers;
	struct server *s = array_push(peers);

	s->owner = sp;

	uint32_t i,nelem;
	s->idx = array_idx(peers, s);

	//log_debug(LOG_VERB, "node rack_name         : '%.*s'", node->rack.len, node->rack.data);
	//log_debug(LOG_VERB, "node dc_name        : '%.*s'", node->dc.len, node->dc.data);
	//log_debug(LOG_VERB, "node address          : '%.*s'", node->pname.len, node->pname.data);
	//log_debug(LOG_VERB, "node ip         : '%.*s'", node->name.len, node->name.data);


	string_copy(&s->pname, node->pname.data, node->pname.len);
	string_copy(&s->name, node->name.data, node->name.len);
	string_copy(&s->rack, node->rack.data, node->rack.len);
	string_copy(&s->dc, node->dc.data, node->dc.len);

	s->port = (uint16_t) node->port;
	s->is_local = node->is_local;
	s->state = node->state;
	s->processed = 0;

	array_init(&s->tokens, 1, sizeof(struct dyn_token));
	struct dyn_token *src_token = &node->token;
	struct dyn_token *dst_token = array_push(&s->tokens);
	copy_dyn_token(src_token, dst_token);

	struct sockinfo  *info =  dn_alloc(sizeof(*info)); //need to free this
	dn_resolve(&s->name, s->port, info);
	s->family = info->family;
	s->addrlen = info->addrlen;
	s->addr = (struct sockaddr *)&info->addr;  //TODOs: fix this by copying, not reference
	s->ns_conn_q = 0;
	TAILQ_INIT(&s->s_conn_q);

	s->next_retry = 0LL;
	s->failure_count = 0;
	s->is_seed = node->is_seed;

	log_debug(LOG_VERB, "add a node to peer %"PRIu32" '%.*s'",
			s->idx, s->pname.len, s->pname.data);

	dnode_peer_relink_conn_owner(sp);

	status = dnode_peer_pool_run(sp);
	if (status != DN_OK)
		return status;

	status = dnode_peer_each_preconnect(s, NULL);

	return status;
}
rstatus_t
dnode_peer_replace(void *rmsg)
{
	//rstatus_t status;
	struct ring_msg *msg = rmsg;
	struct server_pool *sp = msg->sp;
	struct node *node = array_get(&msg->nodes, 0);
	log_debug(LOG_VVERB, "dyn: peer has a replaced message '%.*s'", node->name.len, node->name.data);
	struct array *peers = &sp->peers;
	struct server *s = NULL;

	uint32_t i,nelem;
	//bool node_exist = false;
	//TODOs: use hash table here
	for (i=1, nelem = array_n(peers); i< nelem; i++) {
		struct server * peer = (struct server *) array_get(peers, i);
		if (string_compare(&peer->rack, &node->rack) == 0) {
			//TODOs: now only compare 1st token and support vnode later - use hash string on a tokens for comparison
			struct dyn_token *ptoken = (struct dyn_token *) array_get(&peer->tokens, 0);
			struct dyn_token *ntoken = &node->token;

			if (cmp_dyn_token(ptoken, ntoken) == 0) {
				s = peer; //found a node to replace
			}
		}
	}


	if (s != NULL) {
		log_debug(LOG_INFO, "Found an old node to replace '%.*s'", s->name.len, s->name.data);
		log_debug(LOG_INFO, "Replace with address '%.*s'", node->name.len, node->name.data);

		string_deinit(&s->pname);
		string_deinit(&s->name);
		string_copy(&s->pname, node->pname.data, node->pname.len);
		string_copy(&s->name, node->name.data, node->name.len);

		//TODOs: need to free the previous s->addr?
		//if (s->addr != NULL) {
		//   dn_free(s->addr);
		//}

		struct sockinfo  *info =  dn_alloc(sizeof(*info)); //need to free this
		dn_resolve(&s->name, s->port, info);
		s->family = info->family;
		s->addrlen = info->addrlen;
		s->addr = (struct sockaddr *)&info->addr;  //TODOs: fix this by copying, not reference


		dnode_peer_each_disconnect(s, NULL);
		dnode_peer_each_preconnect(s, NULL);
	} else {
		log_debug(LOG_INFO, "Unable to find any node matched the token");
	}

	return DN_OK;
}
Beispiel #3
0
static rstatus_t
stats_listen(struct stats *st)
{
    rstatus_t status;
    struct sockinfo si;

    status = dn_resolve(&st->addr, st->port, &si);
    if (status < 0) {
        return status;
    }

    st->sd = socket(si.family, SOCK_STREAM, 0);
    if (st->sd < 0) {
        log_error("socket failed: %s", strerror(errno));
        return DN_ERROR;
    }

    status = dn_set_reuseaddr(st->sd);
    if (status < 0) {
        log_error("set reuseaddr on m %d failed: %s", st->sd, strerror(errno));
        return DN_ERROR;
    }

    status = bind(st->sd, (struct sockaddr *)&si.addr, si.addrlen);
    if (status < 0) {
        log_error("bind on m %d to addr '%.*s:%u' failed: %s", st->sd,
                  st->addr.len, st->addr.data, st->port, strerror(errno));
        return DN_ERROR;
    }

    status = listen(st->sd, SOMAXCONN);
    if (status < 0) {
        log_error("listen on m %d failed: %s", st->sd, strerror(errno));
        return DN_ERROR;
    }

    log_debug(LOG_NOTICE, "m %d listening on '%.*s:%u'", st->sd,
              st->addr.len, st->addr.data, st->port);

    return DN_OK;
}