Services can now write to pidfiles

This commit is contained in:
Sasha Koshka 2023-05-31 18:08:29 -04:00
parent 631796a726
commit 8a528e2b4e
4 changed files with 43 additions and 24 deletions

View File

@ -4,8 +4,9 @@ import "io"
import "os" import "os"
import "log" import "log"
import "time" import "time"
import "hnakra/rotate"
import "hnakra/router" import "hnakra/router"
import "hnakra/rotate"
import "hnakra/daemon"
import "hnakra/routines" import "hnakra/routines"
import "hnakra/router/rcon" import "hnakra/router/rcon"
import "hnakra/router/config" import "hnakra/router/config"
@ -59,10 +60,10 @@ func main () {
manager := routines.Manager { RestartDeadline: time.Second * 8 } manager := routines.Manager { RestartDeadline: time.Second * 8 }
rout := router.New(conf) rout := router.New(conf)
srvhnakra := &srvhnakra.Server { Config: conf, Router: rout } srvhnakra := &srvhnakra.Server { Config: conf, Router: rout }
manager.Append(srvhnakra.ListenAndServe) manager.Append(srvhnakra)
if conf.HTTPSEnable() { if conf.HTTPSEnable() {
srvhttps := &srvhttps.Server { Config: conf, Handler: rout } srvhttps := &srvhttps.Server { Config: conf, Handler: rout }
manager.Append(srvhttps.ListenAndServe) manager.Append(srvhttps)
} }
// set up rcon // set up rcon
@ -74,12 +75,19 @@ func main () {
log.SetOutput(originalWriter) log.SetOutput(originalWriter)
} }
// be a daemon
daemon.ShutdownOnSigint()
pidfile := daemon.PidFile(os.Getenv("HNAKRA_PIDFILE"))
if !pidfile.Empty() {
err := pidfile.Start()
if err != nil { log.Println("!!! could not write pid:", err) }
}
defer func () {
err := pidfile.Close()
if err != nil { log.Println("!!! could not delete pidfile:", err) }
} ()
// run servers // run servers
err = manager.Run() err = manager.Run()
if err != nil { log.Println("XXX", err) } if err != nil { log.Println("XXX", err) }
} }
func httpsRoutine (server *srvhttps.Server) {
err := server.ListenAndServe()
if err != nil { log.Println("XXX", err) }
}

View File

@ -13,7 +13,7 @@ type Server struct {
Router *router.Router Router *router.Router
} }
func (server *Server) ListenAndServe () (err error) { func (server *Server) Run () (err error) {
server.underlying, err = tls.Listen ( server.underlying, err = tls.Listen (
"tcp", fmt.Sprint(":", server.Config.RouterPort()), "tcp", fmt.Sprint(":", server.Config.RouterPort()),
config.TLSConfigFor(server.Config)) config.TLSConfigFor(server.Config))
@ -29,6 +29,6 @@ func (server *Server) ListenAndServe () (err error) {
} }
} }
func (server *Server) Close () error { func (server *Server) Shutdown () error {
return server.underlying.Close() return server.underlying.Close()
} }

View File

@ -11,7 +11,7 @@ type Server struct {
Handler http.Handler Handler http.Handler
} }
func (server *Server) ListenAndServe () error { func (server *Server) Run () error {
server.underlying = &http.Server { server.underlying = &http.Server {
Addr: fmt.Sprint(":", server.Config.HTTPSPort()), Addr: fmt.Sprint(":", server.Config.HTTPSPort()),
// ReadHeaderTimeout: timeoutReadHeader * time.Second, // ReadHeaderTimeout: timeoutReadHeader * time.Second,
@ -26,6 +26,6 @@ func (server *Server) ListenAndServe () error {
return server.underlying.ListenAndServeTLS("", "") return server.underlying.ListenAndServeTLS("", "")
} }
func (server *Server) Close () error { func (server *Server) Shutdown () error {
return server.underlying.Close() return server.underlying.Close()
} }

View File

@ -5,6 +5,7 @@ import "os"
import "log" import "log"
import "time" import "time"
import "hnakra/rotate" import "hnakra/rotate"
import "hnakra/daemon"
import "hnakra/routines" import "hnakra/routines"
// Service is capable of managing multiple mounts. It also sets up logging // Service is capable of managing multiple mounts. It also sets up logging
@ -12,6 +13,8 @@ import "hnakra/routines"
type Service struct { type Service struct {
ServiceInfo ServiceInfo
Mounts []Mount Mounts []Mount
manager routines.Manager
} }
// NewService provides a shorthand for creating a new service, leaving most // NewService provides a shorthand for creating a new service, leaving most
@ -29,6 +32,8 @@ func NewService (name, description string, mounts ...Mount) *Service {
// Run runs the mounts within the service, and only exits when all of them have // Run runs the mounts within the service, and only exits when all of them have
// exited. It will automatically start logging to the directory specified by // exited. It will automatically start logging to the directory specified by
// $HNAKRA_LOG_DIR. If that variable is unset, it will just log to stdout. // $HNAKRA_LOG_DIR. If that variable is unset, it will just log to stdout.
// Additionally, if $HNAKRA_PIDFILE is set, it will write the process PID to the
// file specified by it.
func (service *Service) Run () error { func (service *Service) Run () error {
// set up logging // set up logging
logDir := os.Getenv("HNAKRA_LOG_DIR") logDir := os.Getenv("HNAKRA_LOG_DIR")
@ -41,16 +46,28 @@ func (service *Service) Run () error {
log.Println("... starting service", service.Name) log.Println("... starting service", service.Name)
// set up routine manager // set up routine manager
manager := routines.Manager { RestartDeadline: time.Second * 8 } service.manager = routines.Manager { RestartDeadline: time.Second * 8 }
manager.Routines = make([]routines.Routine, len(service.Mounts)) service.manager.Routines = make([]routines.Routine, len(service.Mounts))
for index, mount := range service.Mounts { for index, mount := range service.Mounts {
manager.Routines[index] = func () error { service.manager.Routines[index] = routines.From (func () error {
return mount.Run(service.ServiceInfo) return mount.Run(service.ServiceInfo)
}, mount.Shutdown)
} }
// be a daemon
daemon.ShutdownOnSigint(service)
pidfile := daemon.PidFile(os.Getenv("HNAKRA_PIDFILE"))
if !pidfile.Empty() {
err := pidfile.Start()
if err != nil { log.Println("!!! could not write pid:", err) }
defer func () {
err := pidfile.Close()
if err != nil { log.Println("!!! could not delete pidfile:", err) }
} ()
} }
// send it // send it
err := manager.Run() err := service.manager.Run()
if err != nil { log.Println("XXX", err) } if err != nil { log.Println("XXX", err) }
return err return err
} }
@ -70,11 +87,5 @@ func (service *Service) Close () (err error) {
// Shutdown gracefully shuts down each mount in the service. This will cause // Shutdown gracefully shuts down each mount in the service. This will cause
// Run() to exit. // Run() to exit.
func (service *Service) Shutdown () (err error) { func (service *Service) Shutdown () (err error) {
for _, mount := range service.Mounts { return service.manager.Shutdown()
singleErr := mount.Shutdown()
if singleErr != nil {
err = singleErr
}
}
return
} }