kardianos / service

Run go programs as a service on major platforms.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

macos: LaunchDaemon Restart implementation should perhaps use kickstart

slimsag opened this issue · comments

Right now the macOS Restart implementation is done in terms of stopping and starting the service:

service/service_darwin.go

Lines 258 to 265 in 3596dfa

func (s *darwinLaunchdService) Restart() error {
err := s.Stop()
if err != nil {
return err
}
time.Sleep(50 * time.Millisecond)
return s.Start()
}

Start and Stop actually load and unload the launch daemon plist, which means that if the program crashes for any reason (e.g. another goroutine panics or something) then the daemon would be unloaded and would not start again on future system restarts for example.

I encountered this doing something a bit weird: having my service Restart itself. This works on Windows/Linux, but not macOS due to how Restart is implemented (this was easy enough to workaround by just having my process exit though.)

I believe a better implementation may be to use kickstart with the -k flag as described here: https://serverfault.com/a/947469

Hello. I've tripped over this as well.

Another problem with this implementation is that user probably expects that in case service is currently stopped, Start() and Restart() will have identical behavior (true for systemd, for example). This implementation fails in this case, because Stopping() a service that is not running results in error, and Start() is not called.

BR,
ympek