Files
kgpz_web/server/server.go
2024-11-11 15:50:38 +01:00

90 lines
1.7 KiB
Go

package server
import (
"fmt"
"io"
"net/http"
"githib.com/Theodor-Springmann-Stiftung/kgpz_web/app"
)
type ServerState int
const (
Created ServerState = iota
Running
Restarting
ShuttingDown
ShutDown
ShuttedDown
Kill
Killing
Killed
)
// INFO: Server is a meta-package that handles the current router, which it starts in a goroutine.
// The router must be able to restart itself, if the data validation fails, so we subscribe to a channel on the app,
// which indicates that the data has changed
// On data change:
// - we invalidate all caches if data is valid
// - we reload all clients
// - if data validity catastrophically fails, we restart the router to map error pages.
type Server struct {
}
func Start(k *app.KGPZ) *Server {
return &Server{}
}
func (s *Server) Start() {
srv := &http.Server{Addr: ":8081"}
s.killHandler(srv)
s.shutdownHandler(srv)
s.runnerHandler(srv)
s.restartHandler()
}
func (s *Server) runnerHandler(srv *http.Server) {
shutttingdown := s.Events.Subscribe(1)
go func() {
s.Events.Publish(Running)
// EXAMPLE:
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "hello world\n")
})
srv.Handler = mux
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
fmt.Println("Error starting server")
return
}
loop:
for {
msg := <-shutttingdown
if msg == ShuttingDown {
s.Events.Publish(ShuttedDown)
break loop
}
if msg == Killing {
s.Events.Publish(Killed)
break loop
}
}
}()
go func() {
s.BreakUntil(shutdown, ShutDown)
fmt.Println("Shutting down server")
if err := srv.Shutdown(nil); err != nil {
fmt.Println("Error shutting down server")
}
s.Events.Publish(ShuttingDown)
}()
}