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

211 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ортогональное сравнение: Наш 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_task``asyncio.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 / официальная документация.
---
*Сравнение выполнено ортогонально — по независимым измерениям, без навязывания одного "лучшего" решения.*