func (pn *paxosNode) DoAccept(args *paxosrpc.AcceptArgs, reply *paxosrpc.AcceptReply) error { LOGV.Printf("node %d DoAccept:%d %s %d\n", pn.nodeID, args.SlotIdx, args.V.ToString(), args.N) replychan := make(chan *paxosrpc.AcceptReply, len(pn.peers)) for i, n := range pn.peers { go func(idx int, peernode Node) { r := new(paxosrpc.AcceptReply) if peernode.HostPort == pn.addrport { pn.Accept(args, r) replychan <- r } else { peer, err := rpcwrapper.DialHTTP("tcp", peernode.HostPort) if err != nil { LOGE.Printf("node %d Cannot reach peer %d:%s\n", pn.nodeID, idx, peernode.HostPort) r.Status = paxosrpc.Reject replychan <- r return } prepareCall := peer.Go("PaxosNode.Accept", args, r, nil) select { case _, _ = <-prepareCall.Done: replychan <- r case _ = <-time.After(time.Second): r.Status = paxosrpc.Reject replychan <- r } peer.Close() } }(i, n) } numOK := 0 numRej := 0 for num := 0; num < pn.numNodes; num++ { r, _ := <-replychan if r.Status != paxosrpc.Reject { numOK++ } else { numRej++ } } LOGV.Printf("node %d DoAccept %d result: [%dOK %dRej]\n", pn.nodeID, args.SlotIdx, numOK, numRej) if numOK > len(pn.peers)/2 { reply.Status = paxosrpc.OK return nil } else { reply.Status = paxosrpc.Reject return nil } }
func (pn *paxosNode) Accept(args *paxosrpc.AcceptArgs, reply *paxosrpc.AcceptReply) error { LOGV.Printf("node %d OnAccept:%d %s %d\n", pn.nodeID, args.SlotIdx, args.V.ToString(), args.N) LOGV2.Printf("node %d get lock in Accept()\n", pn.nodeID) pn.cmdMutex.Lock() v, ok := pn.tempSlots[args.SlotIdx] if ok && args.N >= v.Nh { /*if v.isAccepted || v.isCommited { //accepted or commited state v.Nh = args.N reply.Status = paxosrpc.OK return nil } else { //prepare state*/ v.isAccepted = true v.Na = args.N v.Nh = args.N v.V = args.V pn.tempSlots[args.SlotIdx] = v reply.Status = paxosrpc.OK //return nil // } } else if !ok { ic := IndexCommand{} ic.Index = args.SlotIdx ic.Na = args.N ic.Nh = args.N ic.V = args.V ic.isAccepted = true ic.isCommited = false pn.tempSlots[args.SlotIdx] = ic reply.Status = paxosrpc.OK } else { reply.Status = paxosrpc.Reject } LOGV2.Printf("node %d release lock in Accept()\n", pn.nodeID) pn.cmdMutex.Unlock() LOGV.Printf("node %d leaving OnAccept(%d %s %d)\t[%d]\n", pn.nodeID, args.SlotIdx, args.V.ToString(), args.N, reply.Status) return nil }