예제 #1
0
func (srv *Server) handleClient(c net.Conn) {
	clientID := time.Now().UnixNano()
	srv.mu.Lock()
	if _, ok := srv.clients[clientID]; ok {
		panic("Programmer error: Duplicate clientID generated.")
	}
	srv.clients[clientID] = c
	srv.mu.Unlock()

	defer func() {
		srv.mu.Lock()
		delete(srv.clients, clientID)
		srv.mu.Unlock()
	}()

	for {
		kind, b, err := proto.ReadReq(c)
		if err != nil {
			return
		}
		srv.mu.RLock()
		fn, ok := srv.handlers[kind]
		if !ok {
			fn, ok = srv.handlers[AnyRequest]
		}
		srv.mu.RUnlock()

		if !ok {
			panic(fmt.Sprintf("no handler for %d", kind))
		}

		var request Serializable

		switch kind {
		case FetchRequest:
			request, err = proto.ReadFetchReq(bytes.NewBuffer(b))
		case ProduceRequest:
			request, err = proto.ReadProduceReq(bytes.NewBuffer(b))
		case OffsetRequest:
			request, err = proto.ReadOffsetReq(bytes.NewBuffer(b))
		case MetadataRequest:
			request, err = proto.ReadMetadataReq(bytes.NewBuffer(b))
		case ConsumerMetadataRequest:
			request, err = proto.ReadConsumerMetadataReq(bytes.NewBuffer(b))
		case OffsetCommitRequest:
			request, err = proto.ReadOffsetCommitReq(bytes.NewBuffer(b))
		case OffsetFetchRequest:
			request, err = proto.ReadOffsetFetchReq(bytes.NewBuffer(b))
		}

		if err != nil {
			panic(fmt.Sprintf("could not read message %d: %s", kind, err))
		}

		response := fn(request)
		if response != nil {
			b, err := response.Bytes()
			if err != nil {
				panic(fmt.Sprintf("cannot serialize %T: %s", response, err))
			}
			c.Write(b)
		}
	}
}
예제 #2
0
파일: server.go 프로젝트: dropbox/kafka
func (s *Server) handleClient(nodeID int32, conn net.Conn) {
	defer func() {
		_ = conn.Close()
	}()

	for {
		kind, b, err := proto.ReadReq(conn)
		if err != nil {
			if err != io.EOF {
				log.Errorf("client read error: %s", err)
			}
			return
		}

		var resp response

		for _, middleware := range s.middlewares {
			resp = middleware(nodeID, kind, b)
			if resp != nil {
				break
			}
		}

		if resp == nil {
			switch kind {
			case proto.ProduceReqKind:
				req, err := proto.ReadProduceReq(bytes.NewBuffer(b))
				if err != nil {
					log.Errorf("cannot parse produce request: %s\n%s", err, b)
					return
				}
				resp = s.handleProduceRequest(nodeID, conn, req)
			case proto.FetchReqKind:
				req, err := proto.ReadFetchReq(bytes.NewBuffer(b))
				if err != nil {
					log.Errorf("cannot parse fetch request: %s\n%s", err, b)
					return
				}
				resp = s.handleFetchRequest(nodeID, conn, req)
			case proto.OffsetReqKind:
				req, err := proto.ReadOffsetReq(bytes.NewBuffer(b))
				if err != nil {
					log.Errorf("cannot parse offset request: %s\n%s", err, b)
					return
				}
				resp = s.handleOffsetRequest(nodeID, conn, req)
			case proto.MetadataReqKind:
				req, err := proto.ReadMetadataReq(bytes.NewBuffer(b))
				if err != nil {
					log.Errorf("cannot parse metadata request: %s\n%s", err, b)
					return
				}
				resp = s.handleMetadataRequest(nodeID, conn, req)
			case proto.OffsetCommitReqKind:
				req, err := proto.ReadOffsetCommitReq(bytes.NewBuffer(b))
				if err != nil {
					log.Errorf("cannot parse offset commit request: %s\n%s", err, b)
					return
				}
				resp = s.handleOffsetCommitRequest(nodeID, conn, req)
			case proto.OffsetFetchReqKind:
				req, err := proto.ReadOffsetFetchReq(bytes.NewBuffer(b))
				if err != nil {
					log.Errorf("cannot parse offset fetch request: %s\n%s", err, b)
					return
				}
				resp = s.handleOffsetFetchRequest(nodeID, conn, req)
			case proto.ConsumerMetadataReqKind:
				req, err := proto.ReadConsumerMetadataReq(bytes.NewBuffer(b))
				if err != nil {
					log.Errorf("cannot parse consumer metadata request: %s\n%s", err, b)
					return
				}
				resp = s.handleConsumerMetadataRequest(nodeID, conn, req)
			default:
				log.Errorf("unknown request: %d\n%s", kind, b)
				return
			}
		}

		if resp == nil {
			log.Errorf("no response for %d", kind)
			return
		}
		b, err = resp.Bytes()
		if err != nil {
			log.Errorf("cannot serialize %T response: %s", resp, err)
		}
		if _, err := conn.Write(b); err != nil {
			log.Errorf("cannot write %T response: %s", resp, err)
			return
		}
	}
}