diff --git a/.cursor/plans/evobgp_архитектура_0e73ef02.plan.md b/.cursor/plans/evobgp_архитектура_0e73ef02.plan.md index 7a61f03..ab9691e 100644 --- a/.cursor/plans/evobgp_архитектура_0e73ef02.plan.md +++ b/.cursor/plans/evobgp_архитектура_0e73ef02.plan.md @@ -118,7 +118,7 @@ EvoBGP/ │ ├── repository/ # SQL по сущностям (tenant, module, peer, revision, jobs, …) │ ├── domain/ # типы и правила без I/O (префиксы, community, ревизии) │ ├── httpapi/ # роуты OpenAPI, middleware, валидация, маппинг в сервисы -│ ├── jobs/ # очередь: брокер (reference) vs PG + SKIP LOCKED (microVPS) +│ ├── jobs/ # задачи: сейчас in-memory Registry в процессе API; PG job_audit / брокер — целевое расширение (см. примечание ниже §2) │ ├── scheduler/ # триггеры по расписанию модулей │ ├── ingest/ # CDN, DoH, нормализация, запись в БД │ ├── render/ # материализация префиксов, ревизия, текст артефактов BIRD @@ -237,6 +237,8 @@ flowchart LR > **Правило:** логика домена **одинакова**; **один движок БД — PostgreSQL** (одинаковые миграции и SQL). Отличаются число процессов Go, наличие брокера и **настройки** PG. +> **Примечание (текущий код vs целевая очередь):** исполнение async jobs идёт через **in-memory `jobs.Registry` в процессе `evobgp-api` / `evobgp-all`**; таблица `job_audit` в миграциях заложена под будущую персистенцию и идемпотентность между процессами. В **reference** Compose отдельный `evobgp-scheduler` **не** читает эту очередь, а вызывает `POST .../modules/{id}/refresh` по HTTP. NATS в compose — для будущей интеграции; см. [docs/architecture.md](../../docs/architecture.md). + > **Опция `microVPS_sqlite`:** один контейнер `evobgp-all` без PG — только если критичен абсолютный минимум контейнеров; иначе **не рекомендуется** как основной путь. --- diff --git a/cmd/evobgp-all/main.go b/cmd/evobgp-all/main.go index 5913045..3d7e8c5 100644 --- a/cmd/evobgp-all/main.go +++ b/cmd/evobgp-all/main.go @@ -21,7 +21,7 @@ import ( "evobgp/internal/scheduler" ) -// microVPS entrypoint: one process — HTTP API plus in-process scheduler, ingest, render, deploy workers (shared store + job registry). +// microVPS entrypoint: один процесс — HTTP API и фоновые воркеры scheduler, ingest, render, deploy (общий store и jobs.Registry). func main() { cfg := config.Load() opts := httpapi.Options{ diff --git a/cmd/evobgp-scheduler/main.go b/cmd/evobgp-scheduler/main.go index ef8fdb0..2c270f0 100644 --- a/cmd/evobgp-scheduler/main.go +++ b/cmd/evobgp-scheduler/main.go @@ -45,7 +45,10 @@ func main() { Store: st, HTTP: &http.Client{Timeout: 45 * time.Second}, } - if apiBase != "" && apiTok != "" { + if (apiBase != "") != (apiTok != "") { + log.Fatal("evobgp-scheduler: set both EVOBGP_CONTROL_PLANE_URL and EVOBGP_SCHEDULER_BEARER for HTTP mode, or leave both empty for in-process job registry") + } + if apiBase != "" { deps.APIBase = apiBase deps.APIToken = apiTok log.Printf("evobgp-scheduler: control plane HTTP mode (%s)", apiBase) diff --git a/deploy/compose/docker-compose.yaml b/deploy/compose/docker-compose.yaml index 322ac1e..7a295fe 100644 --- a/deploy/compose/docker-compose.yaml +++ b/deploy/compose/docker-compose.yaml @@ -5,6 +5,7 @@ # docker compose --profile microvps up -d --build # # reference: 5× Go (api + scheduler + ingest + render + deploy) + postgres + NATS JetStream + bird2 + agent + web. +# Async jobs выполняются in-process в evobgp-api (jobs.Registry); NATS — задел под брокер (см. docs/architecture.md). # microvps: evobgp-all + postgres + bird2 + agent (без брокера). # # Опция microVPS_sqlite из плана (без контейнера Postgres): требует реализации store на SQLite в приложении; diff --git a/docs/architecture.md b/docs/architecture.md index 4329a3b..fb899ec 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -38,7 +38,7 @@ | `birddeploy` | Логика применения конфигурации к BIRD (используется в цепочке деплоя). | | `config` | Переменные окружения `EVOBGP_*`. | | `observability` | Метрики Prometheus, HTTP middleware. | -| `broker` | Заготовка под NATS/Redis (логирование подключения в воркерах). | +| `broker` | Опциональный `EVOBGP_BROKER_URL` для будущей шины; сейчас задачи только in-process (`jobs.Registry`), пакет лишь логирует факт настройки URL. | | `pipeline` | Ingest+render в одном шаге для `module_refresh`: выборка префиксов (CDN/AS/IP/пустые DOMAINS), `CreateRenderRevision`, превью BIRD через `birdfmt`. | ## Диаграмма: эталонный Compose (reference) diff --git a/docs/openapi.html b/docs/openapi.html index 5cd7b31..56bae32 100644 --- a/docs/openapi.html +++ b/docs/openapi.html @@ -3210,15 +3210,15 @@ data-styled.g138[id="sc-iJQrDi"]{content:"gtHWGb,"}/*!sc*/ " class="sc-iKGpAq sc-cCYyou dXXcln dHaogz">

Обмен ключами и привязка к speaker_id; детали протокола уточняются отдельно.

Authorizations:
bearerAuth
Request Body schema: application/json
required
public_key
string
speaker_id
string (ResourceId) ^[0-9A-Za-z_-]{20,36}$

UUID v7 или ULID.

-
property name*
additional property
any

Responses

property name*
additional property
any

Responses

Request samples

Content type
application/json
{
  • "public_key": "string",
  • "speaker_id": "01JQXYZABCDEFGHIJKLMNOPQRS"
}

Response samples

Content type
application/json
{ }

Settings

https://api.example.com/v1/nodes/enroll

Request samples

Content type
application/json
{
  • "public_key": "string",
  • "speaker_id": "01JQXYZABCDEFGHIJKLMNOPQRS"
}

Response samples

Content type
application/json
{
  • "status": "enrolled",
  • "speaker_id": "01JQXYZABCDEFGHIJKLMNOPQRS",
  • "tenant_id": "01JQXYZABCDEFGHIJKLMNOPQRS"
}

Settings

Глобальные настройки и feature flags; изменение - только operator.

Получить настройки

KV (лимиты CDN, feature flags и т.д.).

@@ -3246,7 +3246,7 @@ data-styled.g138[id="sc-iJQrDi"]{content:"gtHWGb,"}/*!sc*/ " class="sc-iKGpAq sc-cCYyou dXXcln cFvDiF">

Базовый URL инсталляции (замените на свой)

https://api.example.com/v1/settings

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{ }