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

Уникальность QTasks

QTasks — это не просто альтернатива Celery или RQ. Это фреймворк с иным взглядом на архитектуру очередей задач: гибким, модульным и ориентированным на расширение. Ниже представлены ключевые особенности, которые формируют его отличия.


🧬 Компонентная архитектура

  • Все ключевые элементы (Broker, Worker, Storage, GlobalConfig, Starter, TaskExecutor и др.)полностью заменяемы.
  • Компоненты можно переписать под собственную инфраструктуру без изменения ядра.
  • Расширения подключаются через плагины и стартеры.

🆚 Celery: монолитная связка. QTasks: независимые компоненты с plug‑and‑play подходом.


🔁 Поддержка yield в задачах

Позволяет строить поэтапные, потоковые сценарии.

  • Поддержка генераторов в задачах.
  • Обработка результатов yield через generate_handler.
  • Итоговое значение return возвращается как обычный результат задачи.
@app.task(generate_handler=handler)
def task():
    step = yield "INIT"
    return step

🆚 Большинство фреймворков не поддерживает generator‑based задачи.


🧠 Echo и доступ к задаче через self

При включённом echo=True задача превращается в объект Task (Async/Sync), что открывает доступ к инфраструктуре:

  • self.add_task() — создание вложенных задач
  • self.ctx.get_logger() — контекстный логгер
  • self.ctx.cancel() — завершение задачи заранее
  • self.ctx.get_task() — получение другой задачи по UUID

🆚 В других фреймворках задача — простая функция без self‑контекста.


⚙️ Контекст выполнения (ctx)

Контекст задачи предоставляет:

  • UUID задачи
  • доступ к Broker, Storage, GlobalConfig
  • работу с metadata (get_metadata())
  • безопасный sleep (ctx.sleep())
  • отмену задач (cancel())

Это позволяет строить сложные сценарии без глобальных переменных и сторонних синглтонов.


🔗 State и Depends

State

Потокобезопасное хранение промежуточных данных между задачами.

from qtasks.plugins import AsyncState

class MyState(AsyncState):
    pass

@app.task
def sample(state: MyState):
    ...

Depends

Инъекция зависимостей в задачи:

@app.task
def job(data: int, db=Depends(connect_db, scope="worker")):
    return db.save(data)

Scopes включают:

  • task
  • worker
  • broker
  • storage
  • global_config

QTasks автоматически создаёт и завершает зависимости по указанному scope.


🧩 Плагины и стартеры

  • Плагины можно привязывать к любым событиям (триггерам) внутри системы.
  • Можно расширять поведение Worker, Broker, Storage, TaskExecutor.
  • Стартер управляет жизненным циклом компонентов и позволяет внедрять кастомные сценарии потоков.

🆚 Celery требует monkeypatch или глубокую модификацию.


⏱ Таймеры без отдельного сервиса

Встроенный AsyncTimer запускает задачи по расписанию:

  • cron‑логика через apscheduler
  • интеграция с приложением без отдельного процесса типа Celery Beat

🛠 Минимальные зависимости, лёгкий запуск

  • Можно работать без Redis и брокеров — через in‑memory очередь.
  • Запуск:
python main.py
qtasks -A app:app run
  • Простота позволяет использовать QTasks в микросервисах, автоматизации, фриланс‑проектах.

🚀 Производительность

  • 0.6–0.7 сек на задачу с Redis.
  • Асинхронная обработка через PriorityQueue и anyio.Semaphore.
  • Низкие накладные расходы даже на больших объёмах задач.

🧪 Инфраструктура для тестирования

  • SyncTestCase и AsyncTestCase подменяют компоненты для изолированного тестирования.
  • Работает без запуска воркера.
  • Поддержка pytest, unittest, pytest-asyncio.

💡 Подходит для любого уровня разработчика

  • Junior: простота API
  • Middle: плагины, middleware, TaskManager
  • Senior: замена компонентов, управление контекстом, собственные executors
  • Lead: мониторинг, масштабирование, архитектура систем на QTasks

QTasks — это конструктор, который позволяет собирать фреймворк под свои задачи: от маленького скрипта до распределённого сервиса.