diff --git a/doc/thinking/2026-04-26-namespace-manager-step4.md b/doc/thinking/2026-04-26-namespace-manager-step4.md new file mode 100644 index 00000000..a98a2490 --- /dev/null +++ b/doc/thinking/2026-04-26-namespace-manager-step4.md @@ -0,0 +1,32 @@ +# 2026-04-26 — NamespaceManager rewrite, step 4 + +## Цель шага + +Исправить реальный functional bug в dynamic onboarding buildermgr. + +## Дефект + +`buildermgr.StartNSWatcher()` вызывает: + +1. `envw.AddNamespace()` +2. `pkgw.AddNamespace()` + +Но оба watcher-а используют один и тот же глобальный `nsResolver.AddNamespace()` для dedup. +Из-за этого первый вызов добавляет namespace, а второй считает его уже обработанным и +выходит раньше времени. В результате у динамического tenant namespace может подняться только +Environment informer без Package informer. + +## Исправление + +1. Глобальный resolver обновляется один раз в `buildermgr/ns_watcher.go`. +2. `environmentWatcher` dedup делает только по своей map `envWatchInformer`. +3. `packageWatcher` dedup делает только по своим map `pkgInformer` / `podInformer`. + +Так buildermgr становится симметричнее executor path: общий registry обновляется один раз, +а конкретные компоненты сами решают, подписаны ли они уже на namespace. + +## Что НЕ меняем + +- не добавляем cleanup/remove semantics; +- не меняем router; +- не трогаем newdeploy parity gap на этом шаге. \ No newline at end of file diff --git a/pkg/buildermgr/envwatcher.go b/pkg/buildermgr/envwatcher.go index 099ab1b5..8da7075c 100644 --- a/pkg/buildermgr/envwatcher.go +++ b/pkg/buildermgr/envwatcher.go @@ -501,9 +501,9 @@ func (envw *environmentWatcher) createBuilderDeployment(ctx context.Context, env } // AddNamespace dynamically registers a new namespace in environmentWatcher. -// Creates a per-NS Environment informer. Safe to call repeatedly — deduplicates via nsResolver. +// Creates a per-NS Environment informer. Safe to call repeatedly — deduplicates via env informer map. func (envw *environmentWatcher) AddNamespace(ctx context.Context, ns string, mgr manager.Interface) { - if !envw.nsResolver.AddNamespace(ns) { + if _, exists := envw.envWatchInformer[ns]; exists { return // already registered } envw.logger.Info("buildermgr.envWatcher.AddNamespace: setting up informer", zap.String("namespace", ns)) diff --git a/pkg/buildermgr/ns_watcher.go b/pkg/buildermgr/ns_watcher.go index 79597352..4f61b2ac 100644 --- a/pkg/buildermgr/ns_watcher.go +++ b/pkg/buildermgr/ns_watcher.go @@ -16,6 +16,7 @@ import ( "k8s.io/client-go/kubernetes" k8sCache "k8s.io/client-go/tools/cache" + "github.com/fission/fission/pkg/utils" "github.com/fission/fission/pkg/utils/manager" ) @@ -47,6 +48,7 @@ func StartNSWatcher( if ns == "" { return } + utils.DefaultNSResolver().AddNamespace(ns) envw.AddNamespace(ctx, ns, mgr) pkgw.AddNamespace(ctx, ns, mgr) }, @@ -55,6 +57,7 @@ func StartNSWatcher( if !ok || nsObj.Labels[builderManagedNSLabel] != "true" { return } + utils.DefaultNSResolver().AddNamespace(nsObj.Name) envw.AddNamespace(ctx, nsObj.Name, mgr) pkgw.AddNamespace(ctx, nsObj.Name, mgr) }, diff --git a/pkg/buildermgr/pkgwatcher.go b/pkg/buildermgr/pkgwatcher.go index c428c2f9..92eac0cc 100644 --- a/pkg/buildermgr/pkgwatcher.go +++ b/pkg/buildermgr/pkgwatcher.go @@ -333,9 +333,9 @@ func setInitialBuildStatus(ctx context.Context, fissionClient versioned.Interfac } // AddNamespace dynamically registers a new namespace in packageWatcher. -// Creates per-NS Package and Pod informers. Safe to call repeatedly. +// Creates per-NS Package and Pod informers. Safe to call repeatedly — deduplicates via local informer maps. func (pkgw *packageWatcher) AddNamespace(ctx context.Context, ns string, mgr manager.Interface) { - if !pkgw.nsResolver.AddNamespace(ns) { + if _, exists := pkgw.pkgInformer[ns]; exists { return // already registered } pkgw.logger.Info("buildermgr.pkgWatcher.AddNamespace: setting up informers", zap.String("namespace", ns))