There is an API that I need to periodically poll in order to check the status message.
ticker := time.NewTicker(time.Second * tickerWaitTimeSeconds)
defer ticker.Stop()
for range ticker.C {
res, err := r.client.Get(someURL)
if err != nil {
results <- err
return
}
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
results <- err
return
}
status := response.Data.Attributes.CompleteStatus
if status == "COMPLETED" {
results <- nil
return
}
if status == "ERROR" {
results <- ErrFailedJob
return
}
It has worked in quite a stable way so far, but there is one possible catch if I understand how tickers work correctly.
There is this constant tickerWaitTimeSeconds that is currently set to 2 seconds. The value was chosen in such a way that the request has enough time to succeed (it's not even close to 1 second, not to mention 2) and we don't spam the API.
I suspect, however, that if for some reason the request takes longer than tickerWaitTimeSeconds there might be more GET requests to the API than necessary.
Is my suspicion valid in this case? Probably, there is something wrong with my understanding of what really happens and the Get call blocks the ticker, but I doubt that's the case.
CodePudding user response:
Based on the ticker documentation:
The ticker will adjust the time interval or drop ticks to make up for slow receivers.
So the ticker should drop ticks if Get takes longer than tick interval. The Get call is not run in a separate goroutine, so you cannot submit more than one request at any given time. It may be that if one Get lasts 3 seconds, the next Get happens 1 second after the first one. If you want to call the API at least 2 seconds after the completion of the previous call, reset the ticker at each iteration.
CodePudding user response:
Why do you need a ticker? Wouldn't it be easier to use time.Sleep()?
Something like this:
import (
"fmt"
"time"
)
func ticktock( d time.Duration ) {
for true {
doSomethingUseful()
time.Sleep(d)
}
}
See it in action at https://go.dev/play/p/xtg6bqNdwuk
You might want to track the elapsed time required to doSomethingUseful() and deduct that from the sleep interval, so you'd never sleep more than the specified duration, but you might sleep less.
