diff --git a/doc/thinking/2026-04-26-namespace-manager-step19.md b/doc/thinking/2026-04-26-namespace-manager-step19.md new file mode 100644 index 00000000..0155199e --- /dev/null +++ b/doc/thinking/2026-04-26-namespace-manager-step19.md @@ -0,0 +1,16 @@ +# 2026-04-26 — NamespaceManager rewrite, step 19 + +## Цель шага + +Добавить functional adapter для `NamespaceSubscriber`. + +## Что меняем + +1. Добавляем `NamespaceSubscriberFuncs`. +2. Добавляем `Name()/OnNamespaceAdd()/OnNamespaceRemove()/OnNamespaceResync()`. +3. Добавляем unit tests. + +## Что НЕ меняем + +- не подключаем adapter к runtime; +- не меняем production watcher-ы. \ No newline at end of file diff --git a/pkg/utils/namespace_manager.go b/pkg/utils/namespace_manager.go index 705d2e15..dff6a9d2 100644 --- a/pkg/utils/namespace_manager.go +++ b/pkg/utils/namespace_manager.go @@ -14,6 +14,38 @@ type NamespaceSubscriber interface { OnNamespaceResync(ctx context.Context, record NamespaceRecord) error } +type NamespaceSubscriberFuncs struct { + SubscriberName string + AddFunc func(ctx context.Context, record NamespaceRecord) error + RemoveFunc func(ctx context.Context, record NamespaceRecord) error + ResyncFunc func(ctx context.Context, record NamespaceRecord) error +} + +func (s NamespaceSubscriberFuncs) Name() string { + return s.SubscriberName +} + +func (s NamespaceSubscriberFuncs) OnNamespaceAdd(ctx context.Context, record NamespaceRecord) error { + if s.AddFunc == nil { + return nil + } + return s.AddFunc(ctx, record) +} + +func (s NamespaceSubscriberFuncs) OnNamespaceRemove(ctx context.Context, record NamespaceRecord) error { + if s.RemoveFunc == nil { + return nil + } + return s.RemoveFunc(ctx, record) +} + +func (s NamespaceSubscriberFuncs) OnNamespaceResync(ctx context.Context, record NamespaceRecord) error { + if s.ResyncFunc == nil { + return nil + } + return s.ResyncFunc(ctx, record) +} + type NamespaceManager interface { Snapshot() []string SnapshotRecords() []NamespaceRecord diff --git a/pkg/utils/namespace_manager_test.go b/pkg/utils/namespace_manager_test.go index b812874c..193ac0ce 100644 --- a/pkg/utils/namespace_manager_test.go +++ b/pkg/utils/namespace_manager_test.go @@ -265,3 +265,35 @@ func TestNamespaceManagerDispatchResyncFailure(t *testing.T) { t.Fatalf("expected subscriber error to be stored") } } + +func TestNamespaceSubscriberFuncs(t *testing.T) { + addCalls := 0 + removeCalls := 0 + resyncCalls := 0 + subscriber := NamespaceSubscriberFuncs{ + SubscriberName: "router", + AddFunc: func(ctx context.Context, record NamespaceRecord) error { + addCalls++ + return nil + }, + RemoveFunc: func(ctx context.Context, record NamespaceRecord) error { + removeCalls++ + return nil + }, + ResyncFunc: func(ctx context.Context, record NamespaceRecord) error { + resyncCalls++ + return nil + }, + } + + if subscriber.Name() != "router" { + t.Fatalf("expected subscriber name router") + } + _ = subscriber.OnNamespaceAdd(context.Background(), NamespaceRecord{Name: "tenant-a"}) + _ = subscriber.OnNamespaceRemove(context.Background(), NamespaceRecord{Name: "tenant-a"}) + _ = subscriber.OnNamespaceResync(context.Background(), NamespaceRecord{Name: "tenant-a"}) + + if addCalls != 1 || removeCalls != 1 || resyncCalls != 1 { + t.Fatalf("expected all functional callbacks to run once") + } +}