Beispiel #1
0
func handleChosen(slot uint64) {

	var msg fproto.InstructionChosen
	msg.Slot = new(uint64)
	*msg.Slot = slot
	msgBuf, err := proto.Marshal(&msg)
	if err != nil {
		panic("generated bad instruction chosen message")
	}

	var baseMsg baseproto.Message
	baseMsg.MsgType = new(uint32)
	*baseMsg.MsgType = 7
	baseMsg.Content = msgBuf

	connectionsLock.Lock()

	for _, conn := range connections {

		conn.lock.Lock()

		if !conn.sendingBurst {
			conn.conn.Send(&baseMsg)
		}

		if timer, exists := conn.offerTimers[slot]; exists {
			timer.Stop()
			delete(conn.offerTimers, slot)
		}

		conn.lock.Unlock()
	}

	connectionsLock.Unlock()
}
Beispiel #2
0
// Sends a burst to the given connection.
// The Bursting message should already have been sent,
// and f.sendingBurst set to true, before calling this asynchronously.
func sendBurst(f *followConn) {

	log.Print("shared/follow: sending burst to ", f.node)

	globalProp := new(fproto.GlobalProperty)
	globalProp.Key = new(string)
	globalProp.Value = new(string)

	entityProp := new(fproto.EntityProperty)
	entityProp.Entity = new(uint64)
	entityProp.Key = new(string)
	entityProp.Value = new(string)

	aborted := false
	store.Burst(func(key, value string) bool {
		*globalProp.Key = key
		*globalProp.Value = value

		if !f.conn.SendProto(4, globalProp) {
			aborted = true
		}
		return !aborted
	}, func(entity uint64, key, value string) bool {
		*entityProp.Entity = entity
		*entityProp.Key = key
		*entityProp.Value = value

		if !f.conn.SendProto(5, entityProp) {
			aborted = true
		}
		return !aborted
	})

	if aborted {
		return
	}

	store.StartTransaction()
	defer store.EndTransaction()
	f.lock.Lock()
	defer f.lock.Unlock()

	f.sendingBurst = false

	burstDone := new(fproto.BurstDone)
	burstDone.FirstUnapplied = new(uint64)
	*burstDone.FirstUnapplied = store.InstructionFirstUnapplied()
	f.conn.SendProto(6, burstDone)

	// Send an instruction chosen message for all chosen instructions above
	// our first unapplied point.
	instructions := store.InstructionSlots()
	firstUnapplied := store.InstructionFirstUnapplied()
	relativeSlot := int(firstUnapplied - store.InstructionStart())
	for ; relativeSlot < len(instructions); relativeSlot++ {
		slot := store.InstructionStart() + uint64(relativeSlot)
		slotValues := instructions[relativeSlot]
		if len(slotValues) != 1 || !slotValues[0].IsChosen() {
			continue
		}

		// Convert the change request to our internal format.
		chosen := new(fproto.InstructionChosen)
		chosen.Slot = new(uint64)
		*chosen.Slot = slot
		f.conn.SendProto(7, chosen)
	}
}