Long Polling ============ Long Polling (длинный опрос) - простой способ получения обновлений от сервера. Бот отправляет запрос к API и, если новых событий нет, сервер держит соединение открытым некоторое время (timeout), ожидая их появления. Этот метод подходит для разработки и простых ботов, так как не требует публичного IP-адреса или настройки SSL-сертификатов (в отличие от Webhook). .. warning:: Если вы запустите несколько процессов бота с одним токеном, использующих Long Polling, **каждый из них будет получать копии одних и тех же обновлений**. Это особенность работы API Max.ru: сервер не распределяет нагрузку между подключенными клиентами Long Polling, а рассылает события всем активным слушателям. В результате ваши боты будут дублировать ответы пользователям. .. note:: Для масштабирования (запуска нескольких экземпляров бота) или работы под высокой нагрузкой **необходимо использовать Webhook**. В этом случае сервер Max.ru будет отправлять каждое обновление только один раз на ваш endpoint, и вы сможете распределять нагрузку между воркерами (например, с помощью Nginx или Kubernetes). Использование ------------- Для запуска поллинга используется класс :class:`~maxo.transport.long_polling.LongPolling`. .. code-block:: python import os from maxo import Bot, Dispatcher from maxo.transport.long_polling import LongPolling bot = Bot(token=os.environ["TOKEN"]) dispatcher = Dispatcher() # ... регистрация хендлеров ... if __name__ == "__main__": # Запуск поллинга LongPolling(dispatcher).run(bot) Если вы уже находитесь в асинхронном контексте, используйте метод ``start`` вместо ``run``: .. code-block:: python from maxo.transport.long_polling import LongPolling await LongPolling(dispatcher).start(bot) Параметры запуска ----------------- Метод ``run`` принимает несколько аргументов для настройки поллинга: - ``timeout`` (int, по умолчанию 30) - время в секундах, которое сервер будет держать соединение открытым, ожидая новых событий. Чем больше значение, тем меньше «пустых» запросов делает бот. - ``limit`` (int, по умолчанию 100) - максимальное количество обновлений, которое сервер вернет за один запрос. - ``drop_pending_updates`` (bool, по умолчанию False) - если ``True``, бот при запуске пропустит все обновления, которые накопились, пока он был выключен. Полезно при разработке. - ``types`` (list[str], опционально) - список типов обновлений, которые вы хотите получать. Если не указано, **maxo** автоматически определит этот список на основе зарегистрированных обработчиков. .. code-block:: python from maxo.transport.long_polling import LongPolling LongPolling(dispatcher).run( bot, timeout=60, drop_pending_updates=True, ) Пропуск старых обновлений ------------------------- Иногда при перезапуске бота нужно игнорировать все, что накопилось за время простоя (например, чтобы бот не начал отвечать на сообщения часовой давности). .. code-block:: python from maxo.transport.long_polling import LongPolling LongPolling(dispatcher).run(bot, drop_pending_updates=True) Автоматическая обработка ошибок ------------------------------- Встроенный поллер в **maxo** устойчив к сбоям сети. Если запрос к API завершится ошибкой (например, проблемы с интернетом или сервером), поллер не упадет, а: 1. Залогирует ошибку. 2. Подождет некоторое время (используя стратегию Exponential Backoff). 3. Повторит запрос. Это гарантирует, что ваш бот автоматически восстановит работу при возобновлении связи. Конкурентная обработка ---------------------- Поллер использует ``asyncio.TaskGroup`` для обработки обновлений. Это означает, что новые обновления могут обрабатываться параллельно, не блокируя друг друга.