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) } } }
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 } } }