diff --git a/doc/thinking/2026-04-26-namespace-manager-step29.md b/doc/thinking/2026-04-26-namespace-manager-step29.md new file mode 100644 index 00000000..137530fa --- /dev/null +++ b/doc/thinking/2026-04-26-namespace-manager-step29.md @@ -0,0 +1,19 @@ +# 2026-04-26 — NamespaceManager rewrite, step 29 + +## Цель шага + +Перевести `executor/multitenant` watcher на тот же manager flow, что уже используется в `buildermgr` и `router`. + +## Что меняем + +1. `StartNSWatcher()` поднимает локальный `NamespaceManager`. +2. Manager bootstrapped из resolver snapshot. +3. Watcher `Add/Update` события прогоняет через: + - `Upsert()` + - `DispatchAdd()` или `DispatchResync()` +4. Подписчиком manager-а становится executor subscriber adapter. + +## Что НЕ меняем + +- не добавляем remove path; +- не меняем `registerNamespace()` и низкоуровневый executor registration helper. \ No newline at end of file diff --git a/pkg/executor/multitenant/ns_watcher.go b/pkg/executor/multitenant/ns_watcher.go index 86fce199..6a41e712 100644 --- a/pkg/executor/multitenant/ns_watcher.go +++ b/pkg/executor/multitenant/ns_watcher.go @@ -93,6 +93,9 @@ func StartNSWatcher( executorTypes map[fv1.ExecutorType]executortype.ExecutorType, mgr manager.Interface, ) { + nsManager := utils.NewBootstrappedNamespaceManager(utils.DefaultNSResolver(), utils.NamespaceSourceEnv, time.Now().UTC()) + nsManager.Subscribe(NewNamespaceSubscriber(logger, kubernetesClient, executorTypes, mgr)) + // Use a label-filtered informer so only Namespaces with our label are delivered. // The resync period of 30m is standard for Fission informers — it re-lists to recover // from any missed events, but normal operation is purely event-driven (no ticking). @@ -109,11 +112,15 @@ func StartNSWatcher( _, _ = nsInformer.AddEventHandler(k8sCache.ResourceEventHandlerFuncs{ // AddFunc fires when a new Namespace with the label appears. AddFunc: func(obj interface{}) { - ns := namespaceName(obj) - if ns == "" { + nsObj, ok := obj.(*corev1.Namespace) + if !ok || nsObj.Name == "" { return } - registerNamespace(ctx, logger, kubernetesClient, ns, executorTypes, mgr) + nsManager.Upsert(utils.NamespaceEventFromNamespace(utils.NamespaceEventAdd, nsObj, utils.NamespaceSourceWatcher, time.Now().UTC())) + if _, _, err := nsManager.DispatchAdd(ctx, nsObj.Name); err != nil { + logger.Error("multitenant.NSWatcher: DispatchAdd failed", + zap.String("namespace", nsObj.Name), zap.Error(err)) + } }, // UpdateFunc fires when an existing Namespace is updated — covers the case // where the label is added to a pre-existing Namespace. @@ -125,7 +132,11 @@ func StartNSWatcher( if !utils.IsManagedNamespace(nsObj.Labels) { return // label was removed — nothing to do (executor keeps existing registrations) } - registerNamespace(ctx, logger, kubernetesClient, nsObj.Name, executorTypes, mgr) + nsManager.Upsert(utils.NamespaceEventFromNamespace(utils.NamespaceEventUpdate, nsObj, utils.NamespaceSourceWatcher, time.Now().UTC())) + if _, _, err := nsManager.DispatchResync(ctx, nsObj.Name); err != nil { + logger.Error("multitenant.NSWatcher: DispatchResync failed", + zap.String("namespace", nsObj.Name), zap.Error(err)) + } }, })