func (rcv *TCP) handlePickle(conn net.Conn) { atomic.AddInt32(&rcv.active, 1) defer atomic.AddInt32(&rcv.active, -1) defer conn.Close() reader := bufio.NewReader(conn) var msgLen uint32 var err error for { conn.SetReadDeadline(time.Now().Add(2 * time.Minute)) // Read prepended length err = binary.Read(reader, binary.BigEndian, &msgLen) if err != nil { if err == io.EOF { return } atomic.AddUint32(&rcv.errors, 1) logrus.Warningf("[pickle] Can't read message length: %s", err.Error()) return } // Allocate a byte array of the expected length data := make([]byte, msgLen) // Read remainder of pickle packet into byte array if err = binary.Read(reader, binary.BigEndian, data); err != nil { atomic.AddUint32(&rcv.errors, 1) logrus.Warningf("[pickle] Can't read message body: %s", err.Error()) return } msgs, err := points.ParsePickle(data) if err != nil { atomic.AddUint32(&rcv.errors, 1) logrus.Infof("[pickle] Can't unpickle message: %s", err.Error()) logrus.Debugf("[pickle] Bad message: %#v", string(data)) return } for _, msg := range msgs { atomic.AddUint32(&rcv.metricsReceived, uint32(len(msg.Data))) rcv.out <- msg } } }
func (rcv *TCP) handlePickle(conn net.Conn) { defer func() { if r := recover(); r != nil { logrus.Errorf("[pickle] Unknown error recovered: %s", r) } }() atomic.AddInt32(&rcv.active, 1) defer atomic.AddInt32(&rcv.active, -1) defer conn.Close() reader := bufio.NewReader(conn) var msgLen uint32 var err error finished := make(chan bool) defer close(finished) rcv.Go(func(exit chan bool) { select { case <-finished: return case <-exit: conn.Close() return } }) maxMessageSize := rcv.maxPickleMessageSize for { conn.SetReadDeadline(time.Now().Add(2 * time.Minute)) // Read prepended length err = binary.Read(reader, binary.BigEndian, &msgLen) if err != nil { if err == io.EOF { return } atomic.AddUint32(&rcv.errors, 1) logrus.Warningf("[pickle] Can't read message length: %s", err.Error()) return } if msgLen > maxMessageSize { atomic.AddUint32(&rcv.errors, 1) logrus.Warningf("[pickle] Bad message size: %d", msgLen) return } // Allocate a byte array of the expected length data := make([]byte, msgLen) // Read remainder of pickle packet into byte array if err = binary.Read(reader, binary.BigEndian, data); err != nil { atomic.AddUint32(&rcv.errors, 1) logrus.Warningf("[pickle] Can't read message body: %s", err.Error()) return } msgs, err := points.ParsePickle(data) if err != nil { atomic.AddUint32(&rcv.errors, 1) logrus.Infof("[pickle] Can't unpickle message: %s", err.Error()) logrus.Debugf("[pickle] Bad message: %#v", string(data)) return } for _, msg := range msgs { atomic.AddUint32(&rcv.metricsReceived, uint32(len(msg.Data))) rcv.out <- msg } } }