package feed import ( "sync" ) // MultiSource combines events from multiple EventSources into a single stream. type MultiSource struct { sources []EventSource events chan Event done chan struct{} wg sync.WaitGroup } // NewMultiSource creates a new multi-source that combines events from all given sources. func NewMultiSource(sources ...EventSource) *MultiSource { m := &MultiSource{ sources: sources, events: make(chan Event, 100), done: make(chan struct{}), } // Start a goroutine for each source to forward events for _, src := range sources { if src == nil { continue } m.wg.Add(1) go m.forwardEvents(src) } // Close events channel when all sources are done go func() { m.wg.Wait() close(m.events) }() return m } // forwardEvents reads from a source and forwards to the combined channel. func (m *MultiSource) forwardEvents(src EventSource) { defer m.wg.Done() srcEvents := src.Events() for { select { case event, ok := <-srcEvents: if !ok { return } select { case m.events <- event: case <-m.done: return } case <-m.done: return } } } // Events returns the combined event channel. func (m *MultiSource) Events() <-chan Event { return m.events } // Close stops all sources. func (m *MultiSource) Close() error { close(m.done) var lastErr error for _, src := range m.sources { if src != nil { if err := src.Close(); err != nil { lastErr = err } } } return lastErr }