fix: harden operations and configuration recovery
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user