There is a function `unpredictableFunc()`, which needs to be wrapped so that it executes with a timeout (for example, 1 second), and its execution time is logged.
// There is a function that runs indefinitely long and returns a number.
// Its body cannot be changed (imagine it as a network request).
func unpredictableFunc() int64 {
rnd := rand.Int63n(5000)
time.Sleep(time.Duration(rnd) * time.Millisecond)
return rnd
}
// You need to modify the wrapper function to work with a specified timeout (for example, 1 second).
// If the "long" function completes within this time - great, return the result.
// If not - return an error. The result of the execution in this case is not important.
//
// Additionally, you need to measure how long this function took to execute (just log it).
// The signature of the wrapper function can be changed.
func predictableFunc() (int64, error) {
start := time.Now()
ch := make(chan int64, 1)
errCh := make(chan error, 1)
go func() {
result := unpredictableFunc()
ch <- result
}()
select {
case res := <-ch:
duration := time.Since(start)
log.Printf("Function executed in %s", duration)
return res, nil
case <-time.After(1 * time.Second):
duration := time.Since(start)
log.Printf("Function timed out after %s", duration)
return 0, errors.New("timeout")
}
}