Фоновые задачи (Background tasks)

Начиная с версии 0.9.1 фреймворк стал поддерживать запуск фоновых задач для бота.

Фоновая задача — это независимый процесс, выполняющийся параллельно с основным циклом работы бота. Она не привязана к конкретному входящему событию (сообщению, callback, update) и предназначена для выполнения периодических или длительных операций

За запуск фоновых задач отвечает класс PRBackgroundTaskRunner. Внутри каждого бота стоит свой раннер для фоновых задач.

Доступ к ранеру через сам бот

bot.BackgroundTaskRunner

Фоновая задача состоит из двух компонентов.

Важно ID задачи и метаданных должны быть одинаковы

Фоновая задача

Фоновая задача описывается через интерфейс IPRBackgroundTask. Она содержит бизнес-логику, которая выполняется по расписанию и работает совместно с метаданными (IPRBackgroundTaskMetadata).

Доступные методы

  • Id (Guid) — обязательный

    • Уникальный идентификатор задачи.

    • Используется для сопоставления задачи и её метаданных, управления выполнением и логирования.

  • CanExecute() (Task<bool>) — обязательный

    • Метод проверяет, может ли задача быть выполнена в текущий момент.

    • Вызывается перед каждой попыткой запуска задачи.

    • Возврат false означает, что задача будет пропущена до следующего планового запуска.

  • ExecuteAsync(CancellationToken cancellationToken)обязательный

    • Основной метод, выполняющий бизнес-логику задачи.

    • cancellationToken используется для безопасной отмены выполнения задачи.

  • Initialize(PRBotBase bot)необязательный

    • Метод инициализации задачи, вызывается фреймворком перед первым запуском.

    • Позволяет сохранить экземпляр бота, чтобы получать доступ к его сервисам и контексту.

    • Если реализация не требует дополнительных действий при инициализации, можно возвращать Task.CompletedTask.


Примечания

  • Каждая задача должна иметь уникальный Id, чтобы правильно сопоставляться с метаданными.

  • Метод CanExecute позволяет динамически контролировать, запускать задачу или пропускать выполнение.

  • Метод Initialize обычно используется для внедрения зависимостей и получения контекста бота.

  • ExecuteAsync выполняется фреймворком в соответствии с настройками из метаданных (IPRBackgroundTaskMetadata).

Метаданные фоновой задачи

Метаданные фоновой задачи описываются через интерфейс IPRBackgroundTaskMetadata. Они используются для планирования, запуска и контроля выполнения фоновых задач и не содержат бизнес-логику.

Доступные параметры метаданных

  • Id (Guid) — обязательный

    • Уникальный идентификатор фоновой задачи.

    • Используется для сопоставления задачи и её метаданных, а также для управления выполнением (остановка, перезапуск и т.д.).

  • Name (string) — обязательный

    • Уникальное имя фоновой задачи.

    • Применяется для логирования, диагностики и отладки.

  • BotIds (HashSet<long>) — необязательный

    • Идентификаторы ботов, для которых предназначена задача.

    • Используется для разграничения задач при работе через DI.

    • Если коллекция пустая или содержит значение PRConstants.ALL_BOTS_ID, задача применяется ко всем ботам.

  • InitialDelaySeconds (int?) — необязательный

    • Задержка перед первым запуском задачи (в секундах).

    • null, 0 или отрицательное значение — задача запускается немедленно после старта бота.

  • RepeatSeconds (int?) — необязательный

    • Интервал повторного выполнения задачи (в секундах).

    • Минимально допустимый интервал повторения — 1 секунда.

  • MaxRepeatCount (int?) — необязательный

    • Максимальное количество запусков задачи (включая успешные и неуспешные).

    • null или -1 — неограниченное количество запусков.

  • MaxErrorAttempts (int?) — необязательный

    • Максимальное количество попыток выполнения задачи при ошибках.

    • Учитывается первый запуск.

    • null или -1 — без ограничения.

    • Значение 1 означает однократное выполнение без повторных попыток при ошибке.


Примечания

  • Метаданные могут быть заданы:

    • через атрибут PRBackgroundTaskAttribute,

    • через отдельную реализацию IPRBackgroundTaskMetadata,

    • либо непосредственно в коде при инициализации задач.

  • При отсутствии метаданных задача не будет запущена, если они не определены иным способом.

Добавление фоновых задач в бота

Фоновые задачи в PRBot можно добавлять двумя способами: через DI (Dependency Injection) или через билдер.

Через DI

Если вы используете контейнер зависимостей (например, Microsoft.Extensions.DependencyInjection), можно зарегистрировать задачи как сервисы:

Пояснения:

  • Все зарегистрированные сервисы, реализующие IPRBackgroundTask, будут автоматически подхвачены ботом.

  • AddBackgroundTaskMetadata добавляет метаданные, если задача не содержит встроенные атрибуты.

  • Задачи через DI позволяют использовать все преимущества контейнера зависимостей (например, логирование, сервисы, базы данных).

Через билдер

Если вы хотите добавить конкретный экземпляр задачи вручную, можно использовать методы AddBackgroundTask:

Пояснения:

  • Метод AddBackgroundTask(IPRBackgroundTask) требует, чтобы задача либо имела встроенные метаданные (IPRBackgroundTaskMetadata), либо была помечена атрибутом PRBackgroundTaskAttribute.

  • Метод AddBackgroundTask(IPRBackgroundTask, IPRBackgroundTaskMetadata) позволяет отдельно указать метаданные для задачи.

  • Метод AddBackgroundTaskMetadata(IPRBackgroundTaskMetadata) полезен для DI-зависимых задач: сами задачи регистрируются через DI, а метаданные добавляются через билдер.

  • Все задачи, зарегистрированные через билдер, будут подхвачены PRBackgroundTaskRunner и выполнены, указанному в метаданных.

Управление текущими и завершенными задачами

Класс PRBackgroundTaskRunner хранит состояние всех фоновых задач бота и предоставляет доступ к информации о текущих (активных) и завершенных задачах.

1. Текущие задачи

  • Все запущенные задачи хранятся в словаре ActiveTasks.

  • Ключ — Guid задачи, значение — объект IRunningBackgroundTaskData, содержащий:

    • Метаданные задачи (IPRBackgroundTaskMetadata)

    • Статус выполнения (PRTaskStatus)

    • Количество выполнений (ExecutedCount)

    • Количество ошибок (ErrorCount)

    • Токен отмены (CancellationTokenSource)

  • Пример получения всех активных задач:

Завершенные задачи

  • Все задачи, которые завершились (успешно, с ошибкой или отменой), добавляются в коллекцию EndTasks.

  • EndTasks содержит объекты IRunningBackgroundTaskData, где можно узнать:

    • Статус завершения (CompleteStatus) — Success, Failed или Canceled

    • Дата и время начала и окончания (StartDate, EndDate)

    • Общее количество выполнений и ошибок

  1. Примеры использования

Остановка конкретной задачи::

Остановка всех задач:

Last updated