From 979204d454bd84cb12e63ad309ca5f33e6f3f65b Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 6 Aug 2019 21:28:22 +1000 Subject: [PATCH] ensure the current task is stopped before exit so we don't have any child orphan processes --- pkg/gui/gui.go | 5 ++++- pkg/i18n/english.go | 2 ++ pkg/tasks/tasks.go | 30 ++++++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 1655420ab..e44fbb6de 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -161,7 +161,7 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand Config: config, Tr: tr, statusManager: &statusManager{}, - T: tasks.NewTaskManager(log), + T: tasks.NewTaskManager(log, tr), ErrorChan: errorChan, CyclableViews: cyclableViews, } @@ -245,6 +245,9 @@ func (gui *Gui) goEvery(interval time.Duration, function func() error) { // Run setup the gui with keybindings and start the mainloop func (gui *Gui) Run() error { + // closing our task manager which in turn closes the current task if there is any, so we aren't leaving processes lying around after closing lazydocker + defer gui.T.Close() + g, err := gocui.NewGui(gocui.OutputNormal, OverlappingEdges) if err != nil { return err diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 87d863365..b5c479942 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -24,6 +24,7 @@ type TranslationSet struct { UnattachableContainerError string CannotAttachStoppedContainerError string CannotAccessDockerSocketError string + CannotKillChildError string Donate string Cancel string @@ -110,6 +111,7 @@ func englishSet() TranslationSet { UnattachableContainerError: "Container does not support attaching. You must either run the service with the '-it' flag or use `stdin_open: true, tty: true` in the docker-compose.yml file", CannotAttachStoppedContainerError: "You cannot attach to a stopped container, you need to start it first (which you can actually do with the 'r' key) (yes I'm too lazy to do this automatically for you) (pretty cool that I get to communicate one-on-one with you in the form of an error message though)", CannotAccessDockerSocketError: "Can't access docker socket at: unix:///var/run/docker.sock\nRun lazydocker as root or read https://docs.docker.com/install/linux/linux-postinstall/", + CannotKillChildError: "Waited three seconds for child process to stop. There may be an orphan process that continues to run on your system.", Donate: "Donate", Confirm: "Confirm", diff --git a/pkg/tasks/tasks.go b/pkg/tasks/tasks.go index 3de3e9ca5..371cc9b76 100644 --- a/pkg/tasks/tasks.go +++ b/pkg/tasks/tasks.go @@ -1,9 +1,11 @@ package tasks import ( + "fmt" "sync" "time" + "github.com/jesseduffield/lazydocker/pkg/i18n" "github.com/sirupsen/logrus" ) @@ -13,6 +15,7 @@ type TaskManager struct { waitingMutex sync.Mutex taskIDMutex sync.Mutex Log *logrus.Entry + Tr *i18n.TranslationSet waitingTaskAlerts chan struct{} newTaskId int } @@ -24,8 +27,31 @@ type Task struct { f func(chan struct{}) } -func NewTaskManager(log *logrus.Entry) *TaskManager { - return &TaskManager{Log: log} +func NewTaskManager(log *logrus.Entry, translationSet *i18n.TranslationSet) *TaskManager { + return &TaskManager{Log: log, Tr: translationSet} +} + +// Close closes the task manager, killing whatever task may currently be running +func (t *TaskManager) Close() { + return + + if t.currentTask == nil { + return + } + + c := make(chan struct{}, 1) + + go func() { + t.currentTask.Stop() + c <- struct{}{} + }() + + select { + case <-c: + return + case <-time.After(3 * time.Second): + fmt.Println(t.Tr.CannotKillChildError) + } } func (t *TaskManager) NewTask(f func(stop chan struct{})) error {