fix: harden operations and configuration recovery

This commit is contained in:
proxyctl coordinator
2026-08-30 11:13:45 +08:00
parent e34bf7d989
commit 8928986830
27 changed files with 542 additions and 125 deletions
+20
View File
@@ -22,6 +22,7 @@ type operationCoordinator struct {
active bool
intent app.Intent
updates <-chan app.OperationUpdate
cancel func()
progress map[string]app.TargetProgressPhase
status app.OperationStatus
currentError *operationError
@@ -85,6 +86,7 @@ func (o *operationCoordinator) start(application app.InteractiveModule, intent a
o.active = true
o.intent = intent
o.updates = stream.Updates
o.cancel = stream.Cancel
o.progress = make(map[string]app.TargetProgressPhase)
o.spinner = spinner.New(spinner.WithSpinner(applyingSpinner))
if intent.TargetID != "" {
@@ -100,6 +102,8 @@ func operationStartingSummary(kind app.IntentKind) string {
return "Checking Target availability and state…"
case app.ActivateProfile:
return "Changing Active Profile…"
case app.CreateProfile, app.UpdateProfile, app.DeleteProfile:
return "Saving Proxy Profile changes…"
default:
return "Starting Target mutation…"
}
@@ -171,6 +175,8 @@ func relatedResolution(failed, success app.Intent) bool {
return success.Kind == app.RefreshTargets
case failed.Kind == app.ActivateProfile:
return success.Kind == app.ActivateProfile && failed.Name == success.Name
case isProfileMutation(failed.Kind):
return isProfileMutation(success.Kind) && failed.Name == success.Name
case isTargetMutation(failed.Kind):
return isTargetMutation(success.Kind) && failed.TargetID != "" && failed.TargetID == success.TargetID
default:
@@ -188,9 +194,19 @@ func isTargetMutation(kind app.IntentKind) bool {
}
func (o *operationCoordinator) finish() {
// start seeds speculative Running progress before the stream publishes its
// first update. A terminal update may contain no replacement progress (most
// notably a confirmation request), so never let that transient phase outlive
// the operation that created it.
for targetID, phase := range o.progress {
if phase == app.TargetProgressRunning {
delete(o.progress, targetID)
}
}
o.active = false
o.intent = app.Intent{}
o.updates = nil
o.cancel = nil
}
func (o *operationCoordinator) unexpectedClose() {
@@ -225,6 +241,7 @@ func (o *operationCoordinator) confirmedIntent() (app.Intent, bool) {
}
intent := *o.confirmationIntent
intent.Confirm = true
intent.ConfirmationToken = o.confirmation.Token
o.confirmation = nil
o.confirmationDialog = confirmationDialog{}
o.confirmationIntent = nil
@@ -245,6 +262,9 @@ func (o operationCoordinator) deferredQuit() tea.Cmd {
func (o *operationCoordinator) requestQuit() tea.Cmd {
o.quitRequested = true
if o.active {
if o.cancel != nil {
o.cancel()
}
return nil
}
return tea.Quit