"""Base class for all throttling.""" import asyncio import logging import time from abc import ABC, abstractmethod from typing import TYPE_CHECKING if TYPE_CHECKING: from getstream_connector.client.base import BaseExtendedClient __all__ = ["BaseThrottler"] logger = logging.getLogger(__name__) class BaseThrottler(ABC): """Base class for throttling.""" def __init__(self, delay_threshold: float = 0): """Initialize the throttler. :param delay_threshold: Minimum time to sleep in seconds. If calculated sleep time is less than this threshold process won't sleep. """ if delay_threshold < 0: raise ValueError("scale_factor must be greater or equal than 0") self._delay_threshold = delay_threshold def delay(self, client: "BaseExtendedClient") -> bool: """Sleep for certain amount of seconds. :param client: StreamClient object :return: True if it has actually been delayed, False otherwise """ sleep_time = self._get_sleep_time(client=client) if sleep_time <= self._delay_threshold: return False logger.info(f"Sleeping for {sleep_time:.2f} seconds.") time.sleep(sleep_time) return True async def async_delay(self, client: "BaseExtendedClient") -> bool: """Sleep for certain amount of seconds. Using asyncio version of sleep. :param client: StreamClient object :return: True if it has actually been delayed, False otherwise """ sleep_time = self._get_sleep_time(client=client) if sleep_time <= self._delay_threshold: return False logger.info(f"Sleeping for {sleep_time:.2f} seconds.") await asyncio.sleep(sleep_time) return True @abstractmethod def _get_sleep_time(self, client: "BaseExtendedClient") -> float: """Calculate sleep time in seconds. :param client: StreamClient object """ ...