/*检查超时的提案,进行重新提议*/ static void proposer_check_timeouts(evutil_socket_t fd, short event, void* arg) { struct evproposer* p = arg; struct timeout_iterator* iter = proposer_timeout_iterator(p->state); /*第一个阶段超时提案*/ prepare_req* pr; while((pr == timeout_iterator_prepare(iter)) != NULL){ /*获取超时的提案(第一阶段)*/ paxos_log_info("Instance %d timed out.", pr->iid); /*对超时提案重新发起提议过程*/ send_prepares(p, pr); free(pr); } accept_req* ar; while((ar = timeout_iterator_accept(iter)) != NULL){ /*获得超时提案(第二阶段)*/ paxos_log_info("Instance %d timed out.", ar->iid); send_accepts(p, ar); free(ar); } /*释放超时管理的迭代器*/ timeout_iterator_free(iter); /*插入一个定时器*/ event_add(p->timeout_ev, &p->tv); }
static void proposer_handle_prepare_ack(struct evproposer* p, prepare_ack* ack) { prepare_req pr; int preempted = proposer_receive_prepare_ack(p->state, ack, &pr); if (preempted) send_prepares(p, &pr); }
static void proposer_preexecute(struct evproposer* p) { int i; prepare_req pr; int count = p->preexec_window - proposer_prepared_count(p->state); //先进先出队列保存准备实例,队列长128,用一个释放一个,有空间了就把新的加到队列末尾。 if (count <= 0) return; for (i = 0; i < count; i++) { proposer_prepare(p->state, &pr); //发送prepare请求 send_prepares(p, &pr); } paxos_log_debug("Opened %d new instances", count); }
static void proposer_preexecute(struct evproposer* p) { int i; prepare_req pr; /*获得可以发起提案的个数*/ int count = p->preexec_window - proposer_prepared_count(p->state); for(i = 0; i < count; i ++){ /*构建一个prepare_req消息*/ proposer_prepare(p->state, &pr); /*发起一个提案*/ send_prepares(p, &pr); } }
static void proposer_check_timeouts(evutil_socket_t fd, short event, void *arg) { struct evproposer* p = arg; struct timeout_iterator* iter = proposer_timeout_iterator(p->state); prepare_req* pr; while ((pr = timeout_iterator_prepare(iter)) != NULL) { paxos_log_info("Instance %d timed out.", pr->iid); send_prepares(p, pr); free(pr); } accept_req* ar; while ((ar = timeout_iterator_accept(iter)) != NULL) { paxos_log_info("Instance %d timed out.", ar->iid); send_accepts(p, ar); free(ar); } timeout_iterator_free(iter); event_add(p->timeout_ev, &p->tv); //Thus, if you want to make the event pending again, you can call event_add() on it again from inside the callback function.将超时事件重新加入 }
/*proposer对accept ack的处理和响应*/ static void proposer_handle_accept_ack(struct evproposer* p, accept_ack* ack) { prepare_req pr; if (proposer_receive_accept_ack(p->state, ack, &pr))/*对accept ack的响应处理,判断返回值是否是需要重新发起第一阶段*/ send_prepares(p, &pr); }