athunderx / pkg /tache /utils.go
Mr.L
feat: add full alist source code for Docker build
7107f0b
package tache
import (
"runtime"
"sync"
"time"
)
// sliceContains checks if a slice contains a value
func sliceContains[T comparable](slice []T, v T) bool {
for _, vv := range slice {
if vv == v {
return true
}
}
return false
}
// getCurrentGoroutineStack get current goroutine stack
func getCurrentGoroutineStack() string {
buf := make([]byte, 1<<16)
n := runtime.Stack(buf, false)
return string(buf[:n])
}
// newDebounce returns a debounced function
func newDebounce(f func(), interval time.Duration) func() {
var timer *time.Timer
var lock sync.Mutex
return func() {
lock.Lock()
defer lock.Unlock()
if timer == nil {
timer = time.AfterFunc(interval, f)
} else {
timer.Reset(interval)
}
}
}
// isRetry checks if a task is retry executed
func isRetry[T Task](task T) bool {
return task.GetState() == StateWaitingRetry
}
// isLastRetry checks if a task is last retry
func isLastRetry[T Task](task T) bool {
retry, maxRetry := task.GetRetry()
return retry >= maxRetry
}
// needRetry judge whether the task need retry
func needRetry[T Task](task T) bool {
// if task is not recoverable, return false
if !IsRecoverable(task.GetErr()) {
return false
}
// if task is not retryable, return false
if r, ok := Task(task).(Retryable); ok && !r.Retryable() {
return false
}
// only retry when task is errored or failed
if sliceContains([]State{StateErrored, StateFailed}, task.GetState()) {
retry, maxRetry := task.GetRetry()
if retry < maxRetry {
task.SetRetry(retry+1, maxRetry)
task.SetState(StateWaitingRetry)
return true
}
}
return false
}