Add comprehensive process cleanup on TUI exit
- Created internal/cleanup package for orphaned process management - KillOrphanedProcesses(): Finds and kills pg_dump, pg_restore, gzip, pigz - killProcessGroup(): Kills entire process groups (handles pipelines) - Pass parent context through all TUI operations (backup/restore inherit cancellation) - Menu cancel now kills all child processes before exit - Fixed context chain: menu.ctx → backup/restore operations - No more zombie processes when user quits TUI mid-operation Context chain: - signal.NotifyContext in main.go → menu.ctx - menu.ctx → backup_exec.ctx, restore_exec.ctx - Child contexts inherit cancellation via context.WithTimeout(parentCtx) - All exec.CommandContext use proper parent context Prevents: Orphaned pg_dump/pg_restore eating CPU/disk after TUI quit
This commit is contained in:
@@ -19,6 +19,7 @@ type BackupExecutionModel struct {
|
||||
config *config.Config
|
||||
logger logger.Logger
|
||||
parent tea.Model
|
||||
ctx context.Context
|
||||
backupType string
|
||||
databaseName string
|
||||
ratio int
|
||||
@@ -32,11 +33,12 @@ type BackupExecutionModel struct {
|
||||
spinnerFrame int
|
||||
}
|
||||
|
||||
func NewBackupExecution(cfg *config.Config, log logger.Logger, parent tea.Model, backupType, dbName string, ratio int) BackupExecutionModel {
|
||||
func NewBackupExecution(cfg *config.Config, log logger.Logger, parent tea.Model, ctx context.Context, backupType, dbName string, ratio int) BackupExecutionModel {
|
||||
return BackupExecutionModel{
|
||||
config: cfg,
|
||||
logger: log,
|
||||
parent: parent,
|
||||
ctx: ctx,
|
||||
backupType: backupType,
|
||||
databaseName: dbName,
|
||||
ratio: ratio,
|
||||
@@ -50,7 +52,7 @@ func NewBackupExecution(cfg *config.Config, log logger.Logger, parent tea.Model,
|
||||
func (m BackupExecutionModel) Init() tea.Cmd {
|
||||
// TUI handles all display through View() - no progress callbacks needed
|
||||
return tea.Batch(
|
||||
executeBackupWithTUIProgress(m.config, m.logger, m.backupType, m.databaseName, m.ratio),
|
||||
executeBackupWithTUIProgress(m.ctx, m.config, m.logger, m.backupType, m.databaseName, m.ratio),
|
||||
backupTickCmd(),
|
||||
)
|
||||
}
|
||||
@@ -74,11 +76,12 @@ type backupCompleteMsg struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func executeBackupWithTUIProgress(cfg *config.Config, log logger.Logger, backupType, dbName string, ratio int) tea.Cmd {
|
||||
func executeBackupWithTUIProgress(parentCtx context.Context, cfg *config.Config, log logger.Logger, backupType, dbName string, ratio int) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
// Use configurable cluster timeout (minutes) from config; default set in config.New()
|
||||
// Use parent context to inherit cancellation from TUI
|
||||
clusterTimeout := time.Duration(cfg.ClusterTimeoutMinutes) * time.Minute
|
||||
ctx, cancel := context.WithTimeout(context.Background(), clusterTimeout)
|
||||
ctx, cancel := context.WithTimeout(parentCtx, clusterTimeout)
|
||||
defer cancel()
|
||||
|
||||
start := time.Now()
|
||||
|
||||
Reference in New Issue
Block a user