13 KiB
Отчёт 2026-04-26 — Layer2 console, live validation и причина NodeJS сбоя
Цель
Зафиксировать текущее состояние Layer2 API и console UI в репозитории fission, задокументировать выполненные live-проверки и отдельно разобрать корневую причину, по которой NodeJS-функции раньше создавались, но не вызывались.
Что было сделано в этой сессии
1. Namespace status/debug приведён к реальному layer1 поведению
Старый код статуса namespace не соответствовал watcher-based схеме из layer1. В console backend логика была перепривязана к реальной модели readiness и bootstrap.
Сделано:
- добавлена актуальная проверка состояния namespace и control-plane;
- добавлен debug endpoint для UI;
- wiring зарегистрирован в HTTP server.
Основные точки:
2. UI стал показывать прогресс и причины задержек
В UI добавлена более явная обратная связь по долгим операциям:
- таймер deploy/invoke;
- стадия выполнения;
- причина задержки, если функция ещё не готова;
- более явное сообщение об ошибке invoke/deploy.
Это было нужно для демонстрации: пользователь не должен видеть просто зависание без контекста.
Основная точка:
3. Go выведен из текущего demo-сценария
Go не удалялся из backend-логики целиком, но был исключён из текущего UI create-flow и из оперативного demo-фокуса. Причина практическая: это единственный компилируемый язык в текущем наборе, а на стенде он зависал на build pending и не был нужен для ближайшей демонстрации.
Основная точка:
4. NodeJS починен на уровне packaging + entrypoint compatibility
Это был главный runtime-дефект в конце сессии.
Изменения:
- backend-упаковщик NodeJS теперь экспортирует сразу
main,handlerиdefault; - UI-шаблон NodeJS создаёт новые функции с entrypoint
main; - добавлен узкий unit-test на содержимое zip wrapper.
Основные точки:
- console/internal/runtime/nodejs.go
- console/internal/runtime/nodejs_test.go
- console/internal/runtime/entrypoint.go
- console/ui/index.html
Почему NodeJS не работал
Симптом
Свежесозданная NodeJS-функция успешно создавалась, package имел buildstatus: none, poolmgr pod поднимался, но invoke стабильно возвращал timeout:
invoke "node-..." timeout after 20s: function specialization likely failed
Что показала диагностика
В кластере у сломанной функции одновременно наблюдалось следующее:
-
В backend default entrypoint для NodeJS уже был
main. См. console/internal/runtime/entrypoint.go. -
В UI исторический шаблон NodeJS создавал функцию с entrypoint
handler. -
Генерируемый
main.jswrapper не экспортировал именованные entrypoint-ыmainиhandlerодновременно. По факту он не обеспечивал совместимость между старым UI-поведением и backend default semantics. -
В результате в
Function.spec.package.functionNameоказывалсяhandler, а в содержимом package literal не было гарантированной совместимой named export для этого имени. -
Fission specialization доходил до стадии загрузки кода, но не мог корректно разрешить entrypoint и заканчивал таймаутом specialization.
Корневая причина
Корневая причина была не в builder, не в Package CRD и не в самом создании environment.
Проблема была в несовместимости между:
- ожидаемым именем entrypoint в Function spec;
- историческим значением entrypoint из UI;
- фактически экспортируемыми символами в NodeJS wrapper.
Коротко: backend и UI расходились по имени entrypoint, а zip wrapper не был сделан обратносуместимым.
Исправление
В console/internal/runtime/nodejs.go wrapper был изменён так, чтобы:
- разрешать user code как function, default, handler или main;
- экспортировать
__invokeсразу какmainи какhandler; - сохранить также
defaultexport.
Ключевой фрагмент поведения теперь такой:
- поиск callable идёт через
_fn.default || _fn.handler || _fn.main; - наружу wrapper экспортирует
main,handler,default.
Это снимает несовместимость и для старых client-side ожиданий, и для нового backend default entrypoint.
Проверка исправления
- Unit validation:
go test ./internal/runtime ./internal/api ./cmd/server— PASS.
- Live rollout:
- выкачен image
naeel/fission-console:v0.8.17; - deployment
fission-consoleуспешно обновлён до этого образа.
- Live retest после rollout:
- создана свежая NodeJS-функция через public console API;
- create вернул
201; - первый же invoke вернул
200иnode-fix-ok.
Вывод: проблема была именно в entrypoint/export compatibility, и на новых функциях после rollout она устранена.
Важно: уже созданные до фикса NodeJS-функции не чинятся автоматически, потому что их старый package literal уже записан в кластере.
Что проверено живыми тестами
Языки
К моменту завершения фикса подтверждено:
- Python: deploy/invoke PASS;
- PHP: deploy/invoke PASS;
- Ruby: deploy/invoke PASS;
- NodeJS: после выката
v0.8.17deploy/invoke PASS на свежей функции; - Go: исключён из текущего demo-path.
- Perl: исключён из текущего demo-path после нестабильного specialization в
perl-env.
Многопользовательский сценарий
Прогон с 10 параллельными пользователями показал:
CREATE_OK=10/10;INVOKE_OK=10/10.
Отдельно ранее наблюдался шум на первичном init (GET /functions) с частью ответов 000000, то есть проблема была не в create/invoke-конвейере, а в кратковременной нестабильности первичного запроса или timeout-режима самого тестового скрипта.
Что важно помнить перед следующим циклом тестов
- Для длинных прогонов на этом стенде безопаснее использовать self-completing SSH-команды с жёсткими timeout, а не фоновые или интерактивные сценарии.
- Для NodeJS нужно тестировать только новые функции, созданные уже после rollout исправленного console image.
- Для demo сейчас приоритетны Python, NodeJS, PHP, Ruby.
- Go в UI скрыт намеренно и не должен снова появиться в create-flow до отдельного решения по builder path.
Автоочистка test namespace
После серии прогонов на стенде начали накапливаться десятки и сотни user namespace от тестов. Это мешает ручной диагностике и засоряет cluster state.
Чтобы это больше не копилось:
- добавлен helper cleanup_test_namespaces.sh;
- tests_v2.sh теперь в
trap EXITудаляет все namespace, созданные своими test sub; - test_multitenant_ns.sh тоже удаляет свои namespace по завершении, включая аварийный выход.
Дополнительно на стенде был запущен разовый cleanup накопившихся test namespace с префиксами fission-, diag-, l1-test-, rbac-verify-, sa-verify-.
Следующий шаг
Следующий практический шаг после этого отчёта:
- удалить все текущие Fission-функции и managed namespaces;
- затем прогнать новый набор тестов с нуля;
- отдельно включить сценарии, которые имитируют пользовательские ошибки в UI: пустые поля, дубли, неверный entrypoint, плохой код, ранний invoke и повторные клики.
Обновление: удаление Perl из demo-path
После отдельной проверки выяснилось, что Perl ломается не только в multi-tenant console path, но и на обычном single-user Fission через simple-perl-env в default namespace. Поэтому для demo-path Perl был отключён на стороне console.
Что изменено:
- Perl убран из UI create-flow;
- Perl убран из supported language map console-side;
- Perl убран из
ai/checklanguage set; - Perl убран из live regression сценариев demo-path.
Live rollout:
- собран и выкачен image
naeel/fission-console:v0.8.19; - deployment
fission-consoleобновлён доnaeel/fission-console:v0.8.19; - rollout completed successfully.
Что проверено после rollout v0.8.19:
go test ./internal/... ./cmd/server/...— PASS;bash ./test_linters.sh— PASS (PASS=31 FAIL=0);KUBECTL_DIRECT=1 ./test_ui_user_flows.sh— PASS (PASS=26 FAIL=0), после усиления invoke-диагностики и разведения Python / Node / PHP+Ruby по разным user namespaces;KUBECTL_DIRECT=1 ./smoke_live_multiuser.sh 10—CREATE_OK=10/10,INVOKE_OK=10/10, но первичный init далINIT_OK=6/10из-за кратковременныхGET /functions -> 000000;- после добавления retry в init:
KUBECTL_DIRECT=1 ./smoke_live_multiuser.sh 10—INIT_OK=10/10,CREATE_OK=10/10,INVOKE_OK=10/10; - новый параллельный сценарий
KUBECTL_DIRECT=1 ./smoke_user_journeys.sh 5—USER_JOURNEYS_PASS=5/5; - Python / NodeJS / PHP / Ruby demo-path остаются рабочими;
- Perl отсутствует в live UI surface намеренно.
Отдельно зафиксирована причина ложного падения прежнего test_ui_user_flows.sh: это был не баг PHP/Ruby runtime и не ошибка create-path, а quota одного user namespace. Когда в одном и том же namespace последовательно держались Python, NodeJS update и затем PHP/Ruby poolmgr pod'ы, Fission ловил exceeded quota: user-quota, requested: limits.cpu=1, used: limits.cpu=4, limited: limits.cpu=4, после чего invoke возвращал timeout after 20s: function specialization likely failed. Для live user-flow smoke сценарии были разведены по разным test users/namespaces, сохранив совместную проверку PHP+Ruby в одном namespace.
Дополнительно исправлены сами тесты:
test_multitenant_ns.shбольше не использует устаревший SSH key path;test_multitenant_ns.shтеперь JSON-экранирует многострочный Python code payload при create function.