Repository: gradio-app/gradio
File: gradio/queueing.py (Python)

Code before:
        self.process_time_per_fn: defaultdict[BlockFunction, ProcessTime] = defaultdict(
            ProcessTime
        )
        self.live_updates = live_updates
        self.sleep_when_free = 0.05
        self.progress_update_sleep_when_free = 0.1
        self.max_size = max_size
        self.blocks = blocks
        self._asyncio_tasks: list[asyncio.Task] = []
        self.default_concurrency_limit = self._resolve_concurrency_limit(
            default_concurrency_limit
        )
        self.event_analytics: dict[str, dict[str, float | str | None]] = {}
        self.cached_event_analytics_summary = {"functions": {}}
        self.n_events_since_last_analytics_cache = 0
        self.ANAYLTICS_CACHE_FREQUENCY = int(
            os.getenv("GRADIO_ANALYTICS_CACHE_FREQUENCY", "10")
        )

    def compute_analytics_summary(self, event_analytics):
        if (
            len(event_analytics) - self.n_events_since_last_analytics_cache
            >= self.ANAYLTICS_CACHE_FREQUENCY
        ):
            df = pd.DataFrame(list(event_analytics.values()))
            self.n_events_since_last_analytics_cache = len(event_analytics)
            grouped = df.groupby("function")
            metrics = {"functions": {}}
            for fn_name, fn_df in grouped:
                status = fn_df["status"].values
                success = np.sum(status == "success")
                failure = np.sum(status == "failure")
                total = success + failure
                success_rate = success / total if total > 0 else None
                percentiles = np.percentile(fn_df["process_time"].values, [50, 90, 99])  # type: ignore
                metrics["functions"][fn_name] = {
                    "success_rate": success_rate,
                    "process_time_percentiles": {
                        "50th": percentiles[0],  # type: ignore
                        "90th": percentiles[1],  # type: ignore
                        "99th": percentiles[2],  # type: ignore
                    },
                    "total_requests": fn_df.shape[0],
                }
            self.cached_event_analytics_summary = metrics
        return self.cached_event_analytics_summary

    def start(self):
        self.active_jobs = [None] * self.max_thread_count

        run_coro_in_background(self.start_processing)

Review comment (performance):
This variable name is confusing since it sounds like the number of events since the last analytics cache, but actually, it's the number of events _at the time_ analytics were last cached. I'd suggest `n_events_at_last_cache` or even `event_count_at_last_cache`. 

Code after:
        self.process_time_per_fn: defaultdict[BlockFunction, ProcessTime] = defaultdict(
            ProcessTime
        )
        self.live_updates = live_updates
        self.sleep_when_free = 0.05
        self.progress_update_sleep_when_free = 0.1
        self.max_size = max_size
        self.blocks = blocks
        self._asyncio_tasks: list[asyncio.Task] = []
        self.default_concurrency_limit = self._resolve_concurrency_limit(
            default_concurrency_limit
        )
        self.event_analytics: dict[str, dict[str, float | str | None]] = {}
        self.cached_event_analytics_summary = {"functions": {}}
        self.event_count_at_last_cache = 0
        self.ANAYLTICS_CACHE_FREQUENCY = int(
            os.getenv("GRADIO_ANALYTICS_CACHE_FREQUENCY", "1")
        )

    def compute_analytics_summary(self, event_analytics):
        if (
            len(event_analytics) - self.event_count_at_last_cache
            >= self.ANAYLTICS_CACHE_FREQUENCY
        ):
            with pd.option_context("future.no_silent_downcasting", True):
                df = (
                    pd.DataFrame(list(event_analytics.values()))
                    .fillna(value=np.nan)
                    .infer_objects(copy=False)
                )  # type: ignore
            self.event_count_at_last_cache = len(event_analytics)
            grouped = df.groupby("function")
            metrics = {"functions": {}}
            for fn_name, fn_df in grouped:
                status = fn_df["status"].values
                success = np.sum(status == "success")
                failure = np.sum(status == "failed")
                total = success + failure
                success_rate = success / total if total > 0 else None
                percentiles = np.percentile(fn_df["process_time"].values, [50, 90, 99])  # type: ignore
                metrics["functions"][fn_name] = {
                    "success_rate": success_rate,
                    "process_time_percentiles": {
                        "50th": percentiles[0],  # type: ignore
                        "90th": percentiles[1],  # type: ignore
                        "99th": percentiles[2],  # type: ignore
                    },
                    "total_requests": fn_df.shape[0],
                }
            self.cached_event_analytics_summary = metrics
        return self.cached_event_analytics_summary