Expected: To be done after approx. 2 seconds
Actual: Runs indefinitely.
Don't understand what could be causing it to run indefinitely.
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
for i := range generator(ctx) {
select {
case <-time.After(2 * time.Second):
cancel()
return
default:
fmt.Println(i)
}
}
}
func generator(ctx context.Context) <-chan int {
ch := make(chan int)
go func() {
count := 0
for {
select {
case <-ctx.Done():
return
case ch <- count:
count++
}
}
}()
return ch
}
The main issue is that your channel returned from generator(ctx)
emits values almost as fast as you can read them.
The channel created by time.After(2 * time.Second)
is discarded almost immediately, and you create a new timeout channel every iteration through the generator.
If you make one small change; create the timeout channel outside the loop, and then put it in the select clause you'll see it begin to work.
timeout := time.After(2 * time.Second)
for i := range generator(ctx) {
select {
case <-timeout:
cancel()
return
default:
fmt.Println(i)
}
}