Beispiel #1
0
func (w *Worker) readLoop(c *nsqConn) {
	for {
		if atomic.LoadInt32(&c.stopFlag) == 1 || atomic.LoadInt32(&c.stopFlag) == 1 {
			goto exit
		}

		//TODO FIXME should listen on exist, need wait for timeout
		frameType, data, err := c.readUnpackedResponse()
		if err != nil {
			handleError(w, c, fmt.Sprintf("[%s] error (%s) reading response %d %s", c, err.Error(), frameType, data))
			continue
		}

		switch frameType {
		case FrameTypeMessage:
			msg, err := broker.DecodeMessage(data)
			// msg.cmdChan = c.cmdChan
			// msg.responseChan = c.finishedMessages

			if err != nil {
				handleError(w, c, fmt.Sprintf("[%s] error (%s) reading response %d %s", c, err.Error(), frameType, data))
				continue
			}
			log.Printf("INFO: [%s] FrameTypeMessage receive  %s - %s", c, msg.Id, msg.Body)

			// remain := atomic.AddInt64(&c.rdyCount, -1)
			// atomic.AddInt64(&q.totalRdyCount, -1)
			// atomic.AddUint64(&c.messagesReceived, 1)
			// atomic.AddUint64(&q.MessagesReceived, 1)
			// atomic.AddInt64(&c.messagesInFlight, 1)
			// atomic.AddInt64(&q.messagesInFlight, 1)
			// atomic.StoreInt64(&c.lastMsgTimestamp, time.Now().UnixNano())

			// if q.VerboseLogging {
			// 	log.Printf("[%s] (remain %d) FrameTypeMessage: %s - %s",
			// 		c, remain, msg.Id, msg.Body)
			// }

			// q.incomingMessages <- msg
			// c.rdyChan <- c
		case FrameTypeResponse:
			switch {
			case bytes.Equal(data, []byte("CLOSE_WAIT")):
				// server is ready for us to close (it ack'd our StartClose)
				// we can assume we will not receive any more messages over this channel
				// (but we can still write back responses)
				log.Printf("[%s] received ACK from nsqd - now in CLOSE_WAIT", c)
				atomic.StoreInt32(&c.stopFlag, 1)
			case bytes.Equal(data, []byte("H")):
				// var buf bytes.Buffer
				// err := c.sendCommand(&buf, Nop())
				// if err != nil {
				// 	handleError(q, c, fmt.Sprintf("[%s] error sending NOP - %s",
				// 		c, err.Error()))
				// 	goto exit
				// }
				log.Printf("[%s] heartbeat received", c)
			}
		case FrameTypeAck:
			log.Printf("[%s] ack receive %s", c, data)
			params := bytes.Split(data, separatorBytes)
			ackType, err := strconv.ParseInt(string(params[0]), 10, 64)
			clientId, err := strconv.ParseInt(string(params[1]), 10, 64)
			msgId, err := strconv.ParseInt(string(params[1]), 10, 64)
			if err != nil {
				log.Printf("ERROR: parse msgId error %s", err)
				break
			}

			if ackType != int64(ACK_SUCCESS) {
				model.SaveOfflineMessage(fmt.Sprintf("%d", clientId), msgId)
				model.IncrMsgErrCount(msgId, 1)
				model.IncrClientErrCount(clientId, 1)
			} else {
				model.IncrMsgOKCount(msgId, 1)
				model.IncrClientOKCount(clientId, 1)
			}

		case FrameTypeError:
			log.Printf("[%s] error from nsqd %s", c, data)
		default:
			log.Printf("[%s] unknown message type %d", c, frameType)
		}
	}

exit:
	c.wg.Done()
	log.Printf("[%s] readLoop exiting", c)
}
Beispiel #2
0
func (c *Client) readLoop() {
	rbuf := bufio.NewReader(c.Conn)
	for {
		if atomic.LoadInt32(&c.stopFlag) == 1 {
			goto exit
		}

		resp, err := ReadResponse(rbuf)
		frameType, data, err := UnpackResponse(resp)

		if err != nil {
			//handleError(q, c, fmt.Sprintf("[%s] error (%s) reading response %d %s", c, err.Error(), frameType, data))
			continue
		}

		switch frameType {
		case FrameTypeMessage:
			msg, err := broker.DecodeMessage(data)
			// msg.cmdChan = c.cmdChan
			// msg.responseChan = c.finishedMessages
			log.Printf("INFO: [%s] FrameTypeMessage receive  %s - %s", c.Conn.RemoteAddr(), msg.Id, msg.Body)
			if err != nil {
				// handleError(q, c, fmt.Sprintf("[%s] error (%s) decoding message %s",
				// 	c, err.Error(), data))
				continue
			}

			// remain := atomic.AddInt64(&c.rdyCount, -1)
			// atomic.AddInt64(&q.totalRdyCount, -1)
			// atomic.AddUint64(&c.messagesReceived, 1)
			// atomic.AddUint64(&q.MessagesReceived, 1)
			// atomic.AddInt64(&c.messagesInFlight, 1)
			// atomic.AddInt64(&q.messagesInFlight, 1)
			// atomic.StoreInt64(&c.lastMsgTimestamp, time.Now().UnixNano())

			// if q.VerboseLogging {
			// 	log.Printf("[%s] (remain %d) FrameTypeMessage: %s - %s",
			// 		c, remain, msg.Id, msg.Body)
			// }

			// q.incomingMessages <- msg
			// c.rdyChan <- c
		case FrameTypeResponse:
			switch {
			case bytes.Equal(data, []byte("CLOSE_WAIT")):
				// server is ready for us to close (it ack'd our StartClose)
				// we can assume we will not receive any more messages over this channel
				// (but we can still write back responses)
				log.Printf("[%s] received ACK from nsqd - now in CLOSE_WAIT", c)
				atomic.StoreInt32(&c.stopFlag, 1)
			case bytes.Equal(data, []byte("H")):
				// var buf bytes.Buffer
				log.Printf("[%s] heartbeat received", c)
				// err := c.sendCommand(&buf, Nop())
				// if err != nil {
				// 	handleError(q, c, fmt.Sprintf("[%s] error sending NOP - %s",
				// 		c, err.Error()))
				// 	goto exit
				// }
			default:
				log.Printf("FrameTypeResponse receive %s", string(data))
			}
		case FrameTypeError:
			log.Printf("[%s] error from nsqd %s", c, data)
		default:
			log.Printf("[%s] unknown message type %d", c, frameType)
		}
	}

exit:
	c.wg.Done()
	log.Printf("[%s] readLoop exiting", c)
}