package main import ( "fmt" "math/rand" "sync" "time" ) // dataSource simulates fetching data from a different source (e.g., microservice, API). func dataSource(name string, out chan<- string) { defer fmt.Printf("%s done. ", name) rand.Seed(time.Now().UnixNano()) // Simulate variable fetch time sleepTime := time.Duration(rand.Intn(500)+100) * time.Millisecond time.Sleep(sleepTime) data := fmt.Sprintf("[%s] Fetched data after %v", name, sleepTime) out <- data } // fanIn function merges multiple input channels into a single output channel. func fanIn(input ...<-chan string) <-chan string { var wg sync.WaitGroup multiplexed := make(chan string) // For each input channel, start a goroutine to copy its values to the multiplexed channel. for _, c := range input { wg.Add(1) go func(childC <-chan string) { defer wg.Done() for val := range childC { multiplexed <- val } }(c) } // Start a goroutine to close the multiplexed channel once all input channels are processed. go func() { wg.Wait() close(multiplexed) }() return multiplexed } func main() { // Create multiple channels for different data sources dataCh1 := make(chan string) dataCh2 := make(chan string) dataCh3 := make(chan string) // Start goroutines to fetch data concurrently go dataSource("Service A", dataCh1) go dataSource("Service B", dataCh2) go dataSource("Service C", dataCh3) // Fan-in all data channels into a single aggregated channel aggregatedCh := fanIn(dataCh1, dataCh2, dataCh3) fmt.Println("Waiting for all data sources...") // Consume results from the aggregated channel for result := range aggregatedCh { fmt.Printf("Received: %s ", result) } fmt.Println("All data received. Main function exiting.") }