예제 #1
0
// leader has another responsibility to update the highest request that can be executed,
// and if the leader is also synchronous, it can execute the record in this stage
static void leader_try_to_execute(consensus_component* comp){
    SYS_LOG(comp, "highest_seen_req_id %lu.\n", comp->highest_seen_vs->req_id);
    SYS_LOG(comp, "highest_seen_view_id %lu.\n", comp->highest_seen_vs->view_id);
    SYS_LOG(comp, "highest_to_commit_vs_req_id %lu.\n", comp->highest_to_commit_vs->req_id);
    SYS_LOG(comp, "highest_to_commit_vs_view_id %lu.\n", comp->highest_to_commit_vs->view_id);
    db_key_type start;
    db_key_type end = vstol(comp->highest_seen_vs);;

    size_t data_size;
    view_stamp temp_boundary;
    view_boundary* boundary_record = NULL;
    if(comp->highest_seen_vs->view_id != comp->highest_to_commit_vs->view_id){
        // address the boundary
        
        assert(comp->highest_to_commit_vs->view_id + 1 == comp->highest_seen_vs->view_id);
        comp->highest_to_commit_vs->view_id += 1;
        comp->highest_to_commit_vs->req_id = 0;
        comp->highest_committed_vs->view_id = comp->highest_to_commit_vs->view_id;
        comp->highest_committed_vs->req_id = comp->highest_to_commit_vs->req_id;
        start = vstol(comp->highest_to_commit_vs); 
    } else{
        start = vstol(comp->highest_to_commit_vs)+1;
    }

    int exec_flag = (!view_stamp_comp(comp->highest_committed_vs,comp->highest_to_commit_vs));
    request_record* record_data = NULL;
    SYS_LOG(comp,"The Leader Tries To Execute.\n");
    SYS_LOG(comp,"The Start Value Is %lu.\n",start);
    SYS_LOG(comp,"The End Value Is %lu.\n",end);
    for(db_key_type index=start;index<=end;index++){
        retrieve_record(comp->db_ptr,sizeof(index),&index,&data_size,(void**)&record_data);
        assert(record_data!=NULL && "The Record Should Be Inserted By The Node Itself!");
        if(reached_quorum(record_data,comp->group_size)){
            view_stamp temp = ltovs(index);
            SYS_LOG(comp,"Node %d : View Stamp %u : %u Has Reached Quorum.\n",
                    comp->node_id,temp.view_id,temp.req_id);
            
            SYS_LOG(comp,"Before Node %d Inc Execute  %u : %u.\n",
                    comp->node_id,
                    comp->highest_to_commit_vs->view_id,
                    comp->highest_to_commit_vs->req_id);
            view_stamp_inc(comp->highest_to_commit_vs);
            SYS_LOG(comp,"After Node %d Inc Execute  %u : %u.\n",
                    comp->node_id,
                    comp->highest_to_commit_vs->view_id,
                    comp->highest_to_commit_vs->req_id);

            if(exec_flag){
                view_stamp vs = ltovs(index);
                deliver_msg_data(comp,&vs);
                view_stamp_inc(comp->highest_committed_vs);
            }
        }else{
            return;
        }
    }
}
예제 #2
0
static int leader_handle_submit_req(struct consensus_component_t* comp,
        size_t data_size,void* data,view_stamp* vs){
    
    int ret = 1;
    view_stamp next = get_next_view_stamp(comp);
    if(NULL!=vs){
        vs->view_id = next.view_id;
        vs->req_id = next.req_id;
    }
    db_key_type record_no = vstol(&next);
    request_record* record_data = 
        (request_record*)malloc(data_size+sizeof(request_record));
    gettimeofday(&record_data->created_time,NULL);
    record_data->bit_map = (1<<comp->node_id);
    record_data->data_size = data_size;
    record_data->is_closed = 0;
    memcpy(record_data->data,data,data_size);
    if(store_record(comp->db_ptr,sizeof(record_no),&record_no,REQ_RECORD_SIZE(record_data),record_data)){
        goto handle_submit_req_exit;
    }
    ret = 0;
    view_stamp_inc(comp->highest_seen_vs);
    if(comp->group_size>1){
        accept_req* msg = build_accept_req(comp,REQ_RECORD_SIZE(record_data),record_data,&next);
        SYS_LOG(comp, "group_size > 1, sending out consensus msg.\n");
        if(NULL==msg){
            goto handle_submit_req_exit;
        }
        comp->uc(comp->my_node,ACCEPT_REQ_SIZE(msg),msg,-1);
        free(msg);
    }else{
        SYS_LOG(comp, "group_size <= 1, execute by myself.\n");
        try_to_execute(comp);
    }
handle_submit_req_exit: 
    // no need to care about database, every time we will override it.
    if(record_data!=NULL){
        free(record_data);
    }
    
    return ret;
}
예제 #3
0
static void try_to_execute(consensus_component* comp){
    // there we have assumption, for the currently leader,whose commited request
    // and highest request to execute must be in the same view, otherwise, the
    // leader cannot be the leader 
    
    SYS_LOG(comp,"Node %d Try To Execute.\n",
            comp->node_id);
    if(comp->cur_view->view_id==0){
        SYS_LOG(comp,"Node %d Currently Is A NULL Node\n",
                comp->node_id);
        goto try_to_execute_exit;
    }
    if(LEADER==comp->my_role){
        leader_try_to_execute(comp);
    }
    db_key_type start = vstol(comp->highest_committed_vs)+1;
    db_key_type end;
    view_stamp temp_boundary;
    view_boundary* boundary_record = NULL;
    size_t data_size;
    if(comp->highest_committed_vs->view_id!=comp->highest_to_commit_vs->view_id){
        
        SYS_LOG(comp, "highest_to_commit_vs_req_id %lu.\n", comp->highest_to_commit_vs->req_id);
        SYS_LOG(comp, "highest_to_commit_vs_view_id %lu.\n", comp->highest_to_commit_vs->view_id);
        SYS_LOG(comp, "highest_committed_vs_req_id %lu.\n", comp->highest_committed_vs->req_id);
        SYS_LOG(comp, "highest_committed_vs_view_id %lu.\n", comp->highest_committed_vs->view_id);
        //address the boundary
        view_stamp bound;
        bound.view_id = comp->highest_committed_vs->view_id+1;
        bound.req_id = 0;
        db_key_type bound_record_no = vstol(&bound);
        retrieve_record(comp->db_ptr,sizeof(bound_record_no),&bound_record_no,&data_size,(void**)&boundary_record);
        if(NULL==boundary_record){
           SYS_LOG(comp, "Missing bounday_record.\n");
           send_missing_req(comp,&bound); 
           goto try_to_execute_exit;
        }
        temp_boundary.view_id = boundary_record->view_id;
        temp_boundary.req_id = boundary_record->req_id;
        SYS_LOG(comp, "boundary_record_req_id %lu.\n", boundary_record->req_id);
        SYS_LOG(comp, "boundary_record_view_id %lu.\n", boundary_record->view_id);
        end = vstol(&temp_boundary);
    }else{
        end = vstol(comp->highest_to_commit_vs);
    }
    SYS_LOG(comp,"The End Value Is %lu.\n", end);
    request_record* record_data = NULL;
    // we can only execute thins in sequence
    int exec_flag = 1;
    view_stamp missing_vs;
    for(db_key_type index = start;index<=end;index++){
        missing_vs = ltovs(index);
        if(0!=retrieve_record(comp->db_ptr,sizeof(index),&index,
                    &data_size,(void**)&record_data)){
            exec_flag = 0;
            send_missing_req(comp,&missing_vs);
        }
        if(exec_flag){
            deliver_msg_data(comp,&missing_vs);
//            record_data->is_closed = 1;
//            store_record(comp->db_ptr,sizeof(index),&index,REQ_RECORD_SIZE(record_data),record_data);
            view_stamp_inc(comp->highest_committed_vs);
        }
        record_data = NULL;
    }
    if(NULL!=boundary_record){
        temp_boundary.view_id = boundary_record->view_id;
        temp_boundary.req_id = boundary_record->req_id;
        db_key_type op1 = vstol(comp->highest_committed_vs);
        db_key_type op2 = vstol(&temp_boundary);
        if(op1==op2){
            cross_view(comp->highest_committed_vs);
        }
    }
try_to_execute_exit:
    return;
};