fix:goroutines
This commit is contained in:
@@ -87,9 +87,23 @@ func (m BackupManagerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
// Delete archive (with confirmation)
|
||||
if len(m.archives) > 0 && m.cursor < len(m.archives) {
|
||||
selected := m.archives[m.cursor]
|
||||
confirm := NewConfirmationModel(m.config, m.logger, m,
|
||||
archivePath := selected.Path
|
||||
confirm := NewConfirmationModelWithAction(m.config, m.logger, m,
|
||||
"🗑️ Delete Archive",
|
||||
fmt.Sprintf("Delete archive '%s'? This cannot be undone.", selected.Name))
|
||||
fmt.Sprintf("Delete archive '%s'? This cannot be undone.", selected.Name),
|
||||
func() (tea.Model, tea.Cmd) {
|
||||
// Delete the archive
|
||||
err := deleteArchive(archivePath)
|
||||
if err != nil {
|
||||
m.err = fmt.Errorf("failed to delete archive: %v", err)
|
||||
m.message = fmt.Sprintf("❌ Failed to delete: %v", err)
|
||||
} else {
|
||||
m.message = fmt.Sprintf("✅ Deleted: %s", selected.Name)
|
||||
}
|
||||
// Refresh the archive list
|
||||
m.loading = true
|
||||
return m, loadArchives(m.config, m.logger)
|
||||
})
|
||||
return confirm, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ type ConfirmationModel struct {
|
||||
cursor int
|
||||
choices []string
|
||||
confirmed bool
|
||||
onConfirm func() (tea.Model, tea.Cmd) // Callback when confirmed
|
||||
}
|
||||
|
||||
func NewConfirmationModel(cfg *config.Config, log logger.Logger, parent tea.Model, title, message string) ConfirmationModel {
|
||||
@@ -33,6 +34,18 @@ func NewConfirmationModel(cfg *config.Config, log logger.Logger, parent tea.Mode
|
||||
}
|
||||
}
|
||||
|
||||
func NewConfirmationModelWithAction(cfg *config.Config, log logger.Logger, parent tea.Model, title, message string, onConfirm func() (tea.Model, tea.Cmd)) ConfirmationModel {
|
||||
return ConfirmationModel{
|
||||
config: cfg,
|
||||
logger: log,
|
||||
parent: parent,
|
||||
title: title,
|
||||
message: message,
|
||||
choices: []string{"Yes", "No"},
|
||||
onConfirm: onConfirm,
|
||||
}
|
||||
}
|
||||
|
||||
func (m ConfirmationModel) Init() tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
@@ -57,7 +70,11 @@ func (m ConfirmationModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
case "enter", "y":
|
||||
if msg.String() == "y" || m.cursor == 0 {
|
||||
m.confirmed = true
|
||||
// Execute cluster backup
|
||||
// Execute the onConfirm callback if provided
|
||||
if m.onConfirm != nil {
|
||||
return m.onConfirm()
|
||||
}
|
||||
// Default: execute cluster backup for backward compatibility
|
||||
executor := NewBackupExecution(m.config, m.logger, m.parent, "cluster", "", 0)
|
||||
return executor, executor.Init()
|
||||
}
|
||||
|
||||
@@ -324,9 +324,13 @@ func (m MenuModel) handleClusterBackup() (tea.Model, tea.Cmd) {
|
||||
m.message = errorStyle.Render("❌ Cluster backup is available only for PostgreSQL targets")
|
||||
return m, nil
|
||||
}
|
||||
confirm := NewConfirmationModel(m.config, m.logger, m,
|
||||
confirm := NewConfirmationModelWithAction(m.config, m.logger, m,
|
||||
"🗄️ Cluster Backup",
|
||||
"This will backup ALL databases in the cluster. Continue?")
|
||||
"This will backup ALL databases in the cluster. Continue?",
|
||||
func() (tea.Model, tea.Cmd) {
|
||||
executor := NewBackupExecution(m.config, m.logger, m, "cluster", "", 0)
|
||||
return executor, executor.Init()
|
||||
})
|
||||
return confirm, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,47 @@ func NewSettingsModel(cfg *config.Config, log logger.Logger, parent tea.Model) S
|
||||
Type: "selector",
|
||||
Description: "Target database engine (press Enter to cycle: PostgreSQL → MySQL → MariaDB)",
|
||||
},
|
||||
{
|
||||
Key: "cpu_workload",
|
||||
DisplayName: "CPU Workload Type",
|
||||
Value: func(c *config.Config) string { return c.CPUWorkloadType },
|
||||
Update: func(c *config.Config, v string) error {
|
||||
workloads := []string{"balanced", "cpu-intensive", "io-intensive"}
|
||||
currentIdx := 0
|
||||
for i, w := range workloads {
|
||||
if c.CPUWorkloadType == w {
|
||||
currentIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
nextIdx := (currentIdx + 1) % len(workloads)
|
||||
c.CPUWorkloadType = workloads[nextIdx]
|
||||
|
||||
// Recalculate Jobs and DumpJobs based on workload type
|
||||
if c.CPUInfo != nil && c.AutoDetectCores {
|
||||
switch c.CPUWorkloadType {
|
||||
case "cpu-intensive":
|
||||
c.Jobs = c.CPUInfo.PhysicalCores * 2
|
||||
c.DumpJobs = c.CPUInfo.PhysicalCores
|
||||
case "io-intensive":
|
||||
c.Jobs = c.CPUInfo.PhysicalCores / 2
|
||||
if c.Jobs < 1 {
|
||||
c.Jobs = 1
|
||||
}
|
||||
c.DumpJobs = 2
|
||||
default: // balanced
|
||||
c.Jobs = c.CPUInfo.PhysicalCores
|
||||
c.DumpJobs = c.CPUInfo.PhysicalCores / 2
|
||||
if c.DumpJobs < 2 {
|
||||
c.DumpJobs = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Type: "selector",
|
||||
Description: "CPU workload profile (press Enter to cycle: Balanced → CPU-Intensive → I/O-Intensive)",
|
||||
},
|
||||
{
|
||||
Key: "backup_dir",
|
||||
DisplayName: "Backup Directory",
|
||||
|
||||
Reference in New Issue
Block a user