code: func (mc *Client) runFeed(ch chan TapEvent, feed *TapFeed) {
  	defer close(ch)
  	var headerBuf [gomemcached.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 gomemcached.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
  		}
  
  		//log.Printf("** TapFeed received %#v : %q", pkt, pkt.Body)
  
  		if pkt.Opcode == gomemcached.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&gomemcached.TAP_ACK != 0 {
  				if _, err := mc.sendAck(&pkt); err != nil {
  					feed.Error = err
  					break loop
  				}
  			}
  		}
  	}
  	if err := mc.Close(); err != nil {
  		log.Printf("Error closing memcached client:  %v", err)
  	}
  }
docs: // Internal goroutine that reads from the socket and writes events to
  // the channel