//Opens instances at the "end" of the proposer state array 
//Those instances were not opened before
static void
leader_open_instances_p1() {
    int active_count = p1_info.pending_count + p1_info.ready_count;
    
    assert(active_count >= 0);
    
    if(inf_prepare_info.status == empty) {
		//Ask for infinite p1 instances
		//Create an empty prepare batch in send buffer
		sendbuf_clear(to_acceptors, prepare_reqs, this_proposer_id);

		//Send prepare to acceptors
		sendbuf_add_prepare_req(to_acceptors, INF_PREPARE_REQ, FIRST_BALLOT);

		//Send if something is still there
		sendbuf_flush(to_acceptors);

		//Keep track of pending count
		inf_prepare_info.status = p1_pending;
		inf_prepare_info.my_ballot = FIRST_BALLOT;

		LOG(DBG, ("Opened %d new instances\n", 1));

		return;
    }

    
}
Beispiel #2
0
/*发送prepare_req到所有的acceptor进行第一阶段的提议*/
static void send_prepares(struct evproposer* p, prepare_req* pr)
{
	int i;
	for(i = 0; i < peers_count(p->acceptors); i ++){
		struct bufferevent* bev = peers_get_buffer(p->acceptors, i);
		sendbuf_add_prepare_req(bev, pr);
	}
}
static void
leader_check_p1_pending() {
    iid_t iid_iterator;
    p_inst_info * ii;

    //Create an empty prepare batch in send buffer
    sendbuf_clear(to_acceptors, prepare_reqs, this_proposer_id);
    LOG(DBG, ("Checking pending phase 1 from %lu to %lu\n",
        current_iid, p1_info.highest_open));
    
    //Get current time for checking expired    
    struct timeval time_now;
    gettimeofday(&time_now, NULL);
    
    for(iid_iterator = current_iid; 
        iid_iterator <= p1_info.highest_open; iid_iterator++) {

        //Get instance from state array
        ii = GET_PRO_INSTANCE(iid_iterator);
        assert(ii->iid == iid_iterator);
        
        //Still pending -> it's expired
        if(ii->status == p1_pending && leader_is_expired(&ii->timeout, &time_now)) {
            LOG(DBG, ("Phase 1 of instance %ld expired!\n", ii->iid));

            //Reset fields used for previous phase 1
            ii->promises_bitvector = 0;
            ii->promises_count = 0;
            ii->p1_value_ballot = 0;
            if(ii->p1_value != NULL) {
                PAX_FREE(ii->p1_value);
            }
            ii->p1_value = NULL;
            
            //Ballot is incremented
            ii->my_ballot = NEXT_BALLOT(ii->my_ballot);


            //Send prepare to acceptors
            sendbuf_add_prepare_req(to_acceptors, ii->iid, ii->my_ballot);        
            leader_set_expiration(ii, P1_TIMEOUT_INTERVAL);
            
            COUNT_EVENT(p1_timeout);
        }
    }    

    //Send if something is still there
    sendbuf_flush(to_acceptors);
}
static void
leader_periodic_p2_check(int fd, short event, void *arg) {
    UNUSED_ARG(fd);
    UNUSED_ARG(event);
    UNUSED_ARG(arg);
    
    // create a prepare batch for expired instances
    sendbuf_clear(to_acceptors, prepare_reqs, this_proposer_id);

    struct timeval now;
    gettimeofday(&now, NULL);
    // from current to highest open, check deadline
    // if instances in status p2_pending
    iid_t i;
    p_inst_info * ii;
    for(i = current_iid; i < p2_info.next_unused_iid; i++) {
        ii = GET_PRO_INSTANCE(i);

        //Not p2_pending, skip
        if(ii->status != p2_pending) {
            continue;
        }

        //Check if it was closed in the meanwhile
        // (but not delivered yet)
        if(learner_is_closed(i)) {
            ii->status = p2_completed;
            p2_info.open_count -= 1;
            //The rest (i.e. answering client)
            // is done when the value is actually delivered
            LOG(VRB, ("Instance %lu closed, waiting for deliver\n", i));
            continue;
        }

        //Not expired yet, skip
        if(!leader_is_expired(&ii->timeout, &now)) {
            continue;
        }

        //Expired and not closed: must restart from phase 1
        ii->status = p1_pending;
        p1_info.pending_count += 1;
        ii->my_ballot = NEXT_BALLOT(ii->my_ballot);
        //Send prepare to acceptors
        sendbuf_add_prepare_req(to_acceptors, ii->iid, ii->my_ballot);
        leader_set_expiration(ii, P1_TIMEOUT_INTERVAL);

        LOG(VRB, ("Instance %lu restarts from phase 1\n", i));

        COUNT_EVENT(p2_timeout);

    }

    //Flush last message if any
    sendbuf_flush(to_acceptors);

    //Open new instances
    leader_open_instances_p2_new();
    
    //Set next invokation of this function
    leader_set_next_p2_check();

}