Files
ss-tools/docs/scheduler-worker-orthogonal-comparison.md
busya 0cb1f80cd6 feat(git): implement deployment tracking and enhance lifecycle UX
Introduce a deployment recording system to track dashboard versions
across environments and improve the Git management user experience.

- Add `Deployment` model and Alembic migration to persist deployment
  history.
- Implement `GitDeploymentRecorder` and `GitFingerprint` plugins to
  automate deployment logging and content hashing.
- Add `get_deployment_status` API endpoint to retrieve real-time
  environment states.
- Refactor `GitLifecycleHeader` to prioritize Call-to-Action (CTA)
  buttons and improve visual hierarchy.
- Update `GitWorkspacePanel` to emphasize version saving and
  streamline commit workflows.
- Enhance `GitEnvironmentTimeline` with deployment status integration,
  collapsible UI, and improved theme consistency.
- Add auto-navigation logic in `GitManagerModel` to guide users to
  relevant tabs based on recommended actions.
- Clean up obsolete documentation and update i18n strings for
  git visualization features.
2026-07-12 14:57:03 +03:00

17 KiB
Raw Blame History

Ортогональное сравнение: Наш Scheduler + Worker vs Celery и открытые альтернативы

Дата: 2026-07-10
Контекст проекта: superset-tools (FastAPI + Svelte).
Наша реализация: APScheduler (in-process) + кастомный in-process TaskManager/JobLifecycle.

Краткое резюме (TL;DR)

Система Архитектура Брокер Распределённость Интерактивные задачи (AWAITING_*) Реал-тайм UI/логи Операционная сложность Лучше всего для
Наш (APScheduler + TaskManager) In-process (один backend) Нет Только вертикальная Отличная (встроенные) Отличная (WS + Task Center) Низкая Admin tools, интерактивные фоновые задачи, LLM/backup/migration внутри одного приложения
Celery + Beat Producer + Broker + Workers (отдельные процессы) Обязателен (Redis/Rabbit/...) Отличная Сложно (требует кастомизации) Средняя (Flower + кастом) Высокая Высоконагруженные распределённые пайплайны, CPU-bound, высокая отказоустойчивость
APScheduler (standalone) In-process (или с jobstores) Нет Ограниченная Через кастом Кастом Низкая Простые cron-задачи внутри приложения
Huey Лёгкий (Redis/SQLite) Опционально Хорошая Нет Кастом Низкая-средняя Маленькие/средние приложения
RQ Простой Redis Redis Хорошая Нет Кастом Низкая Простые очереди
Dramatiq Современный (Redis/Rabbit) Обязателен Хорошая Нет Кастом Средняя Более простая/надёжная замена Celery
ARQ / Taskiq Async-native (Redis-first) Redis Хорошая Ограничено Кастом Средняя FastAPI + высококонкурентные I/O-задачи
Procrastinate Postgres-native Нет (Postgres) Хорошая Ограничено Кастом Средняя Когда не хочется дополнительный брокер

Наш главный выигрыш: глубокая интеграция с UI, человеческие состояния задач (AWAITING_INPUT, AWAITING_MAPPING), real-time логи через WebSocket и нулевая дополнительная инфраструктура.

Главный проигрыш: нет горизонтального масштабирования и автоматической отказоустойчивости при падении процесса.

Что такое "наш" scheduler и worker (точные факты из кода)

Scheduler

  • Файл: backend/src/core/scheduler.py
  • SchedulerService оборачивает BackgroundScheduler (APScheduler 3.11).
  • Загрузка: load_schedules() очищает все jobs и пересоздаёт из:
    • Backup schedules — из config.environments[].backup_schedule.
    • Translation schedules — из таблицы TranslationSchedule (is_active).
    • Validation policies — динамический cron + ThrottledSchedulerConfigurator (распределение задач внутри окна).
  • Триггеры: CronTrigger.from_crontab(...) + timezone.
  • Мост: AsyncJobRunner (отдельный файл) — run_coroutine_threadsafe + call_later для delayed execution.
  • Нет SQLAlchemyJobStore / persistent jobstore — расписания восстанавливаются из прикладных таблиц и конфига при старте.

