support docker daemon going down randomly

This commit is contained in:
Jesse Duffield 2019-06-16 12:37:47 +10:00
parent 4c916477ba
commit 5ab4ef6f8c
8 changed files with 46 additions and 16 deletions

View file

@ -7,6 +7,7 @@ import (
"os" "os"
"runtime" "runtime"
"github.com/docker/docker/client"
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/jesseduffield/lazydocker/pkg/app" "github.com/jesseduffield/lazydocker/pkg/app"
"github.com/jesseduffield/lazydocker/pkg/config" "github.com/jesseduffield/lazydocker/pkg/config"
@ -50,6 +51,11 @@ func main() {
} }
if err != nil { if err != nil {
if client.IsErrConnectionFailed(err) {
log.Println(app.Tr.ConnectionFailed)
os.Exit(0)
}
newErr := errors.Wrap(err, 0) newErr := errors.Wrap(err, 0)
stackTrace := newErr.ErrorStack() stackTrace := newErr.ErrorStack()
app.Log.Error(stackTrace) app.Log.Error(stackTrace)

View file

@ -283,7 +283,7 @@ func (c *Container) GetDisplayCPUPerc() string {
percentage, err := strconv.ParseFloat(strings.TrimSuffix(stats.CPUPerc, "%"), 32) percentage, err := strconv.ParseFloat(strings.TrimSuffix(stats.CPUPerc, "%"), 32)
if err != nil { if err != nil {
c.Log.Error(err) // probably complaining about not being able to convert '--'
return "" return ""
} }

View file

@ -182,7 +182,7 @@ func GetDefaultConfig() UserConfig {
StopService: "{{ .DockerCompose }} stop {{ .Service.Name }}", StopService: "{{ .DockerCompose }} stop {{ .Service.Name }}",
ServiceLogs: "{{ .DockerCompose }} logs --since=60m --follow {{ .Service.Name }}", ServiceLogs: "{{ .DockerCompose }} logs --since=60m --follow {{ .Service.Name }}",
ViewServiceLogs: "{{ .DockerCompose }} logs --follow {{ .Service.Name }}", ViewServiceLogs: "{{ .DockerCompose }} logs --follow {{ .Service.Name }}",
AllLogs: "{{ .DockerCompose }} logs --since=60m --follow", AllLogs: "{{ .DockerCompose }} logs --tail=300 --follow",
ViewAllLogs: "{{ .DockerCompose }} logs", ViewAllLogs: "{{ .DockerCompose }} logs",
DockerComposeConfig: "{{ .DockerCompose }} config", DockerComposeConfig: "{{ .DockerCompose }} config",
CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet", CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet",

View file

@ -202,7 +202,11 @@ func (gui *Gui) renderLogs(container *commands.Container, template string, setup
return gui.T.NewTickerTask(time.Millisecond*200, nil, func(stop, notifyStopped chan struct{}) { return gui.T.NewTickerTask(time.Millisecond*200, nil, func(stop, notifyStopped chan struct{}) {
gui.clearMainView() gui.clearMainView()
cmd := container.TTYLogsCommand() command := utils.ApplyTemplate(
template,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Container: container}),
)
cmd := gui.OSCommand.RunCustomCommand(command)
setup(cmd) setup(cmd)
@ -211,6 +215,7 @@ func (gui *Gui) renderLogs(container *commands.Container, template string, setup
go func() { go func() {
<-stop <-stop
cmd.Process.Kill() cmd.Process.Kill()
gui.Log.Info("killed container logs process")
return return
}() }()

View file

@ -137,15 +137,11 @@ func (gui *Gui) renderServiceLogs(service *commands.Service) error {
} }
if service.Container == nil { if service.Container == nil {
gui.Log.Warn("container is nil")
return gui.T.NewTask(func(stop chan struct{}) { return gui.T.NewTask(func(stop chan struct{}) {
gui.Log.Warn("about to clear main view")
gui.clearMainView() gui.clearMainView()
gui.Log.Warn("cleared main view")
}) })
} }
gui.Log.Warn("about to render container logs for service ", service.Name)
return gui.renderContainerLogs(service.Container) return gui.renderContainerLogs(service.Container)
} }

View file

@ -20,6 +20,7 @@ type TranslationSet struct {
AnonymousReportingPrompt string AnonymousReportingPrompt string
ConfirmQuit string ConfirmQuit string
ErrorOccurred string ErrorOccurred string
ConnectionFailed string
Donate string Donate string
Cancel string Cancel string
CustomCommandTitle string CustomCommandTitle string
@ -84,9 +85,10 @@ func englishSet() TranslationSet {
RunningSubprocess: "running subprocess", RunningSubprocess: "running subprocess",
NoViewMachingNewLineFocusedSwitchStatement: "No view matching newLineFocused switch statement", NoViewMachingNewLineFocusedSwitchStatement: "No view matching newLineFocused switch statement",
ErrorOccurred: "An error occurred! Please create an issue at https://github.com/jesseduffield/lazydocker/issues", ErrorOccurred: "An error occurred! Please create an issue at https://github.com/jesseduffield/lazydocker/issues",
Donate: "Donate", ConnectionFailed: "connection to docker client failed. You may need to restart the docker client",
Confirm: "Confirm", Donate: "Donate",
Confirm: "Confirm",
Navigate: "navigate", Navigate: "navigate",
Execute: "execute", Execute: "execute",

View file

@ -45,7 +45,9 @@ func (t *TaskManager) NewTask(f func(stop chan struct{})) error {
notifyStopped := make(chan struct{}) notifyStopped := make(chan struct{})
if t.currentTask != nil { if t.currentTask != nil {
t.Log.Info("asking task to stop")
t.currentTask.Stop() t.currentTask.Stop()
t.Log.Info("task stopped")
} }
t.currentTask = &Task{ t.currentTask = &Task{
@ -57,6 +59,7 @@ func (t *TaskManager) NewTask(f func(stop chan struct{})) error {
go func() { go func() {
f(stop) f(stop)
t.Log.Info("returned from function, closing notifyStopped")
close(notifyStopped) close(notifyStopped)
}() }()
}() }()
@ -66,14 +69,17 @@ func (t *TaskManager) NewTask(f func(stop chan struct{})) error {
func (t *Task) Stop() { func (t *Task) Stop() {
close(t.stop) close(t.stop)
t.Log.Info("closed stop channel, waiting for notifyStopped message")
<-t.notifyStopped <-t.notifyStopped
t.Log.Info("received notifystopped message")
return return
} }
// NewTickerTask is a convenience function for making a new task that repeats some action once per e.g. second // NewTickerTask is a convenience function for making a new task that repeats some action once per e.g. second
// the before function gets called after the lock is obtained, but before the ticker starts. // the before function gets called after the lock is obtained, but before the ticker starts.
// if you handle a message on the stop channel in f() you need to send a message on the notifyStopped channel because returning is not sufficient. Here, unlike in a regular task, simply returning means we're now going to wait till the next tick to run again.
func (t *TaskManager) NewTickerTask(duration time.Duration, before func(stop chan struct{}), f func(stop, notifyStopped chan struct{})) error { func (t *TaskManager) NewTickerTask(duration time.Duration, before func(stop chan struct{}), f func(stop, notifyStopped chan struct{})) error {
notifyStopped := make(chan struct{}) notifyStopped := make(chan struct{}, 10)
return t.NewTask(func(stop chan struct{}) { return t.NewTask(func(stop chan struct{}) {
if before != nil { if before != nil {
@ -81,14 +87,17 @@ func (t *TaskManager) NewTickerTask(duration time.Duration, before func(stop cha
} }
tickChan := time.NewTicker(duration) tickChan := time.NewTicker(duration)
// calling f first so that we're not waiting for the first tick // calling f first so that we're not waiting for the first tick
f(stop, notifyStopped) // f(stop, notifyStopped)
for { for {
select { select {
case <-notifyStopped: case <-notifyStopped:
t.Log.Info("exiting ticker task due to notifyStopped channel")
return return
case <-stop: case <-stop:
t.Log.Info("exiting ticker task due to stopped cahnnel")
return return
case <-tickChan.C: case <-tickChan.C:
t.Log.Info("running ticker task again")
f(stop, notifyStopped) f(stop, notifyStopped)
} }
} }

View file

@ -1,9 +1,21 @@
package main package main
import "fmt" import "log"
func main() { func main() {
var arr []string c := make(chan struct{})
arr = nil
fmt.Println(len(arr)) close(c)
close(c)
select {
case <-c:
log.Println("hmm")
}
select {
case <-c:
log.Println("okay")
}
} }