Перейти к содержанию

Компоненты: плагинная система

Эта страница описывает архитектуру плагинной системы QTasks на уровне компонентов: как плагины подключаются, где именно они вызываются и каким образом влияют на поток выполнения.

Плагинная система является встроенным механизмом расширения компонентов и не существует отдельно от них. Каждый компонент сам определяет, поддерживает ли он плагины и в каких точках они могут быть вызваны.


Плагины как часть компонента

У каждого основного компонента QTasks существует собственный набор плагинов, доступный через self.plugins.

Плагины:

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

Таким образом, расширение поведения происходит контролируемо и предсказуемо.


PluginMixin и включение плагинной системы

Чтобы компонент мог использовать плагины, он должен унаследовать AsyncPluginMixin или SyncPluginMixin.

Mixin предоставляет:

  • метод _plugin_trigger() — точку вызова плагинов;
  • метод add_plugin() — механизм регистрации плагинов.

Без подключения соответствующего mixin плагинная система для компонента считается отключённой.


Вызов триггеров

Триггеры плагинов вызываются явно внутри логики компонента.

Пример вызова асинхронного триггера:

new_results = await self._plugin_trigger(
    "storage_get_all",
    storage=self,
    results=results,
    return_last=True,
)

Триггер — это не событие «по умолчанию», а архитектурное решение автора компонента. Если триггер не вызван, плагины не выполняются.


Регистрация плагинов

Плагины добавляются через add_plugin().

self.add_plugin(
    AsyncRetryPlugin(),
    trigger_names=["worker_task_error_retry"],
)

add_plugin() принимает:

  • plugin — экземпляр плагина;
  • trigger_names — список имён триггеров.

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

Note

В QueueTasks() метод add_plugin() дополнительно принимает параметр component="", что позволяет добавить плагин не самому QueueTasks, а конкретному компоненту.

Note

Worker передаёт свои плагины в TaskExecutor на этапе сборки задачи.

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


Типы триггеров

С архитектурной точки зрения триггеры делятся на два типа.

Однонаправленные триггеры

Однонаправленный триггер используется для побочных эффектов и не влияет на дальнейшее выполнение кода компонента.

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

Возвращаемые триггеры

Возвращаемый триггер позволяет плагинам изменить данные, участвующие в дальнейшем выполнении.

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

Какие именно параметры могут быть изменены, определяется описанием конкретного триггера.


Параметры вызова триггеров

Каждый вызов _plugin_trigger() имеет следующую логическую структуру параметров:

  • <self> — компонент, инициировавший вызов триггера;
  • [дополнительный компонент] — опционально, если триггер логически связан с другим компонентом;
  • **parameters — словарь параметров, передаваемых плагинам.

Дополнительные параметры управления выполнением:

  • return_last: bool | None = None — вернуть только последний результат, если доступен;
  • safe: bool = True — если True, ошибки плагинов не игнорируются;
  • continue_on_fail: bool — если True, выполнение других плагинов продолжается даже при ошибке.

Ответственность разработчика компонента

Если вы создаёте собственный компонент и хотите поддерживать плагины, вы обязаны:

  • подключить соответствующий PluginMixin;
  • явно расставить вызовы _plugin_trigger() в нужных местах логики.

Если триггеры не добавлены, плагинная система для компонента фактически не существует.

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


Архитектурные инварианты

  • плагины принадлежат компонентам, а не системе в целом;
  • триггеры вызываются только явно;
  • плагины не нарушают контракты компонентов;
  • плагинная система расширяет поведение, не изменяя архитектурных основ.

Плагинная система QTasks обеспечивает управляемое расширение архитектуры без скрытых зависимостей и неявных побочных эффектов.