package utils import ( "fmt" "mongo.games.com/goserver/core/logger" "runtime" "time" ) func Avg(items []time.Duration) time.Duration { var sum time.Duration for _, item := range items { sum += item } return time.Duration(int64(sum) / int64(len(items))) } // human readable format func ToH(bytes uint64) string { switch { case bytes < 1024: return fmt.Sprintf("%dB", bytes) case bytes < 1024*1024: return fmt.Sprintf("%.2fK", float64(bytes)/1024) case bytes < 1024*1024*1024: return fmt.Sprintf("%.2fM", float64(bytes)/1024/1024) default: return fmt.Sprintf("%.2fG", float64(bytes)/1024/1024/1024) } } // short string format func ToS(d time.Duration) string { u := uint64(d) if u < uint64(time.Second) { switch { case u == 0: return "0" case u < uint64(time.Microsecond): return fmt.Sprintf("%.2fns", float64(u)) case u < uint64(time.Millisecond): return fmt.Sprintf("%.2fus", float64(u)/1000) default: return fmt.Sprintf("%.2fms", float64(u)/1000/1000) } } else { switch { case u < uint64(time.Minute): return fmt.Sprintf("%.2fs", float64(u)/1000/1000/1000) case u < uint64(time.Hour): return fmt.Sprintf("%.2fm", float64(u)/1000/1000/1000/60) default: return fmt.Sprintf("%.2fh", float64(u)/1000/1000/1000/60/60) } } } func CatchPanic(f func()) (err interface{}) { defer func() { err = recover() if err != nil { logger.Logger.Warnf("%s panic: %s", f, err) var buf [4096]byte n := runtime.Stack(buf[:], false) logger.Logger.Error("stack--->", string(buf[:n])) } }() f() return } func RunPanicless(f func()) (panicless bool) { defer func() { err := recover() panicless = err == nil if err != nil { logger.Logger.Warnf("%s panic: %s", f, err) var buf [4096]byte n := runtime.Stack(buf[:], false) logger.Logger.Error("stack--->", string(buf[:n])) } }() f() return } func RepeatUntilPanicless(f func()) { for !RunPanicless(f) { } }