// The newserver is the actual server where the paxos node runs and also keeps // information on clients func NewServer(myhostPort, coordinatorHostPort string, numPaxos, srvId int, hostMap map[int]string) (Server, error) { if numPaxos < 1 { return nil, errors.New("numPaxos should be more than 0") } s := &server{ hostMap: make(map[int]string), clients: make(map[int]*client), clientMutex: sync.Mutex{}, numClients: 0, srvId: srvId, bidChan: make(chan string), } c, err := rpc.DialHTTP("tcp", coordinatorHostPort) if err != nil { fmt.Println(err) return nil, err } args := &coordinatorrpc.RegisterPaxosServerArgs{srvId} var reply coordinatorrpc.RegisterPaxosServerReply reply.Status = coordinatorrpc.NotReady for reply.Status != coordinatorrpc.OK { err := c.Call("Coordinator.RegisterPaxosServer", args, &reply) if err != nil { fmt.Println(err) return nil, err } time.Sleep(time.Duration(rand.Int()%100) * time.Millisecond) } pn, err := paxos.NewPaxosNode(myhostPort, hostMap, numPaxos, srvId, numRetries, false) if err != nil { fmt.Println("Error starting paxos", err) return nil, err } s.pn = pn for nodeID, hostPort := range hostMap { s.hostMap[nodeID] = hostPort } // go s.clientHandler() http.HandleFunc("/bid/", s.bidHandler) http.HandleFunc("/view/", s.viewHandler) go http.ListenAndServe(myhostPort, nil) go s.broadcast() return s, nil }
// RegisterPaxosServer is called by paxos nodes to register to the central coordinator func (c *coordinator) RegisterPaxosServer(args *coordinatorrpc.RegisterPaxosServerArgs, reply *coordinatorrpc.RegisterPaxosServerReply) error { c.serversMutex.Lock() nodeID := args.NodeID _, exists := c.serversMap[nodeID] if exists == false { c.serversMap[nodeID] = c.hostMap[nodeID] } if len(c.serversMap) >= c.numPaxos { reply.Status = coordinatorrpc.OK } else { reply.Status = coordinatorrpc.NotReady } c.serversMutex.Unlock() return nil }