Exemple #1
0
int leader_handle_remove_neighbour(gossip_node_t* neighbour) {
    if (neighbour->id == leader) {
        // Leader was removed from neighbour table; start a new election
        // round
        election_round++;
        // This obviously won't work as intended as of now;
        // leader_elect() needs to be a thread. But this is the general
        // idea.
        leader_init();
    }
    return 1;
}
Exemple #2
0
//This function is invoked when a new message is ready to be read
// from the leader election oracle UDP socket
static void 
pro_handle_oracle_msg(int sock, short event, void *arg) {
    //Make the compiler happy!
    UNUSED_ARG(sock);
    UNUSED_ARG(event);
    UNUSED_ARG(arg);
    
    assert(sock == from_oracle->sock);
    
    //Read the next message
    int valid = udp_read_next_message(from_oracle);
    if (valid < 0) {
        printf("Dropping invalid oracle message\n");
        return;
    }

    //The message is valid, take the appropriate action
    // based on the type
    paxos_msg * msg = (paxos_msg*) &from_oracle->recv_buffer;
    switch(msg->type) {
        case leader_announce: {
            leader_announce_msg * la = (leader_announce_msg *)msg->data;
            if(LEADER_IS_ME && la->current_leader != this_proposer_id) {
            //Some other proposer was nominated leader instead of this one, 
            // step down from leadership
                leader_shutdown();
            } else if (!LEADER_IS_ME 
                && la->current_leader == this_proposer_id) {
            //This proposer has just been promoted to leader
                leader_init();
            }
            current_leader_id = la->current_leader;
        }
        break;

        default: {
            printf("Unknow msg type %d received from oracle\n", msg->type);
        }
    }
}
Exemple #3
0
//Proposer initialization, this function is invoked by
// the underlying learner after it's normal initialization
static int init_proposer() {
    
    //Add network events and prepare send buffer
    if(init_pro_network() != 0) {
        printf("Proposer network init failed\n");
        return -1;
    }

    //Add additional timers to libevent loop
    if(init_pro_fd_events() != 0){
        printf("Proposer timers init failed\n");
        return -1;
    }
    
    //Normal proposer initialization, private structures
    if(init_pro_structs() != 0) {
        printf("Proposer structs init failed\n");
        return -1;
    }
        
    //By default, proposer 0 starts as leader, 
    // later on the failure detector may change that
    if(LEADER_IS_ME) {
        if(leader_init() != 0) {
            printf("Proposer Leader init failed\n");
            return -1;
        }
    }
    
    //Call custom init (i.e. to register additional events)
    if(client_custom_init != NULL && client_custom_init() != 0) {
        printf("Error in client_custom_init\n");
        return -1;
    } else {
        LOG(DBG, ("Custom init completed\n"));
    }

    return 0;
}
Exemple #4
0
/*
 * Place a swarm at start with a number of leaders that all have 
 * the same initial velocity. 
 */
Swarm *swarm_create(Point *start, Vector *initVel, Module *shape, 
					int numLeaders, int numActorsPerLeader, float spread){
	int i, j, id = 0, verbose = 1;
 	float genX, genY, genZ;

	if(verbose) printf("creating swarm\n");

	Swarm *s = malloc(sizeof(Swarm));
	s->leaders = malloc(sizeof(Leader)*numLeaders);
	s->actors = malloc(sizeof(Actor)*numActorsPerLeader*numLeaders);
	s->numActors = numActorsPerLeader*numLeaders;
	s->numLeaders = numLeaders;
	for(i=0; i<numLeaders; i++){
		genX = spread - ((double)rand() / RAND_MAX) * 2.0 * spread;
		genY = spread - ((double)rand() / RAND_MAX) * 2.0 * spread;
		genZ = spread - ((double)rand() / RAND_MAX) * 2.0 * spread;
		leader_init(&(s->leaders[i]), shape);
		leader_setLocation(&(s->leaders[i]), 
							start->val[0] + genX, 
							start->val[1] + genY, 
						   	start->val[2] + genZ);
		leader_setVelocity(&(s->leaders[i]), initVel);
		for(j=0; j<numActorsPerLeader; j++){
			genX = spread - ((double)rand() / RAND_MAX) * 2.0 * spread;
			genY = spread - ((double)rand() / RAND_MAX) * 2.0 * spread;
			genZ = spread - ((double)rand() / RAND_MAX) * 2.0 * spread;
			actor_init(&(s->actors[j+(i*numActorsPerLeader)]), &(s->leaders[i]), shape);
			actor_setLocation(&(s->actors[j+(i*numActorsPerLeader)]), 
								start->val[0] + genX, 
								start->val[1] + genY, 
				 				start->val[2] + genZ);
			actor_setID(&(s->actors[j+(i*numActorsPerLeader)]), id++);
		}
	}
	return s;
}
Exemple #5
0
void leader_handle_msg(void* msg_text, size_t size, uint16_t src){
    uint16_t received_leader;
    uint16_t round;
    gossip_node_t* node;
    char round_buffer[3];
    int len = strlen(PREAMBLE) + strlen(MSG) + strlen(LE) + size;
    char* msg_buffer;

    msg_buffer = malloc(len);
    memset(msg_buffer, 0, len);
    DEBUG("D: received msg of size %d\n",size);

    /* we received something, that means LE started */
    leader_set_initialized(1);

    strncpy( round_buffer, (char*)msg_text+strlen(LE) , sizeof(round_buffer) );
    round = atol(round_buffer);

    DEBUG("D: got round %i (current round %i)\n",round,election_round);

    // a new election round, invalidate leader and elect the next one
    if(round > election_round) { // TODO: fix possible overflow
        DEBUG("D: got new election round %i (was %i)\n",round,election_round);
        election_round = round;
        leader_init();
        free(msg_buffer);
        return;
    }

    // got leader from an old round, inform sending node
    if(round < election_round) { // TODO: fix possible overflow
        DEBUG("D: got round %i (current is %i) informing sender\n",round,election_round);
        sprintf(msg_buffer, "%s%s%s%0" ROUND_LEN_STR "i%0" UID_LEN_STR "i",
                    PREAMBLE, MSG, LE, election_round, leader);
        node = gossip_find_node_by_id(src);
        gossip_send(node, msg_buffer, strlen(msg_buffer));
        free(msg_buffer);
        return;
    }

    received_leader = atol((char*)msg_text+strlen(LE)+UID_LEN);
    DEBUG("D: received candidate: %i\n",received_leader);

    /* XXX: misuse MAX_UID as ACK identifier */
    if(received_leader == MAX_UID){
        free(msg_buffer);
        return;
    }

    // TODO: add custom metrics functions here instead of a<b
    if(received_leader < leader ){
        DEBUG("D: discarding candidate and informing sender\n");
        sprintf(msg_buffer, "%s%s%s%0" ROUND_LEN_STR "i%0" UID_LEN_STR "i",
                    PREAMBLE, MSG, LE, round, leader);
    }

    // update leader if we receive a better candidate
    if(received_leader >= leader ){
        DEBUG("D: adding a new, better leader\n");
        leader_set_leader(received_leader);
        sprintf(msg_buffer, "%s%s%s%0" ROUND_LEN_STR "i%0" UID_LEN_STR "i",
                    PREAMBLE, MSG, LE, round, MAX_UID);
    }

    node = gossip_find_node_by_id(src);
    DEBUG("D: sending msg of size %d\n",strlen(msg_buffer));
    gossip_send(node, msg_buffer, strlen(msg_buffer));
    free(msg_buffer);

}