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.
76 lines
1.4 KiB
Go
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
|
|
}
|