Skip to content

Instantly share code, notes, and snippets.

@ahjdzx
Created December 22, 2018 15:31
Show Gist options
  • Select an option

  • Save ahjdzx/87cf6e044646fa7585ff2fa54f72a435 to your computer and use it in GitHub Desktop.

Select an option

Save ahjdzx/87cf6e044646fa7585ff2fa54f72a435 to your computer and use it in GitHub Desktop.
package async
import (
"context"
"log"
"runtime/debug"
"time"
)
// Repeat performs an action asynchronously on a predetermined interval.
func Repeat(ctx context.Context, interval time.Duration, action func()) context.CancelFunc {
// Create cancellation context first
ctx, cancel := context.WithCancel(ctx)
safeAction := func() {
defer handlePanic()
action()
}
// Perform the action for the first time, syncrhonously
safeAction()
timer := time.NewTicker(interval)
go func() {
for {
select {
case <-ctx.Done():
timer.Stop()
return
case <-timer.C:
safeAction()
}
}
}()
return cancel
}
// handlePanic handles the panic and logs it out.
func handlePanic() {
if r := recover(); r != nil {
log.Printf("panic recovered: %ss \n %s", r, debug.Stack())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment