/*建立一个proposer对象,并启动它*/ struct evproposer* evproposer_init(int id, const char* config, struct event_base* b) { int port, acceptor_count; struct evproposer* p; /*读取配置文件*/ struct evpaxos_config* conf = evpaxos_config_read(config); if(conf == NULL) return NULL; /*非法的proposer id*/ if (id < 0 || id >= MAX_N_OF_PROPOSERS) { paxos_log_error("Invalid proposer id: %d", id); return NULL; } /*读取proposer的监听端口*/ port = evpaxos_proposer_listen_port(conf, id); /*读取acceptor的数量*/ acceptor_count = evpaxos_acceptor_count(conf); p = (struct evproposer *)malloc(sizeof(struct evproposer)); p->id = id; p->base = b; /*获得同时提交的议案数量*/ p->preexec_window = paxos_config.proposer_preexec_window; /*产生一个网络消息接收器*/ p->receiver = tcp_receiver_new(b, port, handle_request, p); /*产生一个acceptor的管理器*/ p->acceptors = peers_new(b); /*对每个acceptor发起连接*/ peers_connect_to_acceptors(p->acceptors, conf, handle_request, p); /*设置定时器*/ p->tv.tv_sec = paxos_config.proposer_timeout; p->tv.tv_usec = 0; /*产生一个libevent定时器事件对象,并设置一个定时器*/ p->timeout_ev = evtimer_new(b, proposer_check_timeouts, p); event_add(p->timeout_ev, &p->tv); /*产生一个proposer 消息处理器*/ p->state = proposer_new(p->id, acceptor_count); /*试探性执行prepare过程(提案第一阶段)*/ proposer_preexecute(p); evpaxos_config_free(conf); return p; }
struct evproposer* evproposer_init(int id, const char* config_file, struct event_base* b) { int i; struct evproposer* p; struct config* conf = read_config(config_file); //读取配置文件 if (conf == NULL) return NULL; // Check id validity of proposer_id if (id < 0 || id >= MAX_N_OF_PROPOSERS) { //检查proposerid paxos_log_error("Invalid proposer id: %d", id); return NULL; } p = malloc(sizeof(struct evproposer)); p->id = id; p->base = b; p->preexec_window = paxos_config.proposer_preexec_window; //128 // Setup client listener p->receiver = tcp_receiver_new(b, &conf->proposers[id], handle_request, p); //创建新的接收器 // Setup connections to acceptors p->acceptors = peers_new(b, conf->acceptors_count); //连接池 for (i = 0; i < conf->acceptors_count; i++) peers_connect(p->acceptors, &conf->acceptors[i], handle_request, p); //连接各个acceptor // Setup timeout p->tv.tv_sec = paxos_config.proposer_timeout; p->tv.tv_usec = 0; p->timeout_ev = evtimer_new(b, proposer_check_timeouts, p); event_add(p->timeout_ev, &p->tv); //添加超时事件 p->state = proposer_new(p->id, conf->acceptors_count); //创建新的proposer状态机 free_config(conf); return p; }
static void* run_discovery(void* data) { discovery_opts_t* opts = (discovery_opts_t*)data; char ip[INET_ADDRSTRLEN] = { '\0' }; const char* interface = opts->interface; udp_t *udp = udp_new(PING_PORT_NUMBER, interface); assert(udp); struct pollfd ufds[1]; int ret; time_t t0, t1; beacon_t beacon; uuid_t uuid; beacon_t recv; peers_t* peers = peers_new(); struct in_addr addr; find_my_ip(&addr, NULL); uuid_generate(uuid); beacon_fill(&beacon, (uint8_t*)BEACON_PROTOCOL, BEACON_VERSION, uuid, addr, htons(47473)); ufds[0].fd = udp_handle(udp); ufds[0].events = POLLIN; t0 = time(NULL); t1 = time(NULL); struct sockaddr_in sockaddr; socklen_t si_len = sizeof(struct sockaddr_in); while (1) { t1 = time(NULL); if ((long)(t1 - t0) >= PING_INTERVAL) { ret = udp_send(udp, (uint8_t*)(&beacon), sizeof(beacon_t)); assert(ret == sizeof(beacon_t)); t0 = time(NULL); } ret = poll(ufds, 1, 200); if (ret == -1) { printf("Error: poll returned -1\n"); break; } else if (ret == 0) { continue; } if (ufds[0].revents & POLLIN) { ret = udp_recv(udp, (uint8_t*)&recv, sizeof(beacon_t), &sockaddr, si_len); if (ret == sizeof(beacon_t) && beacon_check(&recv, (uint8_t*)BEACON_PROTOCOL, BEACON_VERSION)) { if (uuid_compare(uuid, recv.uuid) != 0) { peer_t* peer = peers_exist(peers, recv.uuid); if (!peer) { inet_ntop(sockaddr.sin_family, &sockaddr.sin_addr, ip, INET_ADDRSTRLEN); peer = peer_new(recv.uuid, ip, recv.port); peers_add(peers, peer); opts->add_peer_cb((void*)peer); } peer_is_alive(peer); } } } peers_check(peers); } peers_destroy(&peers); udp_destroy(&udp); return NULL; }