Optimize: Fix high/medium/low priority issues and apply optimizations
High Priority Fixes: - Use configurable ClusterTimeoutMinutes for restore (was hardcoded 2 hours) - Add comment explaining goroutine cleanup in stderr reader (cmd.Run waits) - Add defer cancel() in cluster backup loop to prevent context leak on panic Medium Priority Fixes: - Standardize tick rate to 100ms for both backup and restore (consistent UX) - Add spinnerFrame field to BackupExecutionModel for incremental updates - Define package-level spinnerFrames constant to avoid repeated allocation Low Priority Fixes: - Add 30-second timeout per database in cluster cleanup loop - Prevents indefinite hangs when dropping many databases Optimizations: - Pre-allocate 512 bytes in View() string builders (reduces allocations) - Use incremental spinner frame calculation (more efficient than time-based) - Share spinner frames array across all TUI operations All changes are backward compatible and maintain existing behavior.
This commit is contained in:
@@ -399,8 +399,9 @@ func (e *Engine) BackupCluster(ctx context.Context) error {
|
||||
// Use a context with timeout for each database to prevent hangs
|
||||
// Use longer timeout for huge databases (2 hours per database)
|
||||
dbCtx, cancel := context.WithTimeout(ctx, 2*time.Hour)
|
||||
defer cancel() // Ensure cancel is called even if executeCommand panics
|
||||
err := e.executeCommand(dbCtx, cmd, dumpFile)
|
||||
cancel()
|
||||
cancel() // Also call immediately for early cleanup
|
||||
|
||||
if err != nil {
|
||||
e.log.Warn("Failed to backup database", "database", dbName, "error", err)
|
||||
@@ -786,6 +787,7 @@ regularTar:
|
||||
cmd := exec.CommandContext(ctx, compressCmd, compressArgs...)
|
||||
|
||||
// Stream stderr to avoid memory issues
|
||||
// Use io.Copy to ensure goroutine completes when pipe closes
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err == nil {
|
||||
go func() {
|
||||
@@ -796,12 +798,14 @@ regularTar:
|
||||
e.log.Debug("Archive creation", "output", line)
|
||||
}
|
||||
}
|
||||
// Scanner will exit when stderr pipe closes after cmd.Wait()
|
||||
}()
|
||||
}
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("tar failed: %w", err)
|
||||
}
|
||||
// cmd.Run() calls Wait() which closes stderr pipe, terminating the goroutine
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user