Re:Go Concurrency Patterns: Pipelines and cancellation
by Sajmani on Friday March 14, 2014 @07:09AM
(#7397976)
Yes, interrupt is better, and the article explains how to do that a few paragraphs later:
for n := range in {
select {
case out <- n * n:
case <-done:
return
}
}
If you allow pipeline stages to interrupt their receive loop instead of draining the inbound channel, then _all_ send operations need to be governed by done. Otherwise the interrupted receive loop may block the upstream sender.
Re:Go Concurrency Patterns: Pipelines and cancellation
by songgao on Saturday March 15, 2014 @01:20PM
(#7405247)
The loop (particularly `range c`) keeps getting element out of `c` and assigning it to `n`. If it's "done", then `n` wouldn't be sent into `out`, but still gets read from the channel `c` constantly. In other words, it's the loop itself that makes sure everything sent into channel `c` is consumed.
If `break` is used, for loop is terminated once it's "done", hence nothing would be reading from channel `c`. The previous station in the pipeline would then block at sending operation.
Now I can see it allows you do "discard" all the pending reads from the input channel (and avoid writing to a possibly-closed 'out' channel), but wouldn't it be better to break the loop in this case for an immediate exit?
i.e. go for 'interrupt' semantics, rather than 'drain'?