gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/system/service/service_systemd_linux.go (about) 1 package svc 2 3 import ( 4 "gitee.com/sy_183/go-common/lifecycle" 5 "os" 6 "os/signal" 7 ) 8 9 var isLinuxSystemdService = false 10 11 func init() { 12 if _, err := os.Stat("/run/systemd/system"); err == nil { 13 isLinuxSystemdService = true 14 } 15 } 16 17 type linuxSystemdService struct { 18 app lifecycle.Lifecycle 19 exitCode int 20 21 systemdNotify bool 22 23 notifySignals []os.Signal 24 signalCallback func(sig os.Signal) (exit bool) 25 exitCodeGetter func(err *Error) int 26 } 27 28 func New(name string, app lifecycle.Lifecycle, options ...Option) Service { 29 lss := &linuxSystemdService{ 30 app: app, 31 systemdNotify: isLinuxSystemdService, 32 notifySignals: DefaultNotifySignals[:], 33 signalCallback: DefaultSignalCallback, 34 exitCodeGetter: DefaultExitCodeGetter, 35 } 36 for _, option := range options { 37 option.apply(lss) 38 } 39 return lss 40 } 41 42 func (lss *linuxSystemdService) setSignalNotify(callback func(sig os.Signal) (exit bool), sig ...os.Signal) { 43 lss.signalCallback = callback 44 lss.notifySignals = sig 45 } 46 47 func (lss *linuxSystemdService) setExitCodeGetter(exitCodeGetter func(err *Error) int) { 48 lss.exitCodeGetter = exitCodeGetter 49 } 50 51 func (lss *linuxSystemdService) Run() int { 52 go lss.app.Run() 53 54 sigChan := make(chan os.Signal) 55 signal.Notify(sigChan, lss.notifySignals...) 56 57 startedWaiter := lss.app.StartedWaiter() 58 closedWaiter := make(lifecycle.ChanFuture[error], 1) 59 for { 60 select { 61 case sig := <-sigChan: 62 if lss.signalCallback(sig) { 63 if lss.systemdNotify { 64 SystemdNotify("STOPPING=1") 65 } 66 lss.app.Close(nil) 67 } 68 case err := <-startedWaiter: 69 if err != nil { 70 return lss.exitCodeGetter(&Error{Type: StartError, Err: err}) 71 } 72 lss.app.AddClosedFuture(closedWaiter) 73 if lss.systemdNotify { 74 SystemdNotify("READY=1") 75 } 76 case err := <-closedWaiter: 77 if err != nil { 78 return lss.exitCodeGetter(&Error{Type: ExitError, Err: err}) 79 } 80 return 0 81 } 82 } 83 }