Wait for daemon to come up; exit daemon gracefully.

This commit is contained in:
Qi Xiao 2017-06-20 16:09:07 +02:00
parent d5038c2be5
commit 0ae4f434e2
4 changed files with 40 additions and 9 deletions

View File

@ -72,7 +72,7 @@ func (d *Daemon) Main(serve func(string, string)) int {
})
case 2:
serve(d.SockPath, d.DbPath)
panic("unreachable")
return 0
default:
return 2
}

View File

@ -39,13 +39,20 @@ func Serve(sockpath, dbpath string) {
signal.Notify(quitSignals, syscall.SIGTERM, syscall.SIGINT)
go func() {
sig := <-quitSignals
logger.Printf("received signal %s, shutting down", sig)
logger.Printf("received signal %s", sig)
err := os.Remove(sockpath)
if err != nil {
logger.Println("failed to remove socket %s: %v", sockpath, err)
logger.Printf("failed to remove socket %s: %v", sockpath, err)
}
logger.Println("exiting")
os.Exit(0)
err = st.Close()
if err != nil {
logger.Printf("failed to close storage: %v", err)
}
err = listener.Close()
if err != nil {
logger.Printf("failed to close listener: %v", err)
}
logger.Println("listener closed, waiting to exit")
}()
service := &Service{st}
@ -53,7 +60,8 @@ func Serve(sockpath, dbpath string) {
logger.Println("starting to serve RPC calls")
rpc.Accept(listener)
os.Exit(0)
logger.Println("exiting")
}
// Service provides the daemon RPC service.

View File

@ -43,6 +43,10 @@ func (h *hist) ModeLine() renderer {
}
func historyStart(ed *Editor) {
if ed.historyFuser == nil {
ed.Notify("history offline")
return
}
prefix := ed.line[:ed.dot]
walker := ed.historyFuser.Walker(prefix)
ed.hist = hist{walker}
@ -85,7 +89,7 @@ func historyDefault(ed *Editor) {
// Implementation.
func (ed *Editor) appendHistory(line string) {
if ed.daemon != nil {
if ed.daemon != nil && ed.historyFuser != nil {
ed.historyMutex.Lock()
ed.daemon.Waits().Add(1)
go func() {

23
main.go
View File

@ -16,6 +16,7 @@ import (
"runtime/pprof"
"strconv"
"syscall"
"time"
"github.com/elves/elvish/daemon"
"github.com/elves/elvish/daemon/api"
@ -143,6 +144,12 @@ func main() {
}
}
const (
daemonWaitOneLoop = 10 * time.Millisecond
daemonWaitLoops = 100
daemonWaitTotal = daemonWaitOneLoop * daemonWaitLoops
)
func initRuntime() (*eval.Evaler, *api.Client) {
var dataDir string
var err error
@ -199,7 +206,7 @@ func initRuntime() (*eval.Evaler, *api.Client) {
fmt.Fprintln(os.Stderr, "warning: failed to kill outdated daemon process:", err)
goto spawnDaemonEnd
}
fmt.Fprintln(os.Stderr, "killed outdated daemon")
logger.Println("killed outdated daemon")
killed = true
}
}
@ -209,7 +216,19 @@ func initRuntime() (*eval.Evaler, *api.Client) {
if err != nil {
fmt.Fprintln(os.Stderr, "warning: cannot start daemon:", err)
} else {
fmt.Fprintln(os.Stderr, "started daemon")
logger.Println("started daemon")
}
for i := 0; i < daemonWaitLoops; i++ {
_, err := cl.Version()
if err == nil {
logger.Println("daemon online")
goto spawnDaemonEnd
} else if i == daemonWaitLoops-1 {
fmt.Fprintf(os.Stderr, "cannot connect to daemon after %v: %v\n", daemonWaitTotal, err)
cl = nil
goto spawnDaemonEnd
}
time.Sleep(daemonWaitOneLoop)
}
}
}