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
func handleProposalChange() {
	proposal, leader := store.Proposal()

	var msg fproto.Leader
	msg.Proposal = new(uint64)
	msg.Leader = new(uint32)
	*msg.Proposal = proposal
	*msg.Leader = uint32(leader)
	msgBuf, err := proto.Marshal(&msg)
	if err != nil {
		panic("generated bad leader update message")
	}

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

	connectionsLock.Lock()

	for _, conn := range connections {
		conn.conn.Send(&baseMsg)
	}

	connectionsLock.Unlock()
}
Beispiel #3
0
// Writes our initial capabilities message to the underlying connection.
func (b *BaseConn) writeCapabilities() error {

	capMsg := new(baseproto.Capabilities)

	msg := new(baseproto.Message)
	msg.MsgType = new(uint32)
	*msg.MsgType = 1

	var err error
	if msg.Content, err = proto.Marshal(capMsg); err != nil {
		return err
	}

	return b.writeMsg(msg)
}
Beispiel #4
0
// Serialises the given protobuf message as the content of a new message,
// with the given message type, and sends that message on the connection,
// via Send(). Closes the connection if msg won't serialise.
// Convenience method.
func (b *BaseConn) SendProto(msgType uint32, msg proto.Message) bool {

	content, err := proto.Marshal(msg)
	if err != nil {
		log.Print("shared/connect: error marshalling msg ", err)
		b.Close()
		return false
	}

	baseMsg := new(baseproto.Message)
	baseMsg.MsgType = new(uint32)
	*baseMsg.MsgType = msgType
	baseMsg.Content = content

	return b.Send(baseMsg)
}
Beispiel #5
0
func handlePosition(f *followConn, content []byte) {
	store.StartTransaction()
	defer store.EndTransaction()
	f.lock.Lock()
	defer f.lock.Unlock()

	if f.closed {
		return
	}

	var msg fproto.Position
	if err := proto.Unmarshal(content, &msg); err != nil {
		f.Close()
		return
	}

	if config.IsCore() && f.node <= 0x2000 {
		store.SetNodeFirstUnapplied(f.node, *msg.FirstUnapplied)
	}

	if store.Degraded() && *msg.Degraded {
		f.Close()
		return
	}

	start := store.InstructionStart()
	if *msg.FirstUnapplied < start {

		f.sendingBurst = true
		burstMsg := new(baseproto.Message)
		burstMsg.MsgType = new(uint32)
		burstMsg.Content = []byte{}
		*burstMsg.MsgType = 3
		f.conn.Send(burstMsg)

		go sendBurst(f)

		return

	} else if *msg.FirstUnapplied <= store.InstructionFirstUnapplied() &&
		*msg.Degraded {

		f.sendingBurst = true
		burstMsg := new(baseproto.Message)
		burstMsg.MsgType = new(uint32)
		*burstMsg.MsgType = 3
		f.conn.Send(burstMsg)

		go sendBurst(f)

		return

	} else if *msg.Degraded {
		f.Close()
		return
	}

	// Send all chosen instructions above the first unapplied point.
	instructions := store.InstructionSlots()
	relativeSlot := int(*msg.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.
		sendInstructionData(f, slot, slotValues[0].ChangeRequest())
	}
}