Uh... isn't this a race condition? EDIT: Oh, wait, "die" is unbuffered... But if you have more than one worker it is a race condition though, unless I'm overlooking something else as well.
func worker(die chan bool) {
for {
select {
// ... do stuff cases
case <-die:
// ... do termination tasks
die <- true
return
}
}
}
func main() {
die := make(chan bool)
go worker(die)
die <- true
<-die
}
You would not want to share a die channel like that with multiple workers because when doing die <- true you would not know which one received it.
As I said early on in the presentation using unbuffered channels is 'best' because it makes reasoning about concurrency easy. Given that die is unbuffered the die <- true has to synchronize with something in order to happen; that something is the case <-die. If die were buffered then this example would simply not work.
I realise that, I just find the example interesting because I often would expect to use a whole pool of workers, not just one. The close(start) idiom you used earlier makes more sense in that context (but in a close(die) form).