layer1: add namespace manager subscribers step 9
This commit is contained in:
@@ -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`.
|
||||
@@ -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()
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user