mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
cmd/ctrld: response to OS service manager earlier
When startup, ctrld waits for network up before calling s.Run to starts its logic. However, if network is down on startup, ctrld will hang on waiting for network up. That causes OS service manager unhappy, as ctrld do not response to it, marking ctrld as failure service and never start ctrld again. To fix this, we should call s.Run as soon as possible, and use a channel for waiting a signal that we can actual do our logic after network up. Update #34
This commit is contained in:
committed by
Cuong Manh Le
parent
f0c604a9f1
commit
9927803497
@@ -90,6 +90,35 @@ func initCLI() {
|
||||
if daemon && runtime.GOOS == "windows" {
|
||||
log.Fatal("Cannot run in daemon mode. Please install a Windows service.")
|
||||
}
|
||||
|
||||
waitCh := make(chan struct{})
|
||||
stopCh := make(chan struct{})
|
||||
if !daemon {
|
||||
// We need to call s.Run() as soon as possible to response to the OS manager, so it
|
||||
// can see ctrld is running and don't mark ctrld as failed service.
|
||||
go func() {
|
||||
p := &prog{
|
||||
waitCh: waitCh,
|
||||
stopCh: stopCh,
|
||||
}
|
||||
s, err := service.New(p, svcConfig)
|
||||
if err != nil {
|
||||
mainLog.Fatal().Err(err).Msg("failed create new service")
|
||||
}
|
||||
serviceLogger, err := s.Logger(nil)
|
||||
if err != nil {
|
||||
mainLog.Error().Err(err).Msg("failed to get service logger")
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.Run(); err != nil {
|
||||
if sErr := serviceLogger.Error(err); sErr != nil {
|
||||
mainLog.Error().Err(sErr).Msg("failed to write service log")
|
||||
}
|
||||
mainLog.Error().Err(err).Msg("failed to start service")
|
||||
}
|
||||
}()
|
||||
}
|
||||
noConfigStart := isNoConfigStart(cmd)
|
||||
writeDefaultConfig := !noConfigStart && configBase64 == ""
|
||||
configs := []struct {
|
||||
@@ -150,22 +179,8 @@ func initCLI() {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
s, err := service.New(&prog{}, svcConfig)
|
||||
if err != nil {
|
||||
mainLog.Fatal().Err(err).Msg("failed create new service")
|
||||
}
|
||||
serviceLogger, err := s.Logger(nil)
|
||||
if err != nil {
|
||||
mainLog.Error().Err(err).Msg("failed to get service logger")
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.Run(); err != nil {
|
||||
if sErr := serviceLogger.Error(err); sErr != nil {
|
||||
mainLog.Error().Err(sErr).Msg("failed to write service log")
|
||||
}
|
||||
mainLog.Error().Err(err).Msg("failed to start service")
|
||||
}
|
||||
close(waitCh)
|
||||
<-stopCh
|
||||
},
|
||||
}
|
||||
runCmd.Flags().BoolVarP(&daemon, "daemon", "d", false, "Run as daemon")
|
||||
|
||||
@@ -28,7 +28,9 @@ var svcConfig = &service.Config{
|
||||
}
|
||||
|
||||
type prog struct {
|
||||
mu sync.Mutex
|
||||
mu sync.Mutex
|
||||
waitCh chan struct{}
|
||||
stopCh chan struct{}
|
||||
|
||||
cfg *ctrld.Config
|
||||
cache dnscache.Cacher
|
||||
@@ -41,6 +43,8 @@ func (p *prog) Start(s service.Service) error {
|
||||
}
|
||||
|
||||
func (p *prog) run() {
|
||||
// Wait the caller to signal that we can do our logic.
|
||||
<-p.waitCh
|
||||
p.preRun()
|
||||
if p.cfg.Service.CacheEnable {
|
||||
cacher, err := dnscache.NewLRUCache(p.cfg.Service.CacheSize)
|
||||
@@ -132,6 +136,7 @@ func (p *prog) Stop(s service.Service) error {
|
||||
return err
|
||||
}
|
||||
mainLog.Info().Msg("Service stopped")
|
||||
close(p.stopCh)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user