layer1: add namespace manager subscribers step 9

This commit is contained in:
Naeel
2026-04-26 10:01:21 +03:00
parent 114d5b99af
commit 910f65b6d4
3 changed files with 66 additions and 0 deletions
@@ -0,0 +1,20 @@
# 2026-04-26 — NamespaceManager rewrite, step 9
## Цель шага
Добавить subscriber contract в `NamespaceManager`, не подключая его пока к runtime.
## Что меняем
1. Добавляем interface `NamespaceSubscriber`.
2. Добавляем в manager операции:
- `Subscribe()`
- `SnapshotSubscribers()`
3. Добавляем unit tests на регистрацию и snapshot subscriber-ов.
## Что НЕ меняем
- не вызываем subscriber-ов из watcher-ов;
- не строим reconcile loop;
- не трогаем runtime components;
- не затрагиваем внешнее изменение в `serviceaccount.go`.
+26
View File
@@ -6,10 +6,16 @@ import (
"time"
)
type NamespaceSubscriber interface {
Name() string
}
type NamespaceManager interface {
Snapshot() []string
SnapshotRecords() []NamespaceRecord
Get(name string) (NamespaceRecord, bool)
Subscribe(subscriber NamespaceSubscriber)
SnapshotSubscribers() []string
Upsert(event NamespaceEvent) NamespaceRecord
MarkPartState(namespace string, part string, state NamespacePartState) (NamespaceRecord, bool)
Remove(name string) bool
@@ -18,14 +24,34 @@ type NamespaceManager interface {
type inMemoryNamespaceManager struct {
mu sync.RWMutex
records map[string]NamespaceRecord
subs map[string]NamespaceSubscriber
}
func NewNamespaceManager() NamespaceManager {
return &inMemoryNamespaceManager{
records: make(map[string]NamespaceRecord),
subs: make(map[string]NamespaceSubscriber),
}
}
func (m *inMemoryNamespaceManager) Subscribe(subscriber NamespaceSubscriber) {
m.mu.Lock()
defer m.mu.Unlock()
m.subs[subscriber.Name()] = subscriber
}
func (m *inMemoryNamespaceManager) SnapshotSubscribers() []string {
m.mu.RLock()
defer m.mu.RUnlock()
names := make([]string, 0, len(m.subs))
for name := range m.subs {
names = append(names, name)
}
sort.Strings(names)
return names
}
func (m *inMemoryNamespaceManager) Snapshot() []string {
m.mu.RLock()
defer m.mu.RUnlock()
+20
View File
@@ -6,6 +6,14 @@ import (
"time"
)
type testNamespaceSubscriber struct {
name string
}
func (s testNamespaceSubscriber) Name() string {
return s.name
}
func TestNamespaceManagerSnapshotAndGet(t *testing.T) {
manager := NewNamespaceManager()
now := time.Now().UTC()
@@ -93,4 +101,16 @@ func TestNamespaceManagerSnapshotRecordsReturnsCopies(t *testing.T) {
if record.RegisteredParts["router"].State != "active" {
t.Fatalf("expected part states to be detached copies")
}
}
func TestNamespaceManagerSubscribers(t *testing.T) {
manager := NewNamespaceManager()
manager.Subscribe(testNamespaceSubscriber{name: "router"})
manager.Subscribe(testNamespaceSubscriber{name: "buildermgr"})
manager.Subscribe(testNamespaceSubscriber{name: "router"})
expected := []string{"buildermgr", "router"}
if !reflect.DeepEqual(expected, manager.SnapshotSubscribers()) {
t.Fatalf("expected subscribers %v, got %v", expected, manager.SnapshotSubscribers())
}
}