feat(provider): add iterator for provider info summaries

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 22:19:56 +00:00
parent 1a8fafeec5
commit f0d25392a8
2 changed files with 68 additions and 0 deletions

View file

@ -153,6 +153,40 @@ func (r *Registry) Info() []ProviderInfo {
return infos
}
// InfoIter returns an iterator over all registered provider summaries.
// The iterator snapshots the current registry contents so callers can range
// over it without holding the registry lock.
func (r *Registry) InfoIter() iter.Seq[ProviderInfo] {
r.mu.RLock()
providers := slices.Clone(r.providers)
r.mu.RUnlock()
return func(yield func(ProviderInfo) bool) {
for _, p := range providers {
info := ProviderInfo{
Name: p.Name(),
BasePath: p.BasePath(),
}
if s, ok := p.(Streamable); ok {
info.Channels = s.Channels()
}
if rv, ok := p.(Renderable); ok {
elem := rv.Element()
info.Element = &elem
}
if sf, ok := p.(interface{ SpecFile() string }); ok {
info.SpecFile = sf.SpecFile()
}
if up, ok := p.(interface{ Upstream() string }); ok {
info.Upstream = up.Upstream()
}
if !yield(info) {
return
}
}
}
}
// SpecFiles returns all non-empty provider OpenAPI spec file paths.
// The result is deduplicated and sorted for stable discovery output.
func (r *Registry) SpecFiles() []string {

View file

@ -173,6 +173,40 @@ func TestRegistry_Info_Good_ProxyMetadata(t *testing.T) {
assert.Equal(t, "http://127.0.0.1:9999", info.Upstream)
}
func TestRegistry_InfoIter_Good(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&fullProvider{})
var infos []provider.ProviderInfo
for info := range reg.InfoIter() {
infos = append(infos, info)
}
require.Len(t, infos, 1)
info := infos[0]
assert.Equal(t, "full", info.Name)
assert.Equal(t, "/api/full", info.BasePath)
assert.Equal(t, []string{"stub.event"}, info.Channels)
require.NotNil(t, info.Element)
assert.Equal(t, "core-full-panel", info.Element.Tag)
}
func TestRegistry_InfoIter_Good_SnapshotCurrentProviders(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&fullProvider{})
iter := reg.InfoIter()
reg.Add(&specFileProvider{specFile: "/tmp/later.json"})
var infos []provider.ProviderInfo
for info := range iter {
infos = append(infos, info)
}
require.Len(t, infos, 1)
assert.Equal(t, "full", infos[0].Name)
}
func TestRegistry_Iter_Good(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&stubProvider{})