feat: bootstrap supply intelligence baseline

This commit is contained in:
Your Name
2026-05-07 10:16:46 +08:00
commit afdbea6fb5
62 changed files with 9170 additions and 0 deletions

150
internal/control/module.go Normal file
View File

@@ -0,0 +1,150 @@
package control
import (
"sync"
"time"
)
// ModuleState represents the lifecycle state of a module
type ModuleState string
const (
ModuleStateActive ModuleState = "active"
ModuleStateClosing ModuleState = "closing"
ModuleStateClosed ModuleState = "closed"
)
// ModuleGate controls the enable/disable/close lifecycle of a module
type ModuleGate struct {
mu sync.RWMutex
enabled bool
state ModuleState
closedAt *time.Time
}
func NewModuleGate(enabled bool) *ModuleGate {
return &ModuleGate{enabled: enabled, state: ModuleStateActive}
}
// IsEnabled returns whether the module is accepting new tasks
func (g *ModuleGate) IsEnabled() bool {
g.mu.RLock()
defer g.mu.RUnlock()
return g.enabled && g.state == ModuleStateActive
}
// Close signals the module to stop accepting new tasks
func (g *ModuleGate) Close() {
g.mu.Lock()
defer g.mu.Unlock()
if g.state == ModuleStateActive {
g.state = ModuleStateClosing
now := time.Now().UTC()
g.closedAt = &now
}
}
// MarkClosed marks the module as fully closed (no in-flight tasks)
func (g *ModuleGate) MarkClosed() {
g.mu.Lock()
defer g.mu.Unlock()
g.state = ModuleStateClosed
g.enabled = false
}
// State returns the current module state
func (g *ModuleGate) State() ModuleState {
g.mu.RLock()
defer g.mu.RUnlock()
return g.state
}
// ModuleController manages all module gates
type ModuleController struct {
probes *ModuleGate
discovery *ModuleGate
admission *ModuleGate
publish *ModuleGate
}
func NewModuleController(enabled bool) *ModuleController {
return &ModuleController{
probes: NewModuleGate(enabled),
discovery: NewModuleGate(enabled),
admission: NewModuleGate(enabled),
publish: NewModuleGate(enabled),
}
}
// ShutdownInitiate closes all modules (stop accepting new tasks)
func (c *ModuleController) ShutdownInitiate() {
c.probes.Close()
c.discovery.Close()
c.admission.Close()
c.publish.Close()
}
// ShutdownComplete marks all modules as fully closed
func (c *ModuleController) ShutdownComplete() {
c.probes.MarkClosed()
c.discovery.MarkClosed()
c.admission.MarkClosed()
c.publish.MarkClosed()
}
// IsInflight returns true if any module still has in-flight tasks
func (c *ModuleController) IsInflight() bool {
return c.probes.State() == ModuleStateClosing ||
c.discovery.State() == ModuleStateClosing ||
c.admission.State() == ModuleStateClosing ||
c.publish.State() == ModuleStateClosing
}
// GetModuleState returns the state of a specific module
func (c *ModuleController) GetModuleState(name string) ModuleState {
switch name {
case "probes":
return c.probes.State()
case "discovery":
return c.discovery.State()
case "admission":
return c.admission.State()
case "publish":
return c.publish.State()
default:
return ""
}
}
// Status returns a snapshot of all module states
type ModuleStatus struct {
Probes ModuleState `json:"probes"`
Discovery ModuleState `json:"discovery"`
Admission ModuleState `json:"admission"`
Publish ModuleState `json:"publish"`
}
func (c *ModuleController) Status() ModuleStatus {
return ModuleStatus{
Probes: c.probes.State(),
Discovery: c.discovery.State(),
Admission: c.admission.State(),
Publish: c.publish.State(),
}
}
// RejectIfNotEnabled returns an error if the module is not enabled
func (g *ModuleGate) RejectIfNotEnabled(moduleName string) error {
if !g.IsEnabled() {
return ErrModuleClosed
}
return nil
}
var ErrModuleClosed = &ModuleClosedError{}
type ModuleClosedError struct{}
func (e *ModuleClosedError) Error() string {
return "module is not accepting new tasks"
}

View File

@@ -0,0 +1,124 @@
package control
import (
"testing"
"time"
)
func TestModuleGate_IsEnabled(t *testing.T) {
g := NewModuleGate(true)
if !g.IsEnabled() {
t.Fatal("expected enabled")
}
}
func TestModuleGate_IsDisabled(t *testing.T) {
g := NewModuleGate(false)
if g.IsEnabled() {
t.Fatal("expected disabled")
}
}
func TestModuleGate_Close(t *testing.T) {
g := NewModuleGate(true)
g.Close()
if g.State() != ModuleStateClosing {
t.Fatalf("expected closing, got: %s", g.State())
}
}
func TestModuleGate_MarkClosed(t *testing.T) {
g := NewModuleGate(true)
g.Close()
g.MarkClosed()
if g.State() != ModuleStateClosed {
t.Fatalf("expected closed, got: %s", g.State())
}
if g.IsEnabled() {
t.Fatal("expected not enabled after closed")
}
}
func TestModuleGate_RejectIfNotEnabled(t *testing.T) {
g := NewModuleGate(true)
err := g.RejectIfNotEnabled("test")
if err != nil {
t.Fatal("expected no error when enabled")
}
g.Close()
err = g.RejectIfNotEnabled("test")
if err == nil {
t.Fatal("expected error when closing")
}
}
func TestModuleController_ShutdownInitiate(t *testing.T) {
c := NewModuleController(true)
c.ShutdownInitiate()
if c.probes.State() != ModuleStateClosing {
t.Fatalf("probes should be closing, got: %s", c.probes.State())
}
if c.discovery.State() != ModuleStateClosing {
t.Fatalf("discovery should be closing, got: %s", c.discovery.State())
}
}
func TestModuleController_ShutdownComplete(t *testing.T) {
c := NewModuleController(true)
c.ShutdownInitiate()
c.ShutdownComplete()
if c.probes.State() != ModuleStateClosed {
t.Fatalf("probes should be closed, got: %s", c.probes.State())
}
}
func TestModuleController_IsInflight(t *testing.T) {
c := NewModuleController(true)
c.ShutdownInitiate()
if !c.IsInflight() {
t.Fatal("expected in-flight during closing")
}
c.ShutdownComplete()
if c.IsInflight() {
t.Fatal("expected not in-flight after closed")
}
}
func TestModuleController_GetModuleState(t *testing.T) {
c := NewModuleController(true)
if c.GetModuleState("probes") != ModuleStateActive {
t.Fatalf("expected active, got: %s", c.GetModuleState("probes"))
}
if c.GetModuleState("unknown") != "" {
t.Fatalf("expected empty for unknown module")
}
}
func TestModuleController_Status(t *testing.T) {
c := NewModuleController(true)
status := c.Status()
if status.Probes != ModuleStateActive {
t.Fatalf("expected active, got: %s", status.Probes)
}
}
func TestModuleGate_ClosedAt(t *testing.T) {
g := NewModuleGate(true)
g.Close()
if g.State() != ModuleStateClosing {
t.Fatal("expected closing state")
}
// closedAt should be set when entering closing state
time.Sleep(10 * time.Millisecond)
_ = g.closedAt // not nil when closing
}