改进空闲时间算法

This commit is contained in:
GoEdgeLab
2024-04-18 10:02:09 +08:00
parent 64dd4feb44
commit 8075e19d5b
2 changed files with 69 additions and 28 deletions

View File

@@ -9,6 +9,7 @@ import (
fsutils "github.com/TeaOSLab/EdgeNode/internal/utils/fs"
"github.com/iwind/TeaGo/Tea"
"github.com/shirou/gopsutil/v3/load"
"math"
"os"
"sort"
"time"
@@ -18,7 +19,7 @@ const maxSamples = 7
const cacheFile = "idles.cache"
var hourlyLoadMap = map[int]*HourlyLoad{}
var minLoadHour = -1
var sharedMinLoadHours []int
type HourlyLoad struct {
Hour int `json:"hour"`
@@ -35,7 +36,10 @@ func init() {
{
data, err := os.ReadFile(Tea.Root + "/data/" + cacheFile)
if err == nil {
_ = json.Unmarshal(data, &hourlyLoadMap)
err = json.Unmarshal(data, &hourlyLoadMap)
if err == nil {
calculateMinLoadHours()
}
}
}
@@ -70,36 +74,37 @@ func CheckHourlyLoad(hour int) {
for _, v := range hourlyLoad.Values {
sum += v
}
hourlyLoad.Avg = sum / float64(len(hourlyLoad.Values))
hourlyLoad.Avg = math.Ceil(sum/float64(len(hourlyLoad.Values))*10) / 10 // fix precision
// calculate min load hour
var allLoads = []*HourlyLoad{}
for _, v := range hourlyLoadMap {
allLoads = append(allLoads, v)
}
sort.Slice(allLoads, func(i, j int) bool {
return allLoads[i].Avg < allLoads[j].Avg
})
minLoadHour = allLoads[0].Hour
// write to cache
hourlyLoadMapJSON, err := json.Marshal(hourlyLoadMap)
if err == nil {
_ = os.WriteFile(Tea.Root+"/data/"+cacheFile, hourlyLoadMapJSON, 0666)
}
calculateMinLoadHours()
}
func Run(f func()) {
defer f()
if minLoadHour < 0 {
var minLoadHours = sharedMinLoadHours // copy
if len(minLoadHours) == 0 {
fsutils.WaitLoad(15, 8, time.Hour)
return
}
var hour = time.Now().Hour()
var minLoadHour = -1
for _, v := range minLoadHours {
if v == hour {
minLoadHour = v
break
}
if v > hour {
minLoadHour = v
break
}
}
if minLoadHour < 0 {
minLoadHour = minLoadHours[0]
}
if minLoadHour == hour {
fsutils.WaitLoad(15, 10, time.Minute)
return
@@ -119,8 +124,39 @@ func RunTicker(ticker *time.Ticker, f func()) {
}
}
func TestMinLoadHour() int {
return minLoadHour
func calculateMinLoadHours() {
var allLoads = []*HourlyLoad{}
for _, v := range hourlyLoadMap {
allLoads = append(allLoads, v)
}
sort.Slice(allLoads, func(i, j int) bool {
return allLoads[i].Avg < allLoads[j].Avg
})
var minAvgLoad = allLoads[0].Avg
var newMinLoadHours []int
for _, v := range allLoads {
if v.Avg == minAvgLoad {
newMinLoadHours = append(newMinLoadHours, v.Hour)
}
}
sort.Ints(newMinLoadHours)
sharedMinLoadHours = newMinLoadHours
// write to cache
hourlyLoadMapJSON, err := json.Marshal(hourlyLoadMap)
if err == nil {
_ = os.WriteFile(Tea.Root+"/data/"+cacheFile, hourlyLoadMapJSON, 0666)
}
}
func TestMinLoadHours() []int {
return sharedMinLoadHours
}
func TestSetMinLoadHours(minLoadHours []int) {
sharedMinLoadHours = minLoadHours
}
func TestHourlyLoadMap() map[int]*HourlyLoad {

View File

@@ -5,7 +5,8 @@ package idles_test
import (
"github.com/TeaOSLab/EdgeNode/internal/utils/idles"
"github.com/TeaOSLab/EdgeNode/internal/utils/testutils"
"github.com/iwind/TeaGo/logs"
_ "github.com/iwind/TeaGo/bootstrap"
"github.com/iwind/TeaGo/types"
timeutil "github.com/iwind/TeaGo/utils/time"
"testing"
"time"
@@ -13,17 +14,21 @@ import (
func TestCheckHourlyLoad(t *testing.T) {
for i := 0; i < 10; i++ {
idles.CheckHourlyLoad(5)
idles.CheckHourlyLoad(1)
idles.CheckHourlyLoad(2)
idles.CheckHourlyLoad(3)
idles.CheckHourlyLoad(2)
idles.CheckHourlyLoad(4)
}
t.Log(idles.TestMinLoadHour())
logs.PrintAsJSON(idles.TestHourlyLoadMap(), t)
t.Log(idles.TestMinLoadHours())
for h, v := range idles.TestHourlyLoadMap() {
t.Log(types.String(h)+":", v.Avg)
}
}
func TestRun(t *testing.T) {
//idles.CheckHourlyLoad(time.Now().Hour())
idles.TestSetMinLoadHours([]int{0, time.Now().Hour()})
idles.Run(func() {
t.Log("run once")
})