func (f *followConn) offerTimeout(slot uint64, duration time.Duration) { f.lock.Lock() defer f.lock.Unlock() if f.closed { return } // TODO: Only send this on one Follow connection. var intReq fproto.InstructionRequest intReq.Slot = new(uint64) *intReq.Slot = slot f.conn.SendProto(8, &intReq) f.offerTimers[slot] = time.AfterFunc(duration*2, func() { f.offerTimeout(slot, duration*2) }) }
func handleInstructionChosen(f *followConn, content []byte) { store.StartTransaction() defer store.EndTransaction() f.lock.Lock() defer f.lock.Unlock() var msg fproto.InstructionChosen if err := proto.Unmarshal(content, &msg); err != nil { f.Close() return } if f.closed { return } relativeSlot := int(*msg.Slot - store.InstructionStart()) if relativeSlot < 0 { return } instructions := store.InstructionSlots() if relativeSlot < len(instructions) { slot := instructions[relativeSlot] if len(slot) == 1 && slot[0].IsChosen() { return } } if !config.IsCore() { // TODO: Should only do this on one follow connection. var intReq fproto.InstructionRequest intReq.Slot = msg.Slot f.conn.SendProto(8, &intReq) } timeout := config.ROUND_TRIP_TIMEOUT_PERIOD f.offerTimers[*msg.Slot] = time.AfterFunc( timeout, func() { f.offerTimeout(*msg.Slot, timeout) }) }