from __future__ import annotations import time from collections.abc import Callable from typing import Generic, TypeVar T = TypeVar("T") class PeriodicCollector(Generic[T]): def __init__(self, callback: Callable[[T], None], *, duration: float) -> None: self._duration = duration self._callback = callback self._last_flush_time = time.monotonic() self._total: T | None = None def push(self, value: T) -> None: if self._total is None: self._total = value else: self._total += value # type: ignore if time.monotonic() - self._last_flush_time >= self._duration: self.flush() def flush(self) -> None: if self._total is not None: self._callback(self._total) self._total = None self._last_flush_time = time.monotonic()