Files
sless/doc/decisions/log.md
T

133 lines
8.3 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.
# Решения и обоснования
## 2026-03-06 — Отдельная репа для сервиса
**Решение:** Serverless service в отдельной репе, не вместе с Terraform provider.
**Причина:** Разные зоны ответственности, разные релизы, потенциально разные команды.
---
## 2026-03-06 — Один бинарник для v1
**Решение:** Один Go бинарник вместо микросервисов.
**Причина:** Нагрузки изначально нет. Проще деплоить, проще отлаживать. Разделим при необходимости.
---
## 2026-03-06 — Аутентификация через облачный токен
**Решение:** Использовать Bearer token облака, без Keycloak.
**Причина:** Terraform provider уже работает с токенами облака. Keycloak — лишняя зависимость для v1.
---
## 2026-03-06 — S3 облачный, остальное в кубере
**Решение:** S3 (Ceph) использовать облачный (`ceph.tst.nubes.ru`), PostgreSQL/Redis — в кластере.
**Причина:** S3 имеет внешний доступ и уже готов. Для PostgreSQL/Redis сетевого связывания с облаком пока нет — настраивается через devops облака.
---
## 2026-03-06 — Текущий кластер для разработки
**Решение:** Использовать существующий k8s кластер (namespace `sless`), потом перенести на новый.
**Причина:** Новый кластер ещё не готов. Изоляция через namespace — безопасно для существующих сервисов.
---
## 2026-03-06 — RabbitMQ откладываем
**Решение:** В v1 только HTTP и Cron триггеры. RabbitMQ/event triggers — в v2.
**Причина:** Упрощение первой итерации.
---
## 2026-03-07 — DockerHub вместо внутреннего registry
**Решение:** Образы функций и runtime базовые образы публикуются на DockerHub (user `naeel`).
**Причина:** Namespace `registry` в кластере — это Apache NiFi Registry (NOT Docker). Отдельный Docker registry не поднят. DockerHub доступен и достаточен для разработки.
---
## 2026-03-07 — Terraform провайдер sless — отдельный модуль в той же репе
**Решение:** `terraform/provider/` — независимый Go-модуль внутри репы `sless`.
**Причина:** Удобно держать рядом. Код провайдера писался с прицелом на перенос в nubes провайдер (`/home/naeel/remote_dev/terraform`). Клиент (`internal/client/`) → `internal/core/` nubes, ресурсы → `internal/resources_gen/`.
---
## 2026-03-07 — WaitReady в Terraform провайдере при создании функции
**Решение:** После `UploadCode` провайдер ждёт `phase=Ready` (polling каждые 5 сек, таймаут 5 мин).
**Причина:** Kaniko-сборка занимает ~1 минуту. Без ожидания `terraform apply` завершился бы с `phase=Building` в state, что неверно отображало бы реальное состояние ресурса.
---
## 2026-03-07 — code_hash для детектирования изменений кода функции
**Решение:** Атрибут `code_hash` в `sless_function` — пользователь задаёт через `filemd5("./handler.zip")`. Изменение hash → провайдер перезагружает zip и запускает пересборку.
**Причина:** Terraform не отслеживает содержимое файлов автоматически. Это стандартный паттерн (аналогично `aws_lambda_function.source_code_hash`).
---
## 2026-03-07 — Scale-to-zero откладываем до v2
**Решение:** В v1 функции работают как Deployment с постоянно живым подом (always-on). Scale-to-zero — в v2 через KEDA HTTP Add-on.
**Причина:** Scale-to-zero меняет архитектуру контроллера и routing. Для MVP это несоразмерная сложность. Пользователь может управлять ресурсами вручную через `replicas = 0/1/N` (планируется в v1.1).
**v2 план:** Заменить Deployment на `HTTPScaledObject` (KEDA), минимальные реплики = 0. KEDA буферизует запросы во время cold start (~1-3 сек).
---
## 2026-03-07 — replicas как ручное управление масштабом (TODO v1.1)
**Решение:** Добавить поле `replicas *int32` в `FunctionSpec`. Пользователь задаёт через Terraform: `replicas = 0` (выключить), `replicas = 1` (включить), `replicas = N` (масштабировать).
**Причина:** Без этого функция жрёт ресурсы 24/7 даже если не нужна. Это минимальный механизм контроля потребления до реализации scale-to-zero.
---
## 2026-03-07 — PostgreSQL опционален для базового Function Hosting
**Решение:** Postgres нужен только для логов вызовов (`invocations`). Для базового деплоя функций — не нужен. Оператор работает без него (просто не пишет логи).
**Минимальные зависимости для production:** k8s кластер + S3 + Docker registry + Ingress.
## 2026-03-07 — Версионированные теги для runtime образов (не :latest)
**Решение:** Runtime базовые образы (`sless-runtime-python3.11`, `sless-runtime-nodejs20`) и образ оператора (`sless-operator`) тегируются по схеме `v<major>.<minor>.<patch>`. `:latest` не используется.
**Причина:**
- `:latest` приводит к непредсказуемому поведению: kaniko может взять старый кешированный образ, pod не перезапускается если `imagePullPolicy: IfNotPresent`.
- Версионированные теги дают явный контроль: при изменении runtime нужно обновить тег в `upload.go` → это принудительно пересобирает все функции с новым базовым образом.
- Аудит и откат: можно пинить конкретную версию runtime.
**Соглашение:**
- Runtime образы: `naeel/sless-runtime-{lang}:v{версия}` (например `v0.1.0`)
- Оператор: `naeel/sless-operator:v{версия}`
- При изменении runtime — инкрементировать минорную версию образа и обновить константу в `upload.go`
---
## 2026-03-07 — nodejs20 как второй поддерживаемый runtime
**Решение:** Добавлен nodejs20 runtime (`node:20-alpine` base, `server.js` HTTP wrapper, `exports.handle(event)`).
**Причина:** Node.js — стандарт для serverless (AWS Lambda, Vercel). Покрывает JS/TypeScript аудиторию. Паттерн идентичен python3.11: runtime image → kaniko → Deployment.
**Детали реализации:**
- `runtimes/nodejs20/server.js``http.createServer`, динамический `require(HANDLER_PATH)`
- Зависимости через `package.json``npm install --omit=dev` (аналог `requirements.txt``pip install`)
- `entrypoint` в HCL игнорируется для Node.js (всегда `handler.js` + `exports.handle`) — TODO: поддержать произвольный entrypoint в v1.1