Skip to content

Latest commit

 

History

History
86 lines (66 loc) · 6.18 KB

File metadata and controls

86 lines (66 loc) · 6.18 KB

Параллельные Workers

Для кодогенерации используются изолированные Docker-контейнеры с AI coding agents.

Текущая архитектура

┌─────────────────────────────────────────────────────┐
│                 LangGraph Orchestrator              │
│          (Developer node в Engineering)             │
└─────────────────────────────────────────────────────┘
                         │
                  Redis streams
          (worker:commands / worker:{id}:*)
                         │
                         ▼
┌─────────────────────────────────────────────────────┐
│              worker-manager Service                 │
│    (API / Docker Client / Compose Proxy)            │
└─────────────────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────┐
│        Worker Container (ephemeral)                 │
│  - Образ: worker-base-common + тулинг               │
│  - Нативные утилиты: ruff, pytest, make, python     │
│  - Выполняет coding task                            │
│  - Запрашивает инфраструктуру через CLI             │
└─────────────────────────────────────────────────────┘

Изоляция и Flat Dev Environment

Вместо Docker-in-Docker (Sysbox), система использует парадигму Flat Dev Environment, управляемую с хоста через worker-manager. Это решает проблемы с RAM, кэшами слоёв и стабильностью.

  1. Dual-Network Setup: Каждый воркер подключён к двум сетям:

    • internal (shared codegen network) — для связи с api, redis и worker-manager.
    • dev_proj_<worker_id> — изолированная сеть для сайдкар-контейнеров проекта.
  2. Compose Proxy: Воркеры (инжектированные AI-агенты) не имеют доступа к Docker. Для запуска инфраструктурных зависимостей (DB, Redis) агенты вызывают compose proxy через curl $WORKER_MANAGER_URL/api/worker/$WORKER_ID/infra/compose, который проксирует запрос в worker-manager.

  3. Workspace Bind-Mount: Scaffolded workspace монтируется в /workspace внутри контейнера. Два режима:

    • Pre-scaffolded (story tasks): путь на хосте /data/workspaces/{repo_id}/ — репозиторий уже подготовлен scaffolder'ом (copier + make setup + git push), workspace переиспользуется между задачами в story.
    • Ephemeral (standalone tasks): /tmp/codegen/workspaces/{worker_id}/workspace/ — создаётся на лету, удаляется после завершения. docker compose на хосте использует файлы из этого воркспейса для поднятия сайдкар-контейнеров.

Запрет портов и конвенции

  • Никаких ports: в compose: Сервисы шаблона не публикуют порты на хост, так как это вызовет конфликты при параллельной работе воркеров.
  • Агенты обращаются к сайдкар-сервисам по именам хостов (db:5432) внутри изолированной сети dev_proj_<worker_id>.

Worker Образы

Worker-base образ worker-base-common унифицирован:

  • Ubuntu + Python 3.12 + Node.js
  • Shared Tooling Layer: ruff, pytest, mypy, copier, и т.д. установлены на уровне образа (не дублируются на каждый воркер).
  • Non-root user worker (uid 1000). Код на хосте через bind-mount не становится root-owned.
  • Выполнение тестов и линтеров происходит нативно через per-service venv-ы, без запуска дополнительных эфемерных контейнеров.

Worker Lifecycle & Cleanup

Stream Cleanup

delete_worker() now cleans worker:{id}:input and worker:{id}:output streams (were orphaned forever before).

Orphan GC

Reverse check (Redis → Docker): scans worker:status entries and cleans stale ones where the container is gone. Introspect API shows GONE status for stale workers.

Workspace GC

Scans both WORKSPACE_BASE_PATH and SCAFFOLDED_WORKSPACE_PATH. Max age: 35h. Also cleans stale workspace:active_projects Redis entries. When workspace is deleted, calls POST /repositories/{repo_id}/notify-workspace-deleted to clear workspace_ready flag so scaffolder re-creates it before next task dispatch.

Stale Worker Auto-Cleanup

_check_project_lock() verifies worker:status — workers in terminal states (DEAD/FAILED/STOPPED) get their Redis keys cleaned up automatically, unblocking new task dispatch without manual intervention.

Worker-Manager Introspection API

/api/introspect/ router with 7 endpoints:

  • List workers, worker detail (with container info from Docker)
  • Container logs (tail param, max 5000 lines)
  • Workspace file tree, file content (path traversal protection)
  • Prompts (CLAUDE.md + TASK.md)
  • Kill worker

Admin-frontend nginx proxies /wm-api/ → worker-manager.