Расширяемость¶
Эта страница описывает архитектурный подход QTasks к расширяемости: за счёт каких механизмов система адаптируется под новые сценарии, масштабируется и интегрируется с внешними библиотеками и фреймворками.
Расширяемость в QTasks определяется не количеством настроек, а структурой архитектуры: набором компонентов, их контрактами и возможностью внедрения дополнительного поведения через плагины.
Базовый принцип расширяемости¶
QTasks изначально спроектирован так, чтобы расширение происходило через композицию, а не через модификацию.
Основные факторы расширяемости:
- замена или добавление компонентов;
- использование плагинов;
- соблюдение контрактов абстрактных классов;
- передача данных через схемы.
Настройки играют вторичную роль и не являются основным механизмом масштабирования или интеграции.
Масштабирование через компоненты¶
Компоненты QTasks по умолчанию ориентированы на горизонтальное масштабирование.
Это означает, что система предполагает:
- дублирование серверных экземпляров приложения;
- совместную работу нескольких воркеров;
- использование общего брокера и хранилища.
Изменение модели масштабирования достигается не через флаги конфигурации, а через:
- замену конкретных реализаций компонентов;
- изменение их поведения с помощью плагинов;
- внедрение собственных стратегий распределения нагрузки.
Таким образом, масштабирование становится архитектурным решением, а не настройкой.
Плагины как механизм расширения¶
Плагины в QTasks используются для внедрения дополнительного поведения в существующие потоки выполнения.
Через плагины можно:
- модифицировать жизненный цикл задач;
- внедрять логирование, метрики и трассировку;
- изменять стратегию выполнения без изменения компонентов;
- добавлять интеграционные слои.
Плагины не нарушают архитектурные инварианты и не требуют изменения контрактов компонентов.
Интеграция с внешними библиотеками¶
QTasks допускает интеграцию с внешними библиотеками и фреймворками с минимальными ограничениями.
Это достигается за счёт:
- отсутствия сигналов и глобальных диспетчеров;
- минимального использования глобальных переменных;
- жёсткого разделения ответственности между компонентами;
- прозрачных потоков выполнения;
- явного управления жизненным циклом.
В результате QTasks может использоваться как фоновая система выполнения задач внутри других приложений, не навязывая им собственную модель управления.
Пример интеграции с FastAPI¶
Ниже приведён архитектурный пример использования QTasks совместно с FastAPI.
Определение задач¶
# tasks.py
from qtasks import AsyncRouter
router = AsyncRouter()
@router.task()
async def example_task(x: int, y: int) -> int:
return x + y
Использование задачи в API¶
# api.py
from fastapi import FastAPI
from .tasks import example_task
app = FastAPI()
@app.get("/")
async def read_root():
task = await example_task.add_task(1, 2, timeout=50)
return {"result": task.returning}
Сервер QTasks¶
# qtasks_app.py
from qtasks.asyncio import QueueTasks
from .tasks import router as tasks_router
app = QueueTasks()
app.include_router(tasks_router)
if __name__ == "__main__":
app.run_forever()
Архитектурный разбор примера¶
В этом сценарии:
- API вызывает задачу напрямую через объект задачи, полученный из роутера;
- вызов происходит через брокер (например, Redis), без прямой связи с сервером QTasks;
- API ожидает результат через
AsyncResult, так как указанtimeout; - сервер QTasks может работать в другом процессе или на другом узле;
- сервер знает о задаче благодаря
include_router, а не за счёт жёсткой связки с API.
Клиенту достаточно передать задачу в брокер — остальная обработка происходит независимо.
Об управлении контекстом и глобальными переменными¶
В приведённом примере используется прямой доступ к задаче через роутер.
Если требуется отказаться от глобальных переменных, задача может быть объявлена
через @app.task. В этом случае:
- ссылка на
appсохраняется внутриAsyncTask; AsyncResultавтоматически связан с нужным экземпляром приложения;- вызов задачи остаётся прозрачным для клиента.
Это подчёркивает, что выбор модели интеграции — архитектурное решение пользователя, а не ограничение QTasks.
Архитектурные инварианты¶
- расширяемость достигается через компоненты и плагины;
- масштабирование является следствием архитектуры, а не конфигурации;
- QTasks не навязывает внешним приложениям свою модель управления;
- интеграции не требуют вмешательства в ядро системы.
Такая модель позволяет использовать QTasks как основу для сложных и нестандартных сценариев без потери управляемости.