Пример #1
0
func (ln *leaseNode) dofunction(args *leaserpc.Args, reply *leaserpc.Reply, funcname string) error {
	replychan := make(chan *leaserpc.Reply, len(ln.peers))

	for _, n := range ln.peers {
		go func(peernode Node) {
			if peernode.HostPort == ln.addrport {
				r := leaserpc.Reply{}
				switch {
				case funcname == "LeaseNode.Prepare":
					ln.Prepare(args, &r)
				case funcname == "LeaseNode.Accept":
					ln.Accept(args, &r)
				case funcname == "LeaseNode.RenewPrepare":
					ln.RenewPrepare(args, &r)
				case funcname == "LeaseNode.RenewAccept":
					ln.RenewAccept(args, &r)
				}
				replychan <- &r
			} else {
				r := leaserpc.Reply{}
				peer, err := rpcwrapper.DialHTTP("tcp", peernode.HostPort)
				if err != nil {
					r.Status = leaserpc.Reject
					replychan <- &r
					return
				}
				prepareCall := peer.Go(funcname, args, &r, nil)
				select {
				case _, _ = <-prepareCall.Done:
					replychan <- &r
				case _ = <-time.After(time.Second):
					r.Status = leaserpc.Reject
					replychan <- &r
				}
				peer.Close()
			}
		}(n)
	}

	numOK, numRej := 0, 0
	for num := 0; num < len(ln.peers); num++ {
		r, _ := <-replychan
		if r.Status == leaserpc.OK {
			numOK++
		} else {
			numRej++
		}
	}

	if numOK > ln.numNodes/2 {
		reply.Status = leaserpc.OK
		return nil
	} else {
		reply.Status = leaserpc.Reject
		return nil
	}
}
Пример #2
0
func (ln *leaseNode) Accept(args *leaserpc.Args, reply *leaserpc.Reply) error {
	LOGV.Printf("node %d receives accept %d\n", ln.nodeID, args.N)
	ln.leaseMutex.Lock()
	if args.N < ln.Nh {
		reply.Status = leaserpc.Reject
		LOGV.Printf("node %d rejects accept %d\n", ln.nodeID, args.N)
	} else {
		ln.Nh = args.N
		ln.Na = args.N
		ln.acceptLeaseLen = LEASE_LEN
		reply.Status = leaserpc.OK
		LOGV.Printf("node %d accepts accept %d\n", ln.nodeID, args.N)
	}
	ln.leaseMutex.Unlock()
	return nil
}
Пример #3
0
func (ln *leaseNode) RenewPrepare(args *leaserpc.Args, reply *leaserpc.Reply) error {
	LOGV.Printf("node %d receives renewprepare %d\n", ln.nodeID, args.N)
	ln.leaseMutex.Lock()
	if ln.Nh < args.N {
		ln.Nh = args.N
	}
	if ln.Na == args.N || (ln.acceptLeaseLen == 0 && ln.masterLeaseLen == 0) {
		reply.Status = leaserpc.OK
		LOGV.Printf("node %d accepts renewprepare %d\n", ln.nodeID, args.N)
	} else {
		reply.Status = leaserpc.Reject
		LOGV.Printf("node %d rejects renewprepare %d\n", ln.nodeID, args.N)
	}
	ln.leaseMutex.Unlock()
	return nil
}
Пример #4
0
func (ln *leaseNode) Prepare(args *leaserpc.Args, reply *leaserpc.Reply) error {
	LOGV.Printf("node %d receives prepare %d\n", ln.nodeID, args.N)
	ln.leaseMutex.Lock()
	if args.N < ln.Nh {
		reply.Status = leaserpc.Reject
	} else {
		ln.Nh = args.N
		if ln.masterLeaseLen > 0 || ln.acceptLeaseLen > 0 {
			reply.Status = leaserpc.Reject
			LOGV.Printf("node %d rejects prepare %d\n", ln.nodeID, args.N)
		} else {
			reply.Status = leaserpc.OK
			LOGV.Printf("node %d accepts prepare %d\n", ln.nodeID, args.N)
		}
	}
	ln.leaseMutex.Unlock()
	return nil
}