From 8dc07445acd8f582856a09ab8e89629c3c2249ab Mon Sep 17 00:00:00 2001 From: Naeel Date: Thu, 19 Mar 2026 20:31:49 +0300 Subject: [PATCH] =?UTF-8?q?doc:=20Tests=203-7,=208=20=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=B5=D1=81=D1=81-=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B9,?= =?UTF-8?q?=20=D0=BF=D0=BB=D0=B0=D0=BD=20Go=20runtime=20v0.1.1=20+=20pgx/v?= =?UTF-8?q?5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/decisions/log.md | 37 +++++++++++++++++++ doc/progress.md | 85 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/doc/decisions/log.md b/doc/decisions/log.md index 6ab5fce..771ab7c 100644 --- a/doc/decisions/log.md +++ b/doc/decisions/log.md @@ -1,5 +1,42 @@ # Решения и обоснования +--- + +## 2026-03-19 — Go runtime v0.1.1: внешние зависимости через go.mod/go.sum + +### Контекст + +Go runtime `naeel/sless-runtime-go1.23:v0.1.0` содержал `go.mod` только с `module sless/fn` и `go 1.23`. +Никаких `require` — пользовательский код мог использовать только stdlib. + +При попытке добавить `pgxpool` в handler.go функция не собиралась (зависимость не найдена). + +### Решение + +Добавить `require github.com/jackc/pgx/v5 v5.7.2` в `runtimes/go1.23/go.mod`. +Сгенерировать `go.sum` через `go mod tidy` (stub `.go` файл с импортом нужен — иначе tidy удалит deps). +Обновить `Dockerfile` — добавить `COPY go.sum` + `RUN go mod download` **до** копирования пользовательского кода → зависимости кешируются в слое Docker, не скачиваются при каждой сборке функции. + +### Почему pgx/v5, а не lib/pq + +- `pgx/v5` — современный нативный PG-драйвер, `pgxpool` встроен, не нужен отдельный `database/sql` +- `lib/pq` — legacy, минимальный API, отсутствует connection pool +- `jackc/pgx/v5 v5.7.2` — последний стабильный тег на момент решения + +### Что стало возможным + +Любая Go функция в платформе может импортировать `pgxpool` и работать с PG напрямую: +```go +import "github.com/jackc/pgx/v5/pgxpool" +``` + +### Версионирование образа + +`v0.1.0` → `v0.1.1` — изменение breaking: бинарник пересобирается с новыми deps. +Base image в `context.go` обновляется с `v0.1.0` на `v0.1.1`, оператор бампится. + +--- + ## 2026-03-19 — Архитектура event-trigger (Вариант A: отдельный event-dispatcher) ### Контекст diff --git a/doc/progress.md b/doc/progress.md index 3b40bb6..d620f14 100644 --- a/doc/progress.md +++ b/doc/progress.md @@ -1,6 +1,89 @@ # Прогресс разработки -Последнее обновление: 2026-03-19 14:00 +Последнее обновление: 2026-03-19 21:00 + +--- + +## 2026-03-19 — Go runtime v0.1.1: pgx/v5 + stress-go-pgstorm ⏳ В РАБОТЕ + +### Цель +Новая функция `stress-go-pgstorm` — Go код со 100 горутинами, которые ~10 минут долбят +PostgreSQL напрямую через `pgxpool`. Проверяем: Go runtime под нагрузкой, connection pool +под конкурентными запросами, устойчивость кластера. + +### Задачи + +| # | Задача | Статус | Заметки | +|---|--------|--------|---------| +| 1 | `runtimes/go1.23/go.mod` — добавить `pgx/v5 v5.7.2` | ✅ | go mod tidy на remote, go.sum сгенерирован (28 строк) | +| 2 | `runtimes/go1.23/go.sum` — создан | ✅ | Все indirect deps: pgpassfile, pgservicefile, puddle/v2, crypto, sync, text | +| 3 | `runtimes/go1.23/Dockerfile` — добавить `go mod download` | ⏳ | | +| 4 | Собрать `naeel/sless-runtime-go1.23:v0.1.1`, запушить | ⏳ | | +| 5 | `internal/builder/context.go` — обновить тег `go1.23` → v0.1.1 | ⏳ | | +| 6 | Пересобрать оператор `v0.1.39`, задеплоить | ⏳ | | +| 7 | `code/stress-go-pgstorm/handler.go` — горутины + pgxpool | ⏳ | | +| 8 | `resources.tf` — новая функция + trigger | ⏳ | | +| 9 | `terraform apply`, тест | ⏳ | | +| 10 | Коммит | ⏳ | | + +### Архитектура функции stress-go-pgstorm + +``` +Handle(event) → запускает N горутин (default 100) + каждая горутина в цикле duration_sec (default 600): + - случайная задержка 0-500ms + - чередующиеся операции: INSERT / SELECT COUNT / SELECT MAX + - логирует ошибки, считает ok/err + финал → {workers, duration_sec, total_ops, ok_ops, err_ops, ops_per_sec} +pgxpool.New() — connection pool, MaxConns=20 +env: PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD, PGSSLMODE +``` + +--- + +## 2026-03-19 — Tests 3-7: E2E прогон POSTGRES + 8 стресс-функций + +### Tests 3-7 + +| Тест | Действие | Результат | +|------|----------|-----------| +| Test 3 | `table_rw.py`: добавлен `version: v2-with-hostname`, `host: socket.gethostname()` | ✅ Terraform apply, функция пересобрана | +| Test 4 | `pg_info.js`: добавлен `code_version: v2-agent-test` | ✅ code_hash изменился, вернул `{"code_version":"v2-agent-test"}` | +| Test 5 | Удалить trigger → 404 → пересоздать → работает | ✅ | +| Test 6 | Удалить function + trigger → 404 → пересоздать (rebuild 46s) → работает | ✅ | +| Test 7 | Новая функция `pg-stats` (Python): version, total_rows → протестирована → удалена | ✅ `{"version":"v1-test7","total_rows":3}` | + +### 8 стресс-функций (коммит `014b99e`) + +Задеплоены и прогнаны дважды через `stress_test.sh` (3 раунда). +После crash-тестов все 8 подов: `Running`, 0 restarts. + +| # | Функция | Runtime | Что проверяет | Результат | +|---|---------|---------|---------------|-----------| +| 1 | `stress-slow` | Python | sleep 3-N сек | ✅ `{"slept_sec":3}` | +| 2 | `stress-bigloop` | Python | CPU n=2M | ✅ 0.31s | +| 3 | `stress-divzero` | Python | ZeroDivisionError crash | ✅ pod restart → при d=7: `{"result":6.0}` | +| 4 | `stress-writer` | Python | batch INSERT в PG | ✅ +3/+10 строк | +| 5 | `stress-go-fast` | Go | factorial+fib без deps | ✅ factorial(20), fib(20) | +| 6 | `stress-go-nil` | Go | nil pointer panic | ✅ pod restart → при crash=false: ok | +| 7 | `stress-js-async` | NodeJS | 3 PG запроса Promise.all | ✅ version/count/max_id | +| 8 | `stress-js-badenv` | NodeJS | TypeError (pod жив, HTTP 500) | ✅ нет restart | + +**Итого в таблице после двух прогонов: 32 строки.** + +### Поведение crash-функций + +- `stress-divzero` / `stress-go-nil`: **pod restart** при краше (EOF на первый запрос после падения) — нормальное k8s поведение, runtime процесс умирает целиком +- `stress-js-badenv`: **HTTP 500 без restart** — NodeJS поймал TypeError внутри async handler, pod остался жив +- Это различие задокументировано: Python/Go crash = process exit, NodeJS crash = unhandled rejection в async = 500 + +### git + +- Бинарник `event-dispatcher` (50MB) удалён из истории через `git reset --soft HEAD~2` +- Добавлен в `.gitignore` +- Force push: `d879817` → `014b99e` + +--- ## 2026-03-19 — event-trigger refactor (ветка feat/event-trigger-refactor)