// 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; } } }
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; }
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; };