Concurrency and Replicated Requests, what is time.After() for?
I'm reading concurrency in Go and getting very close to the end! Overall it's been a great read. In one of the examples, the author is describing how to simulate request replication. The code example is this:
func main() {
doWork := func(
done <-chan interface{},
id int,
wg *sync.WaitGroup,
result chan<- int,
) {
started := time.Now()
defer wg.Done()
// Simulate random load
simulatedLoadTime := time.Duration(1*rand.Intn(5)) * time.Second
/** use two separate select blocks because we want to send/receive two different values, the time.After (receive) and the id (send).
/ if they were in the same select block, then we could only use one value at a time, the other will get lost. */
select {
// do not want to return on <-done because we still want to log the time it took
case <-done:
case <-time.After(simulatedLoadTime):
}
select {
case <-done:
case result <- id:
}
took := time.Since(started)
// Display how long handlers would have taken
if took < simulatedLoadTime {
took = simulatedLoadTime
}
fmt.Printf("%v took %v\n", id, took)
}
done := make(chan interface{})
result := make(chan int)
var wg sync.WaitGroup
wg.Add(10)
for i := 0; i < 10; i++ {
go doWork(done, i, &wg, result)
}
firstReturned := <-result
close(done)
wg.Wait()
fmt.Printf("Received an answer from #%v\n", firstReturned)
}
The one line I don't understand is case <-time.After(simulatedLoadTime). Why is this here? When are we ever making use of the value being returned from that channel. How is that channel even being communicated outside of the select block? For whatever reason, that line seems to be pretty integral in synchronizing the timing of results, because if I were to replace it with a default: the results are out of sync.
from Recent Questions - Stack Overflow https://ift.tt/2KT8NFh
https://ift.tt/eA8V8J
Comments
Post a Comment