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"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type NamespaceSubscriber interface {
|
||||||
|
Name() string
|
||||||
|
}
|
||||||
|
|
||||||
type NamespaceManager interface {
|
type NamespaceManager interface {
|
||||||
Snapshot() []string
|
Snapshot() []string
|
||||||
SnapshotRecords() []NamespaceRecord
|
SnapshotRecords() []NamespaceRecord
|
||||||
Get(name string) (NamespaceRecord, bool)
|
Get(name string) (NamespaceRecord, bool)
|
||||||
|
Subscribe(subscriber NamespaceSubscriber)
|
||||||
|
SnapshotSubscribers() []string
|
||||||
Upsert(event NamespaceEvent) NamespaceRecord
|
Upsert(event NamespaceEvent) NamespaceRecord
|
||||||
MarkPartState(namespace string, part string, state NamespacePartState) (NamespaceRecord, bool)
|
MarkPartState(namespace string, part string, state NamespacePartState) (NamespaceRecord, bool)
|
||||||
Remove(name string) bool
|
Remove(name string) bool
|
||||||
@@ -18,14 +24,34 @@ type NamespaceManager interface {
|
|||||||
type inMemoryNamespaceManager struct {
|
type inMemoryNamespaceManager struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
records map[string]NamespaceRecord
|
records map[string]NamespaceRecord
|
||||||
|
subs map[string]NamespaceSubscriber
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNamespaceManager() NamespaceManager {
|
func NewNamespaceManager() NamespaceManager {
|
||||||
return &inMemoryNamespaceManager{
|
return &inMemoryNamespaceManager{
|
||||||
records: make(map[string]NamespaceRecord),
|
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 {
|
func (m *inMemoryNamespaceManager) Snapshot() []string {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|||||||
@@ -6,6 +6,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type testNamespaceSubscriber struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s testNamespaceSubscriber) Name() string {
|
||||||
|
return s.name
|
||||||
|
}
|
||||||
|
|
||||||
func TestNamespaceManagerSnapshotAndGet(t *testing.T) {
|
func TestNamespaceManagerSnapshotAndGet(t *testing.T) {
|
||||||
manager := NewNamespaceManager()
|
manager := NewNamespaceManager()
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
@@ -94,3 +102,15 @@ func TestNamespaceManagerSnapshotRecordsReturnsCopies(t *testing.T) {
|
|||||||
t.Fatalf("expected part states to be detached copies")
|
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