コード例 #1
0
ファイル: tap_feed.go プロジェクト: jchris/indexing
// Internal goroutine that reads from the socket and writes events to
// the channel
func (mc *Client) runFeed(ch chan TapEvent, feed *TapFeed) {
	defer close(ch)
	var headerBuf [transport.HDR_LEN]byte
loop:
	for {
		// Read the next request from the server.
		//
		//  (Can't call mc.Receive() because it reads a
		//  _response_ not a request.)
		var pkt transport.MCRequest
		n, err := pkt.Receive(mc.conn, headerBuf[:])
		if TapRecvHook != nil {
			TapRecvHook(&pkt, n, err)
		}

		if err != nil {
			if err != io.EOF {
				feed.Error = err
			}
			break loop
		}

		//logging.Warnf("** TapFeed received %#v : %q", pkt, pkt.Body)

		if pkt.Opcode == transport.TAP_CONNECT {
			// This is not an event from the server; it's
			// an error response to my connect request.
			feed.Error = fmt.Errorf("tap connection failed: %s", pkt.Body)
			break loop
		}

		event := makeTapEvent(pkt)
		if event != nil {
			if event.Opcode == tapEndStream {
				break loop
			}

			select {
			case ch <- *event:
			case <-feed.closer:
				break loop
			}
		}

		if len(pkt.Extras) >= 4 {
			reqFlags := binary.BigEndian.Uint16(pkt.Extras[2:])
			if reqFlags&transport.TAP_ACK != 0 {
				if _, err := mc.sendAck(&pkt); err != nil {
					feed.Error = err
					break loop
				}
			}
		}
	}
	if err := mc.Close(); err != nil {
		logging.Warnf("Error closing memcached client:  %v", err)
	}
}
コード例 #2
0
ファイル: dcp_feed.go プロジェクト: jchris/indexing
// receive loop
func (feed *DcpFeed) doReceive(rcvch chan []interface{}, conn *Client) {
	defer close(rcvch)

	var headerBuf [transport.HDR_LEN]byte
	var duration time.Duration
	var start time.Time
	var blocked bool

	epoc := time.Now()
	tick := time.Tick(time.Minute * 5) // log every 5 minutes.
	for {
		pkt := transport.MCRequest{} // always a new instance.
		bytes, err := pkt.Receive(conn.conn, headerBuf[:])
		if err != nil && err == io.EOF {
			logging.Infof("%v EOF received\n", feed.logPrefix)
			break

		} else if feed.isClosed() {
			logging.Infof("%v doReceive(): connection closed\n", feed.logPrefix)
			break

		} else if err != nil {
			logging.Errorf("%v doReceive(): %v\n", feed.logPrefix, err)
			break
		}
		logging.Tracef("%v packet received %#v", feed.logPrefix, pkt)
		if len(rcvch) == cap(rcvch) {
			start, blocked = time.Now(), true
		}
		rcvch <- []interface{}{&pkt, bytes}
		if blocked {
			duration += time.Since(start)
			blocked = false
			select {
			case <-tick:
				percent := float64(duration) / float64(time.Since(epoc))
				fmsg := "%v DCP-socket -> projector %f%% blocked"
				logging.Infof(fmsg, feed.logPrefix, percent)
			default:
			}
		}
	}
}