You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
1.1 KiB
62 lines
1.1 KiB
package lib
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"runtime"
|
|
"runtime/debug"
|
|
"time"
|
|
)
|
|
|
|
func RunAsync(ctx context.Context, fn func()) {
|
|
go func() {
|
|
defer Recover(ctx)
|
|
fn()
|
|
}()
|
|
}
|
|
|
|
func Recover(ctx context.Context) (flag bool, msg string) {
|
|
recoverErr := recover()
|
|
if recoverErr == nil {
|
|
return false, ""
|
|
}
|
|
|
|
stack := debug.Stack()
|
|
pc, file, line, _ := runtime.Caller(2)
|
|
msg = fmt.Sprintf("Recovered panic. file: %s, line: %d, function: %s, error: %s, stack: %s", file, line, runtime.FuncForPC(pc).Name(), recoverErr, stack)
|
|
|
|
return true, msg
|
|
}
|
|
|
|
func Retrier[T any](
|
|
maxCountRetries int,
|
|
timeRetries time.Duration,
|
|
disableProgressCalc bool,
|
|
f func() (T, error),
|
|
) (res T, err error) {
|
|
for i := 0; i < maxCountRetries; i++ {
|
|
if i > 0 {
|
|
if disableProgressCalc {
|
|
time.Sleep(timeRetries)
|
|
} else {
|
|
time.Sleep(sleepCalc(i, timeRetries))
|
|
}
|
|
}
|
|
|
|
res, err = f()
|
|
if err == nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func sleepCalc(ind int, requestRetryMinInterval time.Duration) time.Duration {
|
|
sleep := ind ^ 2
|
|
if sleep > 60 {
|
|
sleep = 60
|
|
}
|
|
|
|
return time.Duration(sleep) * requestRetryMinInterval
|
|
}
|
|
|