Worker / Task Execution

  • TaskManager (фасад) + JobLifecycle + TaskGraph + EventBus.
  • Создание: create_taskasyncio.create_task(_run_task).
  • Выполнение: plugin.execute(...) (async или asyncio.to_thread).
  • Ограничение блокирующих операций: именованные ThreadPoolExecutor (db/file/git) — core/utils/executors.py (ADR-0011).
  • Состояния: PENDING → RUNNING → SUCCESS/FAILED + AWAITING_MAPPING / AWAITING_INPUT.
  • Персистентность: отдельная таблица task_records + task_logs (может быть TASKS_DATABASE_URL = основной или sqlite).
  • Реал-тайм: EventBus (asyncio.Queue) → WS для логов, статуса, событий датасетов.
  • Интерактивность: resume_task_with_password, resolve_task — задачи реально "парятся" и ждут пользователя.
  • Деплой: один контейнер backend (docker-compose.yml). Нет отдельного worker-сервиса.

ADR-0011 явно отвергает multiprocessing workers и брокер в пользу async + bounded executors внутри процесса.

Ортогональные проекции (13 измерений)

1. Architecture & Deployment Model

Наш: Монолитный процесс (API + scheduler + executor).
Celery: Три отдельных роли (app, beat, worker(s)) + брокер.
ARQ/Taskiq: Async workers как отдельные процессы/контейнеры.
Huey/RQ: Лёгкие отдельные worker-процессы.
APScheduler standalone: Обычно в том же процессе, что и приложение.

Вывод: Наш — самый простой в деплое (один сервис).

2. External Dependencies & Operational Surface

Наш: Только основная БД (опционально отдельная для задач). APScheduler — чисто in-memory.
Celery: Брокер + результат + мониторинг (Flower) + beat.
Dramatiq/ARQ: Брокер обязателен.
Procrastinate: Только Postgres.

Наш выигрывает по операционной простоте.

3. Scheduling (Cron + Dynamic jobs)

Наш: Полноценный Cron + динамическое добавление/удаление/перезагрузка из нескольких источников. Throttling внутри окон.
Celery Beat: Cron/interval + django-celery-beat для динамики.
APScheduler: Лучший в классе триггеров (date/interval/cron) + jobstores.
Huey: Periodic tasks через huey.contrib.
RQ: Нет встроенного — внешний планировщик или rq-scheduler.

Наш: Очень удобен для пользовательских расписаний (translate, validation, backup).

4. Task Execution Model & Concurrency

Наш: asyncio + bounded thread pools внутри event loop. Плагины выполняются в контексте приложения.
Celery: Отдельные процессы (prefork/eventlet/gevent).
ARQ/Taskiq: Нативный asyncio в worker'ах.
Dramatiq: Sync-first (можно с gevent).

Для I/O-heavy (LLM, HTTP к Superset, Git) async-модели (наш + ARQ) эффективнее по вертикали.

5. Scalability & Distribution

Наш: Только вертикальная (добавить CPU/RAM одной ноде). При нескольких backend'ах — дублирование расписаний.
Celery / большинство очередей: Линейное горизонтальное масштабирование (добавляй workers).
APScheduler с RedisJobStore: Ограниченная распределённость.

Наш не предназначен для десятков тысяч задач в минуту.

6. Reliability, Resilience & Fault Tolerance

Наш:

  • Расписания восстанавливаются при рестарте.
  • Задачи сохраняют состояние.
  • Проблема: RUNNING задачи при падении процесса не возобновляются автоматически. AWAITING_* требуют ручного рестарта.
  • Нет встроенных ретраев на уровне очереди.

Celery: Ack, redeliver, retries, max_retries, dead-letter, result backend.
Dramatiq: Хорошие ретраи по умолчанию.
Procrastinate: Надёжность Postgres.

Критично для нас: если задача "перевода 200k строк" упала вместе с backend — нужно перезапускать вручную.

7. Task Lifecycle Richness & Advanced Features

Наш — лидер в своей нише:

  • AWAITING_INPUT (пароли БД)
  • AWAITING_MAPPING (разрешение ресурсов)
  • TaskContext для structured logging
  • Отмена, resume, resolve через API

Celery: canvas (chain/group/chord), routing, priority, eta/countdown, rate_limit, task_revocation.
Остальные: базовые retry + простые очереди. Интерактивность почти ни у кого нет "из коробки".

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

8. Observability, Monitoring & UX Integration

Наш:

  • Нативный Task Status Center (spec 034)
  • WebSocket real-time логи + статус
  • Фильтры, summary, drawer с логами
  • RBAC на уровне задач

