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() }
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() }
// 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) }
// 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) }
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()) } }