In order to limit the number of tries, we simply need to count the attempts made, which is trivial with the existing for loop.
It appears with the stop
channel that you intend to make this cancellable as well, but the usage here will not work as expected. You can use a context.Context
for this, which can be later incorporated into other calls that accept a context. Otherwise a sync.WaitGroup
is the expected method to wait for completion.
Waiting for the goroutine to return can be done with a channel, but you should not rely on sending a single value. As shown in your example, multiple readers (which may have been added later due to refactoring) will cause the other to not receive the signal. If you do use a channel, closing the channel is the canonical way to broadcast a signal.
Using that information, we can come up with this modified example:
https://play.golang.org/p/hZiRXtMm-SB
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
maxAttempts := 5
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
ticker := time.NewTicker(1000 * time.Millisecond)
call(1)
for i := 1; ; i++ {
if i >= maxAttempts {
fmt.Println("too many tries")
return
}
select {
case <-ctx.Done():
fmt.Println("cancelled")
return
case <-ticker.C:
randInt := get()
call(randInt)
if randInt == 11 {
fmt.Println("OK")
return
}
}
}
}()
wg.Wait()
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…