Celery: Flower (отдельное приложение), Prometheus экспортеры, кастом.
Другие: обычно только логи + кастомный дашборд.

Наш выигрывает для пользователей продукта (не только DevOps).

9. Persistence (Schedules + Task State/Results/Logs)

Наш:

  • Расписания — в прикладных таблицах + config.
  • Задачи/логи — task_records / task_logs (JSON + отдельная таблица логов).
  • Высокопроизводительная батчевая запись логов.

Celery: Результаты в отдельном backend (Redis/Postgres/…). Задачи обычно не хранят детальные логи внутри. APScheduler + SQLAlchemyJobStore: Полная персистентность расписаний. Huey: Опционально SQLite/Redis.

10. Resource Footprint, Isolation & Performance Profile

Наш: Низкий overhead. Всё в одном процессе. Bounded pools дают backpressure.
Celery prefork: Выше потребление памяти, хорошая изоляция.
Async workers (ARQ): Отличная плотность I/O-задач на ядро.
CPU-bound задачи: Процессные модели лучше (изоляция GIL).

Для наших задач (LLM, Superset API, Git, batch SQL) in-process async + pools работает отлично.

11. Ease of Development, Testing & Integration (FastAPI)

Наш: Плагины просто реализуют execute. Всё в одном codebase. Легко тестировать с TaskContext.
Celery: Отдельный app, сериализация, импорт проблем, тесты сложнее.
ARQ/Taskiq: Хорошая интеграция с FastAPI (async-native).
APScheduler: Самый простой для простых cron.

12. Ecosystem, Maturity & Maintenance Burden

  • Celery: Самая зрелая, огромная экосистема, но репутация "сложная и полна сюрпризов".
  • APScheduler: Зрелая, активно поддерживается.
  • Dramatiq: Создавалась как "лучше Celery".
  • ARQ: От автора Pydantic/FastAPI — отличный современный выбор.
  • Huey/RQ: Простые, меньше "магии".

Наш — полностью кастомный слой поверх APScheduler. Поддержка ложится на команду проекта.

13. Best-fit Use Cases & Trade-off Summary

Идеально для нас сегодня:

  • Инструмент администратора Superset.
  • Задачи с человеческим участием.
  • Реал-тайм обратная связь важнее горизонтального масштаба.
  • Минимальная операционная нагрузка.

Когда стоит рассмотреть Celery/ARQ/Dramatiq:

  • Появятся десятки тысяч фоновых задач.
  • Нужна настоящая отказоустойчивость (задача должна дожить до выполнения даже при рестарте всего кластера).
  • CPU-heavy работа (большие вычисления, не I/O).
  • Несколько независимых сервисов, которые должны шарить очередь.

Гибрид возможен: оставить текущий механизм для UI-driven и scheduled admin-задач, а тяжёлые batch-операции вынести в отдельную очередь.

Сравнительная матрица (сводка)

(См. TL;DR таблицу выше + детальные проекции.)

Рекомендация для superset-tools

Оставить текущую архитектуру как основную.

Причины:

  • Отлично соответствует текущим потребностям (переводы, бэкапы, валидации, миграции, git).
  • Уникальные фичи (AWAITING_*, TaskContext, нативный красивый Task Center) очень ценны для пользователей.
  • Низкая операционная сложность — большое преимущество.
  • ADR-0011 и вся эволюция проекта сознательно шли в эту сторону.

Что можно улучшить без революции (опционально):

  • Добавить SQLAlchemyJobStore или RedisJobStore для расписаний (защита от потери при странных рестартах).
  • Добавить автоматический "reconcile" для зависших RUNNING задач при старте (по таймауту или heartbeat).
  • Для очень тяжёлых переводов — рассмотреть возможность выноса в отдельный worker позже.

Не переходить на Celery "на всякий случай" — это добавит значительную сложность без немедленной пользы.

Источники

  • Код проекта: backend/src/core/scheduler.py, task_manager/*, ADR-0011-async-backend.md, docker-compose.
  • Внешние сравнения:
    • APScheduler vs Celery Beat (leapcell.io, 2025) [web:3].
    • Reddit 2026: "Choosing a Python task queue library".
    • Dramatiq motivation page.
    • ARQ adoption stories и бенчмарки (см. также [web:0], [web:9]).
    • StackShare / официальная документация.

Сравнение выполнено ортогонально — по независимым измерениям, без навязывания одного "лучшего" решения.