I'm writing something that reads lines from os.Stdin
using a bufio.Scanner
like:
for s.scanner.Scan() {
line := s.scanner.Text()
// process line
}
This is running in a goroutine and I want to be able to stop it when a chan struct{}
closes. However as Scan
blocks until there is another line, I'm at a loss as how to stop it, if there is no more input, it'll block indefinitely.
Can anyone point me in the right direction here?
By creating one more indirection and ignoring the underlying, we can stop.
// actual reading, converts input stream to a channel
func readUnderlying(lines chan interface{}) {
s := bufio.NewScanner(os.Stdin)
for s.Scan() {
lines <- s.Text()
}
lines <- s.Err()
}
func read(stop chan struct{}) {
input := make(chan interface{}) // input stream
go readUnderlying(input) // go and read
for {
select { // read or close
case lineOrErr := <-input:
fmt.Println(lineOrErr)
case <-stop:
return
}
}
}
func main() {
stop := make(chan struct{})
go read(stop)
// wait some to simulate blocking
time.Sleep(time.Second * 20) // it will print what is given
close(stop)
time.Sleep(time.Second * 20) // stopped so no more processing
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With