4.4 KiB
4.4 KiB
План внедрения
-
Шаблон + каркас пакета - сделано
- Создать структуру из ТЗ (один пакет
dataloader/по src-layout). - Подтянуть
rest_template.mdартефакты:os_router.py,middleware.py,logger/*. pyproject.toml:fastapi,uvicorn,pydantic-settings,sqlalchemy>=2, async,psycopg[binary,pool]илиasyncpg,httpx,pytest,pytest-asyncio,httpx[cli].- Критерий:
uvicorn dataloader.__main__:appподнимается,/healthотдаёт 200.
- Создать структуру из ТЗ (один пакет
-
Конфиг и контекст - сделано
config.py:AppSettings(DSN, тайминги, WORKERS_JSON).context.py:AppContext, созданиеAsyncEngineиasync_sessionmaker, DI.- Критерий:
/statusвозвращает версию/uptime, движок создаётся на старте без попыток коннекта в/health.
-
Хранилище очереди - в работе
-
storage/db.py: фабрики engine/sessionmaker. -
storage/repositories.py: методыcreate_or_get(req),get_status(job_id),cancel(job_id),requeue_lost(now),- вспомогательные
claim_one(queue),heartbeat(job_id, ttl),finish_ok(job_id),finish_fail_or_retry(job_id, err).
-
Только чистый SQL (как в ТЗ), транзакция на операцию.
-
Критерий: unit-интегра тест «поставил-прочитал-отменил» проходит.
-
-
API v1
api/v1/schemas.py:TriggerJobRequest/Response,JobStatusResponse.api/v1/service.py: бизнес-слой над репозиторием.api/v1/router.py:POST /jobs/trigger,GET /jobs/{id}/status,POST /jobs/{id}/cancel.- Критерий: ручки соответствуют контрактам, идемпотентность по
idempotency_keyработает.
-
Базовый воркер
workers/base.py: классPGWorkerс цикламиlisten_or_sleep → claim → advisory_lock → _pipeline → heartbeat → finish.- Идём строго по SQL из ТЗ:
FOR UPDATE SKIP LOCKED, lease/heartbeat, backoff при lock. - Критерий: локальный мок-пайплайн выполняется, статус
succeeded.
-
Менеджер воркеров
workers/manager.py: парсингWORKERS_JSON, созданиеasyncio.Taskна воркеры; мягкая остановка на shutdown.- Подключение в
__main__.pyчерез FastAPIon_startup/on_shutdown. - Критерий: при старте создаются нужные таски, при SIGTERM корректно гасим.
-
Реестр пайплайнов
workers/pipelines/registry.py:@register(task),resolve(task).- Пустой эталонный пайплайн (no-op, имитирует 2–3 чанка).
- Критерий: задача с
task="noop"исполняется через реестр.
-
Reaper
- Фоновая async-задача в приложении:
requeue_lostраз вDL_REAPER_PERIOD_SEC. - Критерий: задачи с протухшим
lease_expires_atвозвращаются вqueued.
- Фоновая async-задача в приложении:
-
Интеграционные тесты
-
tests/integration_tests/v1_api/test_service.py:- trigger → status (queued),
- воркер подхватил → status (running),
- done → status (succeeded),
- cancel во время пайплайна → корректная реакция.
-
Критерий: тесты зелёные в CI.
-
-
Dockerfile и запуск
- Slim образ на Python 3.11/3.12,
uvicornentrypoint. - ENV-пример
.env, README с запуском. - Критерий: контейнер стартует, воркеры работают, API доступно.
- Наблюдаемость
- Логи в формате шаблона (структурные, маскирование).
- Простая сводка в
/status(кол-во активных воркеров, конфиг таймингов). - Критерий: видно ключевые переходы статусов и ошибки пайплайнов.