38 lines
649 B
Go
38 lines
649 B
Go
package timer
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
)
|
|
|
|
var ErrTimeout = errors.New("execution timed out")
|
|
|
|
// RunTimeout 执行带超时控制的任务,并支持打点追踪
|
|
func RunTimeout[T any](timeout time.Duration, fn func(tk *Tracker) (T, error)) (T, error) {
|
|
tk := Start()
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
done := make(chan struct {
|
|
res T
|
|
err error
|
|
}, 1)
|
|
|
|
go func() {
|
|
res, err := fn(tk)
|
|
done <- struct {
|
|
res T
|
|
err error
|
|
}{res, err}
|
|
}()
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
var zero T
|
|
return zero, ErrTimeout
|
|
case result := <-done:
|
|
return result.res, result.err
|
|
}
|
|
}
|