generated from atomicgo/template
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
timeout.go
43 lines (36 loc) · 1006 Bytes
/
timeout.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package timeout
import (
"errors"
"time"
)
// Function is a function that returns a generic value and an error.
type Function[T any] func() (T, error)
// ErrTimeoutReached is returned when the timeout is reached.
var ErrTimeoutReached = errors.New("timeout reached")
// Execute executes a function and returns the result or an error if the timeout is reached.
// If the timeout is reached, the Function will be interrupted.
// If the Function returns an error, the error will be returned.
func Execute[T any](duration time.Duration, fn Function[T]) (T, error) {
resultChannel := make(chan T, 1)
errorChannel := make(chan error, 1)
go func() {
result, err := fn()
if err != nil {
errorChannel <- err
return
}
resultChannel <- result
}()
select {
case res := <-resultChannel:
return res, nil
case err := <-errorChannel:
return zeroValue[T](), err
case <-time.After(duration):
return zeroValue[T](), ErrTimeoutReached
}
}
func zeroValue[T any]() T {
var v T
return v
}