A feed ingester may need to accept new feed URLs while also reporting failures from feeds already being processed. Waiting on either channel alone would leave the other kind of event unattended. A select statement lets one goroutine wait for multiple channel operations and proceed with one that is ready. section 9.4
func (a *App) run() {
for {
select { #1
case feed := <-a.feedRead: #2
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
go a.fetchFeed(ctx, feed)
cancel()
case err := <-a.errChan: #3
fmt.Println("error:", err)
}
}
}
The application loop receives a URL from feedRead or an error from errChan. The feed case starts a fetch; the error case reports the failure. The timeout context is created inside the feed case, not as another select case. section 9.4
Keep data and error reporting on separate channels so a failed fetch can report its error while other work continues. Other select cases can respond to cancellation; a default case permits a nonblocking operation. Handle errors explicitly and close channels when they are no longer needed. section 9.4 section 9.7








