There are two issues with using time.Sleep
in the way you envision, one major and one minor.
You have no way to terminate the goroutine
The goroutine is stuck in an infinite loop, so unless doJob
panics, it will never terminate. You should probably pass it a channel that will be closed when the goroutine needs to terminate:
done := make(chan struct{})
go worker(done)
...
close(done)
...
func worker(done <-chan struct{}){
for {
doJob()
timer := time.NewTimer(time.Hour)
select {
case <-timer.C:
// nothing
case <-done:
timer.Stop()
return
}
}
}
Or, better yet, using a ticker:
func worker(done <-chan struct{}){
ticker := time.NewTicker(time.Hour)
for {
doJob()
select {
case <-ticker.C:
// nothing
case <-done:
ticker.Stop()
return
}
}
}
It is good style here to use defer
:
func worker(done <-chan struct{}){
ticker := time.NewTicker(time.Hour)
defer ticker.Stop()
for {
doJob()
select {
case <-ticker.C:
// nothing
case <-done:
return
}
}
}
You're wasting a stack
While a goroutine uses negligible CPU resources, it uses a stack, on the order of a dozen kilobytes or so. That's probably not a problem for you, but if it is, and if your application has a main loop, then you can insert your ticker and invocation of doWork
into the main select
statement of the main loop.