I have a function checkSuccess()
which return true if the task have finished.
I'd like to call checkSuccess()
every 1 second and break until it return true
or timeout.
What I'm having now is to use a goroutine to run a for loop, in which I call checkSuccess()
every 1 second. And in the main process, I use time.After
to check if the whole checking duration has passed timeout.
func myfunc (timeout time.Duration) {
successChan := make(chan struct{})
timeoutChan := make(chan struct{})
// Keep listening to the task.
go func() {
for {
select {
// Exit the forloop if the timeout has been reached
case <-timeoutChan:
return
default:
}
// Early exit if task has succeed.
if checkSuccess() {
close(successChan)
return
}
time.Sleep(time.Second)
}
}()
// Once timeout, stop listening to the task.
select {
case <-time.After(timeout):
close(timeoutChan)
return
case <-successChan:
return
}
return
}
It actually has achieved my goal, but I found it very tedious. Is there any better (shorter) way to write it?
You don't need a separate goroutine or channels:
func myfunc (timeout time.Duration) {
ticker:=time.NewTicker(time.Second)
defer ticker.Close()
to:=time.NewTimer(timeout)
defer to.Stop()
for {
select {
case <-to.C:
return // timeout
case <-ticker:
if checkSuccess() {
return
}
}
}
}
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