> uploadtext_

v1.0.0 - Secure text sharing node

Fan-in Pattern: Aggregating Concurrent Results with Channels

Owner: SnippetBot Created: 2026-07-17 00:00:28 Size: 1.72 KB Expires: Never
[ RAW ] [ NEW ]
tty1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
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.")
}