Esempio n. 1
0
func (r *Replica) HandleQLeaseReply(ql *qlease.Lease, pr *qleaseproto.PromiseReply) {
	if pr.TimestampNs < ql.LatestTsSent {
		//old reply, ignore
		return
	}
	if pr.LeaseInstance > ql.PromisedByMeInst {
		ql.PromiseRejects++
		if ql.PromiseRejects == r.N {
			ql.WriteInQuorumUntil = 0
		}
		return
	}
	now := time.Now().UnixNano()
	max := now
	for i := int32(0); i < int32(r.N); i++ {
		if i == r.Id {
			continue
		}
		if i == pr.ReplicaId {
			ql.LatestRepliesReceived[i] = now + ql.Duration
		}
		if max < ql.LatestRepliesReceived[i] {
			max = ql.LatestRepliesReceived[i]
		}
	}

	ql.WriteInQuorumUntil = max

	r.LastReplyReceivedTimestamp[pr.ReplicaId] = now
}
Esempio n. 2
0
func (r *Replica) EstablishQLease(ql *qlease.Lease) {
	now := time.Now().UnixNano()
	ql.LatestTsSent = now
	ql.PromiseRejects = 0
	g := &qleaseproto.Guard{r.Id, now, qlease.GUARD_DURATION_NS}
	for i := int32(0); i < int32(r.N); i++ {
		if i == r.Id || !r.Alive[i] {
			continue
		}
		r.SendMsg(i, r.qleaseGuardRPC, g)
	}
}
Esempio n. 3
0
func (r *Replica) RenewQLease(ql *qlease.Lease, latestAccInst int32) {
	now := time.Now().UnixNano()
	ql.PromiseRejects = 0
	p := &qleaseproto.Promise{r.Id, ql.PromisedByMeInst, now, ql.Duration, latestAccInst}
	for i := int32(0); i < int32(r.N); i++ {
		if i == r.Id || !r.Alive[i] {
			continue
		}
		ql.LatestRepliesReceived[i] += ql.Duration
		r.SendMsg(i, r.qleasePromiseRPC, p)
	}
	ql.LatestTsSent = now

	// sufficient to extend wait time by the duration of the lease, because
	// grantees must receive the lease refresh message before the previous lease expires
	// (otherwise they will dicount the refresh)
	ql.WriteInQuorumUntil += ql.Duration
}
Esempio n. 4
0
func (r *Replica) HandleQLeasePromise(ql *qlease.Lease, p *qleaseproto.Promise) bool {
	now := time.Now().UnixNano()
	// check that this promise was received on time
	if ql.LatestPromisesReceived[p.ReplicaId] < now && ql.GuardExpires[p.ReplicaId] < now {
		//didn't receive promise on time, must ignore
		//TODO: send NACK as optimization
		return false
	}

	if p.LeaseInstance < ql.PromisedToMeInst {
		// the sender must update its lease view
		pr := &qleaseproto.PromiseReply{r.Id, ql.PromisedToMeInst, p.TimestampNs}
		r.SendMsg(p.ReplicaId, r.qleasePromiseReplyRPC, pr)
		return false
	} else if p.LeaseInstance > ql.PromisedToMeInst {
		ql.PromisedToMeInst = p.LeaseInstance
		for i := int32(0); i < int32(r.N); i++ {
			ql.LatestPromisesReceived[i] = 0
		}
	}

	ql.LatestPromisesReceived[p.ReplicaId] = now + p.DurationNs

	//send reply
	pr := &qleaseproto.PromiseReply{r.Id, ql.PromisedToMeInst, p.TimestampNs}
	r.SendMsg(p.ReplicaId, r.qleasePromiseReplyRPC, pr)

	sorted := make([]int64, r.N)
	copy(sorted, ql.LatestPromisesReceived)
	sorted[r.Id] = 0
	sort.Sort(Int64Slice(sorted))

	ql.ReadLocallyUntil = sorted[r.N-(r.N/2)]

	return true
}
Esempio n. 5
0
func (r *Replica) HandleQLeaseGuardReply(ql *qlease.Lease, gr *qleaseproto.GuardReply, latestAccInst int32) {

	if gr.TimestampNs < ql.LatestTsSent {
		//old reply, must ignore
		return
	}

	now := time.Now().UnixNano()

	p := &qleaseproto.Promise{r.Id, ql.PromisedByMeInst, now, ql.Duration, latestAccInst}

	ql.LatestRepliesReceived[gr.ReplicaId] = now + qlease.GUARD_DURATION_NS + ql.Duration

	if ql.WriteInQuorumUntil < ql.LatestRepliesReceived[gr.ReplicaId] {
		ql.WriteInQuorumUntil = ql.LatestRepliesReceived[gr.ReplicaId]
	}

	r.SendMsg(gr.ReplicaId, r.qleasePromiseRPC, p)
}