Files
AetherForge/agent/miner/schedule.go
AetherForge ea6f54ad03 Expand test coverage across server, agent, and web; fix bugs found during audit.
Adds hundreds of unit/integration/e2e tests, fixes WS bcrypt auth, config merge, fleet analytics, agent schedule/log tail, and documents stale PROBLEMS items. Updates PROBLEMS.md, README, and test scripts; ignores local spread-kits and coverage dirs.
2026-05-31 01:13:58 -07:00

76 lines
1.4 KiB
Go

package miner
import (
"sync"
"time"
"crypto-miner-agent/config"
"crypto-miner-agent/stats"
)
type ScheduleGuard struct {
cfg config.RuntimeConfig
reporter *stats.Reporter
mu sync.Mutex
idleSince time.Time
idleReady bool
}
func NewScheduleGuard(cfg config.RuntimeConfig, reporter *stats.Reporter) *ScheduleGuard {
return &ScheduleGuard{
cfg: cfg,
reporter: reporter,
}
}
func (g *ScheduleGuard) Allowed() bool {
return g.allowedAt(time.Now())
}
func (g *ScheduleGuard) allowedAt(now time.Time) bool {
switch g.cfg.MiningModeNormalized() {
case "idle":
return g.idleAllowed()
case "scheduled", "schedule":
return g.cfg.InScheduleWindow(now)
default:
return true
}
}
func (g *ScheduleGuard) idleAllowed() bool {
cpu := g.reporter.SystemCPUPercent()
threshold := float64(g.cfg.IdleThresholdPct)
if threshold <= 0 {
threshold = 20
}
duration := time.Duration(g.cfg.IdleDurationMinutes) * time.Minute
if duration <= 0 {
duration = 5 * time.Minute
}
g.mu.Lock()
defer g.mu.Unlock()
if cpu == 0 {
// First sample has no delta yet; treat as not idle.
g.idleSince = time.Time{}
g.idleReady = false
return false
}
if cpu <= threshold {
if g.idleSince.IsZero() {
g.idleSince = time.Now()
}
if time.Since(g.idleSince) >= duration {
g.idleReady = true
}
} else {
g.idleSince = time.Time{}
g.idleReady = false
}
return g.idleReady
}