diff options
Diffstat (limited to 'defer_after.go')
| -rw-r--r-- | defer_after.go | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/defer_after.go b/defer_after.go new file mode 100644 index 0000000..ce20f81 --- /dev/null +++ b/defer_after.go @@ -0,0 +1,66 @@ +package argvpb + +import ( + "fmt" + "time" +) + +// RunIfTakesLonger schedules a function `f` to run after a duration `d`. +// It returns a "cancel" function. If the cancel function is called before +// the duration `d` has passed, the scheduled function `f` will not be executed. +// +// This is designed to be used with defer, like so: +// +// func myFunc() { +// cancel := RunIfTakesLonger(time.Second, func() { +// fmt.Println("myFunc took more than a second!") +// }) +// defer cancel() +// +// // ... rest of the function +// } +func RunIfTakesLonger(d time.Duration, f func()) (cancel func()) { + // time.AfterFunc executes a function in its own goroutine after the + // specified duration. It returns a Timer that can be used to cancel it. + timer := time.AfterFunc(d, f) + + // We return a function that stops the timer. + // The caller is expected to call this function using `defer`. + return func() { + // The Stop method returns true if it successfully prevented the + // timer from firing. We don't need the return value here, but it's + // useful for understanding. + timer.Stop() + } +} + +// A task that takes less time than the timeout. +func shortTask() { + fmt.Println("--- Running shortTask (will take 500ms) ---") + cancel := RunIfTakesLonger(time.Second, func() { + fmt.Println("!!! This should NOT be printed !!!") + }) + defer cancel() + + fmt.Println("shortTask: working...") + time.Sleep(500 * time.Millisecond) + fmt.Println("shortTask: finished.") +} + +// A task that takes more time than the timeout. +func longTask() { + fmt.Println("\n--- Running longTask (will take 2 seconds) ---") + cancel := RunIfTakesLonger(time.Second, func() { + fmt.Println(">>> longTask took more than 1 second! Clean-up function executed. <<<") + }) + defer cancel() + + fmt.Println("longTask: working...") + time.Sleep(2 * time.Second) + fmt.Println("longTask: finished.") +} + +func main() { + shortTask() + longTask() +} |
