Files
3x-ui/internal/util/sys/cpu_times.go
T
PluS98 121123eaaa fix: keep panel restarts from hanging on the CPU job and Telegram (#7029)
Restarting the panel left it unreachable for up to a minute. CheckCpuJob sampled cpu.Percent over its whole one-minute period, so cron.Stop nearly always waited on it; it now diffs cpu.Times against its previous run (iowait counted as idle, as before). With Telegram unreachable, bus.Stop waited on an in-flight send and tgbot.Start ran getMe/setMyCommands inline; each bot call now returns once StopBot closes the bot's stop channel, the bot stops before the bus, and the artwork/commands warm-up runs in the background.
2026-11-02 15:34:22 +01:00

37 lines
1.1 KiB
Go

package sys
import "github.com/shirou/gopsutil/v4/cpu"
// CPUBusyPercent is the busy share of CPU time between two cumulative samples,
// counting iowait as busy; ok is false when no time elapsed or the counters reset.
func CPUBusyPercent(prev, cur cpu.TimesStat) (percent float64, ok bool) {
return cpuPercent(prev, cur, true)
}
// CPUWorkPercent is CPUBusyPercent with iowait counted as idle, as gopsutil's
// cpu.Percent does, so a host waiting on disk is not reported as CPU-bound.
func CPUWorkPercent(prev, cur cpu.TimesStat) (percent float64, ok bool) {
return cpuPercent(prev, cur, false)
}
func cpuPercent(prev, cur cpu.TimesStat, iowaitIsBusy bool) (float64, bool) {
// Guest and GuestNice are already counted inside User and Nice on Linux.
idle := cur.Idle - prev.Idle
busy := (cur.User - prev.User) +
(cur.System - prev.System) +
(cur.Nice - prev.Nice) +
(cur.Irq - prev.Irq) +
(cur.Softirq - prev.Softirq) +
(cur.Steal - prev.Steal)
if iowait := cur.Iowait - prev.Iowait; iowaitIsBusy {
busy += iowait
} else {
idle += iowait
}
total := busy + idle
if total <= 0 {
return 0, false
}
return min(max(100*busy/total, 0), 100), true
}