From db4499d8c7d34459cbd51f8ae34b4709f9fe4ba9 Mon Sep 17 00:00:00 2001 From: Naeel Date: Sun, 26 Apr 2026 10:05:12 +0300 Subject: [PATCH] layer1: add namespace part helpers step 14 --- .../2026-04-26-namespace-manager-step14.md | 19 ++++++++++++++ pkg/utils/namespace_manager.go | 21 ++++++++++++++- pkg/utils/namespace_manager_test.go | 26 ++++++++++++++++++- 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 doc/thinking/2026-04-26-namespace-manager-step14.md diff --git a/doc/thinking/2026-04-26-namespace-manager-step14.md b/doc/thinking/2026-04-26-namespace-manager-step14.md new file mode 100644 index 00000000..d1e71e6b --- /dev/null +++ b/doc/thinking/2026-04-26-namespace-manager-step14.md @@ -0,0 +1,19 @@ +# 2026-04-26 — NamespaceManager rewrite, step 14 + +## Цель шага + +Добавить удобные helper-методы для part-state transitions. + +## Что меняем + +1. В manager interface добавляем: + - `MarkPartRegistering()` + - `MarkPartActive()` + - `MarkPartFailed()` +2. Реализуем их поверх `MarkPartState()`. +3. Добавляем unit tests. + +## Что НЕ меняем + +- не подключаем helpers к runtime reconcile; +- не трогаем watcher-ы и runtime components. \ No newline at end of file diff --git a/pkg/utils/namespace_manager.go b/pkg/utils/namespace_manager.go index e631e7c5..ea2d4a05 100644 --- a/pkg/utils/namespace_manager.go +++ b/pkg/utils/namespace_manager.go @@ -19,6 +19,9 @@ type NamespaceManager interface { SnapshotSubscribers() []string Upsert(event NamespaceEvent) NamespaceRecord MarkPartState(namespace string, part string, state NamespacePartState) (NamespaceRecord, bool) + MarkPartRegistering(namespace string, part string) (NamespaceRecord, bool) + MarkPartActive(namespace string, part string) (NamespaceRecord, bool) + MarkPartFailed(namespace string, part string, err error) (NamespaceRecord, bool) Remove(name string) bool } @@ -184,6 +187,22 @@ func (m *inMemoryNamespaceManager) MarkPartState(namespace string, part string, return record.Clone(), true } +func (m *inMemoryNamespaceManager) MarkPartRegistering(namespace string, part string) (NamespaceRecord, bool) { + return m.MarkPartState(namespace, part, NamespacePartState{State: NamespacePartStateRegistering}) +} + +func (m *inMemoryNamespaceManager) MarkPartActive(namespace string, part string) (NamespaceRecord, bool) { + return m.MarkPartState(namespace, part, NamespacePartState{State: NamespacePartStateActive}) +} + +func (m *inMemoryNamespaceManager) MarkPartFailed(namespace string, part string, err error) (NamespaceRecord, bool) { + lastError := "" + if err != nil { + lastError = err.Error() + } + return m.MarkPartState(namespace, part, NamespacePartState{State: NamespacePartStateFailed, LastError: lastError}) +} + func (m *inMemoryNamespaceManager) Remove(name string) bool { m.mu.Lock() defer m.mu.Unlock() @@ -219,4 +238,4 @@ func deriveNamespacePhase(record NamespaceRecord) NamespacePhase { } return NamespacePhaseActive -} \ No newline at end of file +} diff --git a/pkg/utils/namespace_manager_test.go b/pkg/utils/namespace_manager_test.go index d27d983d..1b224ad3 100644 --- a/pkg/utils/namespace_manager_test.go +++ b/pkg/utils/namespace_manager_test.go @@ -1,6 +1,7 @@ package utils import ( + "errors" "reflect" "testing" "time" @@ -159,6 +160,29 @@ func TestNamespaceManagerBootstrap(t *testing.T) { } } +func TestNamespaceManagerPartStateHelpers(t *testing.T) { + manager := NewNamespaceManager() + manager.Upsert(NamespaceEvent{Type: NamespaceEventAdd, Name: "tenant-a", Source: NamespaceSourceWatcher}) + + record, ok := manager.MarkPartRegistering("tenant-a", "router") + if !ok || record.Phase != NamespacePhaseRegistering { + t.Fatalf("expected registering helper to set registering phase") + } + + record, ok = manager.MarkPartActive("tenant-a", "router") + if !ok || record.Phase != NamespacePhaseActive { + t.Fatalf("expected active helper to set active phase") + } + + record, ok = manager.MarkPartFailed("tenant-a", "router", errors.New("boom")) + if !ok || record.Phase != NamespacePhaseFailed { + t.Fatalf("expected failed helper to set failed phase") + } + if record.RegisteredParts["router"].LastError != "boom" { + t.Fatalf("expected failed helper to persist error") + } +} + func TestNewBootstrappedNamespaceManager(t *testing.T) { resolver := &NamespaceResolver{ FissionResourceNS: map[string]string{ @@ -178,4 +202,4 @@ func TestNewBootstrappedNamespaceManager(t *testing.T) { if record.Source != NamespaceSourceEnv { t.Fatalf("expected env source, got %s", record.Source) } -} \ No newline at end of file +}