예제 #1
0
파일: evprepare.c 프로젝트: ahnufy/libpaxos
/*建立一个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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}