feat: add diagnostics and safe reset maintenance

This commit is contained in:
proxyctl coordinator
2026-07-17 03:28:29 +08:00
parent 3003450dce
commit d4c76e4b3c
13 changed files with 1041 additions and 23 deletions
+38 -5
View File
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"time"
"proxyctl/internal/profile"
"proxyctl/internal/target"
@@ -55,10 +56,12 @@ type Module interface {
}
type Application struct {
store profile.Store
state profile.State
targets []target.Target
inspections map[string]target.Inspection
store profile.Store
state profile.State
targets []target.Target
inspections map[string]target.Inspection
mutationLock MutationLock
logger OperationLogger
}
func New(store profile.Store) (*Application, error) {
@@ -66,11 +69,23 @@ func New(store profile.Store) (*Application, error) {
}
func NewWithTargets(store profile.Store, targets []target.Target) (*Application, error) {
return NewWithTargetsAndLock(store, targets, nil)
}
// NewWithTargetsAndLock configures the cross-process lock used by every
// Profile or Target mutation. A nil lock is intended only for isolated tests.
func NewWithTargetsAndLock(store profile.Store, targets []target.Target, mutationLock MutationLock) (*Application, error) {
return NewWithTargetsAndRuntime(store, targets, mutationLock, nil)
}
// NewWithTargetsAndRuntime configures shared mutation serialization and local
// operation diagnostics for production callers.
func NewWithTargetsAndRuntime(store profile.Store, targets []target.Target, mutationLock MutationLock, logger OperationLogger) (*Application, error) {
state, err := store.Load()
if err != nil {
return nil, err
}
a := &Application{store: store, state: state, targets: append([]target.Target(nil), targets...), inspections: make(map[string]target.Inspection)}
a := &Application{store: store, state: state, targets: append([]target.Target(nil), targets...), inspections: make(map[string]target.Inspection), mutationLock: mutationLock, logger: logger}
a.refreshTargets()
return a, nil
}
@@ -87,6 +102,13 @@ func (a *Application) Snapshot() Snapshot {
}
func (a *Application) Dispatch(intent Intent) Result {
if a.mutationLock != nil {
unlock, err := a.mutationLock.Lock(context.Background())
if err != nil {
return Result{Snapshot: a.Snapshot(), Err: fmt.Errorf("lock proxyctl mutation: %w", err)}
}
defer unlock()
}
if intent.Kind == SetTargetDesired {
return a.setTargetDesired(intent)
}
@@ -161,6 +183,17 @@ func (a *Application) setTargetDesired(intent Intent) Result {
}
result := selected.SetDesired(context.Background(), intent.Enabled, active)
a.inspections[selected.ID()] = result.Inspection
outcome, detail := "success", result.Inspection.Evidence
if result.Err != nil {
outcome, detail = "failure", result.Err.Error()
}
if a.logger != nil {
operation := "disable"
if intent.Enabled {
operation = "enable"
}
_ = a.logger.Write(LogEntry{Time: time.Now(), Operation: operation, Target: selected.ID(), Result: outcome, Detail: RedactLogDetail(detail)})
}
notice := ""
if result.Err == nil {
notice = fmt.Sprintf("%s Target is now %s", selected.Description().Name, result.Inspection.State)