示例#1
0
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
	}
}
示例#2
0
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
}