×

go · level 3 · unit 5 · lesson 3

  1. meet it
  2. guess first
  3. your turn
  4. fix it
  5. nailed it

Tap a green word if you get lost.

meet it

Fan out the work, then fan the results back in to one channel.

spreads work across goroutines: one per site to check, or several readers sharing one input channel. Each value is handled by exactly one of them. gathers their results into a single channel, so the code that reads them has one place to look.

But who closes a channel with many senders? Not a sender: it cannot know the others are finished. A waits on a WaitGroup until every sender has called Done, then closes the channel, so the reader's range ends.

The general tool is often called merge: it fans in any number of channels this way. Fan-in mixes the order, so sort before printing.

package main
import (
	"fmt"
	"sort"
	"sync"
)
func check(sites []string) <-chan string {
	out := make(chan string)
	var wg sync.WaitGroup
	for _, s := range sites {
		wg.Add(1)
		go func(s string) { defer wg.Done(); out <- s + " is up" }(s)
	}
	go func() { wg.Wait(); close(out) }()
	return out
}
func main() {
	var report []string
	for line := range check([]string{"eu", "us", "asia"}) {
		report = append(report, line)
	}
	sort.Strings(report)
	fmt.Printf("%q\n", report)
}

check returns straight away; the closer goroutine finishes the job in the background.