コード例 #1
0
ファイル: reader.go プロジェクト: ChongFeng/beats
func (r *reader) readEvents(in io.Reader, events []interface{}) ([]interface{}, error) {
	for len(events) < cap(events) {
		var hdr [2]byte
		if err := readFull(in, hdr[:]); err != nil {
			return nil, err
		}

		if hdr[0] != protocol.CodeVersion {
			log.Println("Event protocol version error")
			return nil, ErrProtocolError
		}

		switch hdr[1] {
		case protocol.CodeDataFrame:
			event, err := r.readEvent(in)
			if err != nil {
				log.Printf("failed to read json event with: %v\n", err)
				return nil, err
			}
			events = append(events, event)
		case protocol.CodeCompressed:
			readEvents, err := r.readCompressed(in, events)
			if err != nil {
				return nil, err
			}
			events = readEvents
		default:
			log.Printf("Unknown frame type: %v", hdr[1])
			return nil, ErrProtocolError
		}
	}
	return events, nil
}
コード例 #2
0
ファイル: handler.go プロジェクト: ChongFeng/beats
func (h *defaultHandler) handle() error {
	log.Printf("Start client handler")
	defer log.Printf("client handler stopped")
	defer h.Stop()

	for {
		// 1. read data into batch
		b, err := h.reader.ReadBatch()
		if err != nil {
			return err
		}

		// read next batch if empty batch has been received
		if b == nil {
			continue
		}

		// 2. push batch to ACK queue
		select {
		case <-h.signal:
			return nil
		case h.ch <- b:
		}

		// 3. push batch to server receive queue:
		if err := h.cb.OnEvents(b); err != nil {
			return nil
		}
	}
}
コード例 #3
0
ファイル: reader.go プロジェクト: ChongFeng/beats
func (r *reader) ReadBatch() (*lj.Batch, error) {
	// 1. read window size
	var win [6]byte
	_ = r.conn.SetReadDeadline(time.Time{}) // wait for next batch without timeout
	if err := readFull(r.in, win[:]); err != nil {
		return nil, err
	}

	if win[0] != protocol.CodeVersion && win[1] != protocol.CodeWindowSize {
		log.Printf("Expected window from. Received %v", win[0:1])
		return nil, ErrProtocolError
	}

	count := int(binary.BigEndian.Uint32(win[2:]))
	if count == 0 {
		return nil, nil
	}

	if err := r.conn.SetReadDeadline(time.Now().Add(r.timeout)); err != nil {
		return nil, err
	}

	events, err := r.readEvents(r.in, make([]interface{}, 0, count))
	if events == nil || err != nil {
		log.Printf("readEvents failed with: %v", err)
		return nil, err
	}

	return lj.NewBatch(events), nil
}
コード例 #4
0
ファイル: server.go プロジェクト: ChongFeng/beats
func (s *Server) startConnHandler(client net.Conn) {
	var wgStart sync.WaitGroup

	h, err := s.opts.Handler(newChanCallback(s.sig.Sig(), s.ch), client)
	if err != nil {
		log.Printf("Failed to initialize client handler: %v", h)
		return
	}

	s.sig.Add(1)
	wgStart.Add(1)
	stopped := make(chan struct{}, 1)
	go func() {
		defer s.sig.Done()
		defer close(stopped) // signal handler loop stopped

		wgStart.Done()
		h.Run()
	}()

	wgStart.Wait()
	go func() {
		select {
		case <-s.sig.Sig():
			// server shutdown
			h.Stop()

		case <-stopped:
			// handler loop stopped
		}
	}()
}
コード例 #5
0
ファイル: reader.go プロジェクト: ChongFeng/beats
func (r *reader) readCompressed(in io.Reader, events []interface{}) ([]interface{}, error) {
	var hdr [4]byte
	if err := readFull(in, hdr[:]); err != nil {
		return nil, err
	}

	payloadSz := binary.BigEndian.Uint32(hdr[:])
	limit := io.LimitReader(in, int64(payloadSz))
	reader, err := zlib.NewReader(limit)
	if err != nil {
		log.Printf("Failed to initialized zlib reader %v\n", err)
		return nil, err
	}

	events, err = r.readEvents(reader, events)
	if err != nil {
		_ = reader.Close()
		return nil, err
	}
	if err := reader.Close(); err != nil {
		return nil, err
	}

	// consume final bytes from limit reader
	for {
		var tmp [16]byte
		if _, err := limit.Read(tmp[:]); err != nil {
			if err != io.EOF {
				return nil, err
			}
			break
		}
	}
	return events, nil
}
コード例 #6
0
ファイル: server.go プロジェクト: ChongFeng/beats
func (s *Server) run() {
	defer s.sig.Done()

	for {
		client, err := s.listener.Accept()
		if err != nil {
			break
		}

		log.Printf("New connection from %v", client.RemoteAddr())
		s.startConnHandler(client)
	}
}
コード例 #7
0
ファイル: server.go プロジェクト: ChongFeng/beats
func newServer(l net.Listener, opts ...Option) (Server, error) {
	cfg, err := applyOptions(opts)
	if err != nil {
		return nil, err
	}

	var servers []func(net.Listener) (Server, byte, error)

	log.Printf("Server config: %#v", cfg)

	if cfg.v1 {
		servers = append(servers, func(l net.Listener) (Server, byte, error) {
			s, err := v1.NewWithListener(l,
				v1.Timeout(cfg.timeout),
				v1.Channel(cfg.ch),
				v1.TLS(cfg.tls))
			return s, '1', err
		})
	}
	if cfg.v2 {
		servers = append(servers, func(l net.Listener) (Server, byte, error) {
			s, err := v2.NewWithListener(l,
				v2.Keepalive(cfg.keepalive),
				v2.Timeout(cfg.timeout),
				v2.Channel(cfg.ch),
				v2.TLS(cfg.tls),
				v2.JSONDecoder(cfg.decoder))
			return s, '2', err
		})
	}

	if len(servers) == 0 {
		return nil, ErrNoVersionEnabled
	}
	if len(servers) == 1 {
		s, _, err := servers[0](l)
		return s, err
	}

	ownCH := false
	if cfg.ch == nil {
		ownCH = true
		cfg.ch = make(chan *lj.Batch, 128)
	}

	mux := make([]muxServer, len(servers))
	for i, mk := range servers {
		muxL := newMuxListener(l)
		log.Printf("mk: %v", i)
		s, b, err := mk(muxL)
		if err != nil {
			return nil, err
		}

		mux[i] = muxServer{
			mux:    b,
			l:      muxL,
			server: s,
		}
	}

	s := &server{
		ch:          cfg.ch,
		ownCH:       ownCH,
		netListener: l,
		mux:         mux,
		done:        make(chan struct{}),
	}
	s.wg.Add(1)
	go s.run()

	return s, nil
}