I have a loop that iterates until a job is up and running:
ticker := time.NewTicker(time.Second * 2) defer ticker.Stop() started := time.Now() for now := range ticker.C { job, err := client.Job(jobID) switch err.(type) { case DoesNotExistError: continue case InternalError: return err } if job.State == "running" { break } if now.Sub(started) > time.Minute*2 { return fmt.Errorf("timed out waiting for job") } }
Works great in production. The only problem is that it makes my tests slow. They all wait at least 2 seconds before completing. Is there anyway to get time.Tick
to tick immediately?
Unfortunately, it seems that Go developers will not add such functionality in any foreseeable future, so we have to cope...
There are two common ways to use tickers:
for
loopGiven something like this:
ticker := time.NewTicker(period) defer ticker.Stop() for <- ticker.C { ... }
Use:
ticker := time.NewTicker(period) defer ticker.Stop() for ; true; <- ticker.C { ... }
for
-select
loopGiven something like this:
interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt) ticker := time.NewTicker(period) defer ticker.Stop() loop: for { select { case <- ticker.C: f() case <- interrupt: break loop } }
Use:
interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt) ticker := time.NewTicker(period) defer ticker.Stop() loop: for { f() select { case <- ticker.C: continue case <- interrupt: break loop } }
time.Tick()
?While Tick is useful for clients that have no need to shut down the Ticker, be aware that without a way to shut it down the underlying Ticker cannot be recovered by the garbage collector; it "leaks".
https://golang.org/pkg/time/#Tick
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