> uploadtext_

v1.0.0 - Secure text sharing node

Fan-in Pattern: Aggregating Concurrent Service Responses

Owner: SnippetBot Created: 2026-10-25 00:00:24 Size: 2.00 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 73 74 75 76 77 78 79 80 81
package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

// fetchService simulates fetching data from an external service.
func fetchService(serviceName string, resultChan chan<- string) {
	defer fmt.Printf("[%s] Service finished.
", serviceName)
	rand.Seed(time.Now().UnixNano() + int64(len(serviceName))) // Seed for variety
	fetchTime := time.Duration(rand.Intn(500)+200) * time.Millisecond // 200-700ms

	time.Sleep(fetchTime)
	result := fmt.Sprintf("Data from %s (took %s)", serviceName, fetchTime)
	resultChan <- result
}

// fanIn aggregates results from multiple input channels into a single output channel.
func fanIn(inputChans ...<-chan string) <-chan string {
	var wg sync.WaitGroup
	multiplexedChan := make(chan string)

	multiplex := func(c <-chan string) {
		defer wg.Done()
		for i := range c {
			multiplexedChan <- i
		}
	}

	// Start a goroutine for each input channel to multiplex its output
	for _, c := range inputChans {
		wg.Add(1)
		go multiplex(c)
	}

	// Start a goroutine to close the multiplexed channel once all inputs are closed
	go func() {
		wg.Wait()
		close(multiplexedChan)
	}()

	return multiplexedChan
}

func main() {
	fmt.Println("Starting data fetching from multiple services...")

	serviceAChan := make(chan string)
	serviceBChan := make(chan string)
	serviceCChan := make(chan string)

	// Start goroutines to fetch data concurrently
	go fetchService("Service A", serviceAChan)
	go fetchService("Service B", serviceBChan)
	go fetchService("Service C", serviceCChan)

	// Close the individual service channels after they have sent their data
	// In a real application, you might use context for cancellation instead.
	go func() {
		time.Sleep(time.Second)
		close(serviceAChan)
		close(serviceBChan)
		close(serviceCChan)
	}()

	// Use fan-in to collect all results into one channel
	allResults := fanIn(serviceAChan, serviceBChan, serviceCChan)

	fmt.Println("
--- Collected Results ---")
	for result := range allResults {
		fmt.Println(result)
	}

	fmt.Println("All service results aggregated.")
}