support docker daemon going down randomly

pull/1/head
Jesse Duffield 5 years ago
parent 4c916477ba
commit 5ab4ef6f8c

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

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

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

@ -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{}) {
gui.clearMainView()
cmd := container.TTYLogsCommand()
command := utils.ApplyTemplate(
template,
gui.DockerCommand.NewCommandObject(commands.CommandObject{Container: container}),
)
cmd := gui.OSCommand.RunCustomCommand(command)
setup(cmd)
@ -211,6 +215,7 @@ func (gui *Gui) renderLogs(container *commands.Container, template string, setup
go func() {
<-stop
cmd.Process.Kill()
gui.Log.Info("killed container logs process")
return
}()

@ -137,15 +137,11 @@ func (gui *Gui) renderServiceLogs(service *commands.Service) error {
}
if service.Container == nil {
gui.Log.Warn("container is nil")
return gui.T.NewTask(func(stop chan struct{}) {
gui.Log.Warn("about to clear main view")
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)
}

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

@ -45,7 +45,9 @@ func (t *TaskManager) NewTask(f func(stop chan struct{})) error {
notifyStopped := make(chan struct{})
if t.currentTask != nil {
t.Log.Info("asking task to stop")
t.currentTask.Stop()
t.Log.Info("task stopped")
}
t.currentTask = &Task{
@ -57,6 +59,7 @@ func (t *TaskManager) NewTask(f func(stop chan struct{})) error {
go func() {
f(stop)
t.Log.Info("returned from function, closing notifyStopped")
close(notifyStopped)
}()
}()
@ -66,14 +69,17 @@ func (t *TaskManager) NewTask(f func(stop chan struct{})) error {
func (t *Task) Stop() {
close(t.stop)
t.Log.Info("closed stop channel, waiting for notifyStopped message")
<-t.notifyStopped
t.Log.Info("received notifystopped message")
return
}
// 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.
// 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 {
notifyStopped := make(chan struct{})
notifyStopped := make(chan struct{}, 10)
return t.NewTask(func(stop chan struct{}) {
if before != nil {
@ -81,14 +87,17 @@ func (t *TaskManager) NewTickerTask(duration time.Duration, before func(stop cha
}
tickChan := time.NewTicker(duration)
// calling f first so that we're not waiting for the first tick
f(stop, notifyStopped)
// f(stop, notifyStopped)
for {
select {
case <-notifyStopped:
t.Log.Info("exiting ticker task due to notifyStopped channel")
return
case <-stop:
t.Log.Info("exiting ticker task due to stopped cahnnel")
return
case <-tickChan.C:
t.Log.Info("running ticker task again")
f(stop, notifyStopped)
}
}

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

Loading…
Cancel
Save