Beispiel #1
0
//Use NOP to detect the gap slots [from, to)
func CatchUp(pn *paxosNode, from, to int) {
	pn.catchupMutex.Lock()
	pn.catchupCounter++
	pn.catchupMutex.Unlock()
	for index := from; index < to; index++ {
		i := 1
		c := new(command.Command)
		c.Type = command.NOP
		LOGV.Printf("node %d Try to catch up with slot %d\n", pn.nodeID, index)
		success, _, num := pn.DoReplicate(c, 0, index)
		for !success {
			LOGV.Printf("node %d last Paxos is not success, waiting to try again...\n", pn.nodeID)
			//TODO:maybe do not need to wait
			time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond)
			LOGV.Printf("node %d last Paxos is not success, try again...\n", pn.nodeID)
			//i++
			LOGV.Printf("node %d Try to catch up with slot %d\n", pn.nodeID, index)
			i = (num/pn.numNodes + 1)
			success, _, num = pn.DoReplicate(c, i, index)
		}
		LOGV.Printf("Catched up with slot %d\n", index)
	}
	pn.catchupMutex.Lock()
	pn.catchupCounter--
	pn.catchupMutex.Unlock()
}
Beispiel #2
0
func (q *Queue) Enqueue(c *command.Command) {
	//fmt.Println("Enqueue command:"+c.ToString())
	q.lock.Lock()
	//q.cond.L.Lock()
	if c.Type == command.Acquire {
		c.Value = strconv.FormatInt(time.Now().UnixNano(), 10)
	}
	q.l.PushBack(c)
	q.lock.Unlock()
	//q.cond.L.Unlock()
	q.cond.Signal()
	//fmt.Println("After Enqueue command:"+c.ToString())
}
Beispiel #3
0
func (pn *paxosNode) Replicate(command *command.Command) error {
	i := 1
	command.AddrPort = pn.addrport
	LOGV2.Printf("node %d get lock in DoReplicate()\n", pn.nodeID)
	pn.cmdMutex.Lock()
	index := len(pn.commitedCommands)
	LOGV.Printf("in replicate, cur len %d\n", index)
	LOGV2.Printf("node %d release lock in DoReplicate()\n", pn.nodeID)
	pn.cmdMutex.Unlock()
	_, success, num := pn.DoReplicate(command, 0, index)
	for !success {
		LOGV.Printf("node %d last Paxos is not success, waiting to try again...\n", pn.nodeID)
		time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond)
		LOGV.Printf("node %d last Paxos slot %d is not success, try again... iter:%d\n", pn.nodeID, index, i)
		LOGV2.Printf("node %d get lock in DoReplicate()\n", pn.nodeID)
		pn.cmdMutex.Lock()
		length := len(pn.commitedCommands)
		LOGV.Printf("in retry, cur len %d\n", index)
		LOGV2.Printf("node %d release lock in DoReplicate()\n", pn.nodeID)
		pn.cmdMutex.Unlock()
		if index < length { // the slot has been passed
			//LOGV.Printf("node %d slot %d need no retry, since other nodes commited %s\n", pn.nodeID, index, pn.commitedCommands[index].ToString())
			if pn.commitedCommands[index].AddrPort == "" {
				//empty slot here, index keeps the same, iter increases
				i = (num/pn.numNodes + 1)
			} else if pn.commitedCommands[index].AddrPort == pn.addrport {
				//Has commited by other nodes, just return
				return nil
			} else {
				//the slot has been occupied by other node's command
				//try to contend to a new slot
				index = length
				i = 0
			}
		} else {
			i = (num/pn.numNodes + 1)
		}
		_, success, num = pn.DoReplicate(command, i, index)
	}
	return nil
}
Beispiel #4
0
func fakecallback(index int, c command.Command) {
	fmt.Printf("\n%d's index %d is %s\n", nid, index, c.ToString())
	done <- struct{}{}
}