func (srv *Server) handleClient(c net.Conn) { clientID := time.Now().UnixNano() srv.mu.Lock() 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)) } if _, err := c.Write(b); err != nil { panic(fmt.Sprintf("cannot wirte to client: %s", err)) } } } }
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.Printf("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.Printf("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.Printf("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.Printf("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.Printf("cannot parse metadata request: %s\n%s", err, b) return } resp = s.handleMetadataRequest(nodeID, conn, req) case proto.OffsetCommitReqKind: log.Printf("not implemented: %d\n%s", kind, b) return case proto.OffsetFetchReqKind: log.Printf("not implemented: %d\n%s", kind, b) return case proto.ConsumerMetadataReqKind: log.Printf("not implemented: %d\n%s", kind, b) return default: log.Printf("unknown request: %d\n%s", kind, b) return } } if resp == nil { log.Printf("no response for %d", kind) return } b, err = resp.Bytes() if err != nil { log.Printf("cannot serialize %T response: %s", resp, err) } if _, err := conn.Write(b); err != nil { log.Printf("cannot write %T response: %s", resp, err) return } } }
func (srv *Server) handleClient(c net.Conn) { stop := make(chan struct{}) go func() { select { case <-srv.stop: case <-stop: } _ = c.Close() }() for { kind, b, err := proto.ReadReq(c) if err != nil { close(stop) 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)) } if _, err := c.Write(b); err != nil { panic(fmt.Sprintf("cannot wirte to client: %s", err)) } } } }