""" Конфигурация для rate limiting в AnonBot """ import os from dataclasses import dataclass from typing import Optional from dotenv import load_dotenv # Загружаем переменные окружения load_dotenv() @dataclass class RateLimitSettings: """Настройки rate limiting для разных типов сообщений""" # Основные настройки messages_per_second: float = float(os.getenv('RATE_LIMIT_MESSAGES_PER_SECOND', '0.5')) # Максимум 0.5 сообщений в секунду на чат burst_limit: int = int(os.getenv('RATE_LIMIT_BURST_LIMIT', '2')) # Максимум 2 сообщения подряд retry_after_multiplier: float = float(os.getenv('RATE_LIMIT_RETRY_MULTIPLIER', '1.5')) # Множитель для увеличения задержки при retry max_retry_delay: float = float(os.getenv('RATE_LIMIT_MAX_RETRY_DELAY', '30.0')) # Максимальная задержка между попытками max_retries: int = int(os.getenv('RATE_LIMIT_MAX_RETRIES', '3')) # Максимальное количество повторных попыток # Специальные настройки для разных типов сообщений voice_message_delay: float = float(os.getenv('RATE_LIMIT_VOICE_DELAY', '2.0')) # Дополнительная задержка для голосовых сообщений media_message_delay: float = float(os.getenv('RATE_LIMIT_MEDIA_DELAY', '1.5')) # Дополнительная задержка для медиа сообщений text_message_delay: float = float(os.getenv('RATE_LIMIT_TEXT_DELAY', '1.0')) # Дополнительная задержка для текстовых сообщений # Настройки для разных типов чатов private_chat_multiplier: float = float(os.getenv('RATE_LIMIT_PRIVATE_MULTIPLIER', '1.0')) # Множитель для приватных чатов group_chat_multiplier: float = float(os.getenv('RATE_LIMIT_GROUP_MULTIPLIER', '0.8')) # Множитель для групповых чатов channel_multiplier: float = float(os.getenv('RATE_LIMIT_CHANNEL_MULTIPLIER', '0.6')) # Множитель для каналов # Глобальные ограничения global_messages_per_second: float = float(os.getenv('RATE_LIMIT_GLOBAL_MESSAGES_PER_SECOND', '10.0')) # Максимум 10 сообщений в секунду глобально global_burst_limit: int = int(os.getenv('RATE_LIMIT_GLOBAL_BURST_LIMIT', '20')) # Максимум 20 сообщений подряд глобально # Конфигурации для разных сценариев использования # Основаны на официальных лимитах Telegram Bot API: # - 1 сообщение в секунду в личных чатах # - 20 сообщений в минуту в групповых чатах (0.33 в секунду) # - 30 запросов в секунду глобально DEVELOPMENT_CONFIG = RateLimitSettings( messages_per_second=0.8, # Более мягкие ограничения для разработки (80% от лимита) burst_limit=3, # До 3 сообщений подряд retry_after_multiplier=1.2, max_retry_delay=15.0, max_retries=2, voice_message_delay=1.5, media_message_delay=1.2, text_message_delay=1.0 ) PRODUCTION_CONFIG = RateLimitSettings( messages_per_second=0.5, # Консервативные ограничения (50% от лимита) burst_limit=2, # До 2 сообщений подряд retry_after_multiplier=1.5, max_retry_delay=30.0, max_retries=3, voice_message_delay=2.5, # Дополнительная задержка для голосовых media_message_delay=2.0, # Дополнительная задержка для медиа text_message_delay=1.5, # Дополнительная задержка для текста global_messages_per_second=20.0, # 20 из 30 доступных запросов в секунду global_burst_limit=15 # До 15 сообщений подряд глобально ) STRICT_CONFIG = RateLimitSettings( messages_per_second=0.3, # Очень консервативные ограничения (30% от лимита) burst_limit=1, # Только 1 сообщение подряд retry_after_multiplier=2.0, max_retry_delay=60.0, max_retries=5, voice_message_delay=3.0, media_message_delay=2.5, text_message_delay=2.0, global_messages_per_second=10.0, # 10 из 30 доступных запросов в секунду global_burst_limit=8 # До 8 сообщений подряд глобально ) def get_rate_limit_config(environment: str = None) -> RateLimitSettings: """ Получает конфигурацию rate limiting в зависимости от окружения Args: environment: Окружение ('development', 'production', 'strict') Если не указано, берется из переменной окружения RATE_LIMIT_ENV Returns: RateLimitSettings: Конфигурация для указанного окружения """ if environment is None: environment = os.getenv('RATE_LIMIT_ENV', 'production') configs = { "development": DEVELOPMENT_CONFIG, "production": PRODUCTION_CONFIG, "strict": STRICT_CONFIG } return configs.get(environment, PRODUCTION_CONFIG) def get_adaptive_config( current_error_rate: float, base_config: Optional[RateLimitSettings] = None ) -> RateLimitSettings: """ Получает адаптивную конфигурацию на основе текущего уровня ошибок Args: current_error_rate: Текущий уровень ошибок (0.0 - 1.0) base_config: Базовая конфигурация Returns: RateLimitSettings: Адаптированная конфигурация """ if base_config is None: base_config = PRODUCTION_CONFIG # Если уровень ошибок высокий, ужесточаем ограничения if current_error_rate > 0.1: # Более 10% ошибок return RateLimitSettings( messages_per_second=base_config.messages_per_second * 0.5, burst_limit=max(1, base_config.burst_limit - 1), retry_after_multiplier=base_config.retry_after_multiplier * 1.5, max_retry_delay=base_config.max_retry_delay * 1.5, max_retries=base_config.max_retries + 1, voice_message_delay=base_config.voice_message_delay * 1.5, media_message_delay=base_config.media_message_delay * 1.3, text_message_delay=base_config.text_message_delay * 1.2 ) # Если уровень ошибок низкий, можно немного ослабить ограничения elif current_error_rate < 0.01: # Менее 1% ошибок return RateLimitSettings( messages_per_second=base_config.messages_per_second * 1.2, burst_limit=base_config.burst_limit + 1, retry_after_multiplier=base_config.retry_after_multiplier * 0.9, max_retry_delay=base_config.max_retry_delay * 0.8, max_retries=max(1, base_config.max_retries - 1), voice_message_delay=base_config.voice_message_delay * 0.8, media_message_delay=base_config.media_message_delay * 0.9, text_message_delay=base_config.text_message_delay * 0.9 ) # Возвращаем базовую конфигурацию return base_config