From 0aec99544180eff041e2b819db5b7b7655ac1b84 Mon Sep 17 00:00:00 2001 From: Simon Martens Date: Mon, 11 Nov 2024 20:53:27 +0100 Subject: [PATCH] Lots of stuff --- controllers/controller.go | 12 ++++++++ kgpz_web.go | 20 +++++++++--- providers/config.go | 16 ++++++++++ server/middleware.go | 5 +++ server/mux.go | 17 +++++++++++ server/server.go | 64 ++++++++++++++++++++++----------------- techstack.md | 16 ++++++++++ 7 files changed, 117 insertions(+), 33 deletions(-) create mode 100644 controllers/controller.go create mode 100644 server/middleware.go create mode 100644 server/mux.go diff --git a/controllers/controller.go b/controllers/controller.go new file mode 100644 index 0000000..1fad205 --- /dev/null +++ b/controllers/controller.go @@ -0,0 +1,12 @@ +package controller + +import ( + "net/http" + + "githib.com/Theodor-Springmann-Stiftung/kgpz_web/app" + "githib.com/Theodor-Springmann-Stiftung/kgpz_web/templating" +) + +// ControllerFunc is a function that get injected all dependencies and returns a http.HandlerFunc +// A controller is resposible for executing all the neccessary middlewares and rendering the HTML +type ControllerFunc func(kgpz *app.KGPZ, layouts *templating.LayoutRegistry, templates *templating.TemplateRegistry) http.HandlerFunc diff --git a/kgpz_web.go b/kgpz_web.go index 2dee142..755f0d9 100644 --- a/kgpz_web.go +++ b/kgpz_web.go @@ -12,6 +12,11 @@ import ( "githib.com/Theodor-Springmann-Stiftung/kgpz_web/server" ) +const ( + DEFAULT_CONFIG = "config.json" + DEV_CONFIG = "config.dev.json" +) + // 1. Check if folder exists // - If not, clone the repo, if possible or throw if error // 2. If the folder exists, we try to serialize -- and spawn a goroutine to pull. @@ -24,7 +29,7 @@ import ( // - Setup GitHub webhook if set func main() { - cfg := providers.NewConfigProvider([]string{"config.dev.json", "config.json"}) + cfg := providers.NewConfigProvider([]string{DEV_CONFIG, DEFAULT_CONFIG}) if err := cfg.Read(); err != nil { helpers.MaybePanic(err, "Error reading config") } @@ -32,7 +37,7 @@ func main() { kgpz := app.NewKGPZ(cfg) Bootstrap(kgpz) - server := server.Start(kgpz) + server := server.Start(kgpz, cfg) Start(kgpz, server) } @@ -50,11 +55,16 @@ func Start(k *app.KGPZ, s *server.Server) { signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { - _ = <-sigs + sig := <-sigs fmt.Println("Received signal. Cleaning up.") // INFO: here we add cleanup functions - s.Stop() - fmt.Println("Server stopped. Waiting for FS.") + if sig == syscall.SIGTERM { + s.Stop() + fmt.Println("Server stopped. Waiting for FS.") + } else { + s.Kill() + fmt.Println("Server killed. Waiting for FS.") + } k.Shutdown() fmt.Println("FS stopped. Exiting.") done <- true diff --git a/providers/config.go b/providers/config.go index 6b4a37c..64ed22b 100644 --- a/providers/config.go +++ b/providers/config.go @@ -16,6 +16,10 @@ const ( DEFAULT_GIT_DIR = "data_git" DEFAULT_GND_DIR = "cache_gnd" DEFAULT_GEO_DIR = "cache_geo" + + DEFAULT_PORT = "8080" + DEFAULT_ADDR = "localhost" + DEFAULT_HTTPS = false ) type ConfigProvider struct { @@ -34,6 +38,10 @@ type Config struct { WebHookSecret string `json:"webhook_secret" envconfig:"WEBHOOK_SECRET"` Debug bool `json:"debug" envconfig:"DEBUG"` LogData bool `json:"log_data" envconfig:"LOG_DATA"` + + Address string `json:"address" envconfig:"ADDRESS"` + Port string `json:"port" envconfig:"PORT"` + Https bool `json:"https" envconfig:"HTTPS"` } func NewConfigProvider(files []string) *ConfigProvider { @@ -91,6 +99,14 @@ func readDefaults(cfg *Config) *Config { cfg.GeoPath = DEFAULT_GEO_DIR } + if strings.TrimSpace(cfg.Address) == "" { + cfg.Address = DEFAULT_ADDR + } + + if strings.TrimSpace(cfg.Port) == "" { + cfg.Port = DEFAULT_PORT + } + return cfg } diff --git a/server/middleware.go b/server/middleware.go new file mode 100644 index 0000000..dee5451 --- /dev/null +++ b/server/middleware.go @@ -0,0 +1,5 @@ +package server + +import "net/http" + +type Middleware func(http.Handler) http.Handler diff --git a/server/mux.go b/server/mux.go new file mode 100644 index 0000000..5591e2a --- /dev/null +++ b/server/mux.go @@ -0,0 +1,17 @@ +package server + +import "net/http" + +type Mux struct { + sm http.ServeMux +} + +func NewMux() *Mux { + return &Mux{ + sm: http.ServeMux{}, + } +} + +func (m *Mux) Router() *http.ServeMux { + return &m.sm +} diff --git a/server/server.go b/server/server.go index d244bd5..0b4296d 100644 --- a/server/server.go +++ b/server/server.go @@ -1,26 +1,15 @@ package server import ( + "context" "fmt" "io" "net/http" "sync" + "time" "githib.com/Theodor-Springmann-Stiftung/kgpz_web/app" -) - -type ServerState int - -const ( - Created ServerState = iota - Running - Restarting - ShuttingDown - ShutDown - ShuttedDown - Kill - Killing - Killed + "githib.com/Theodor-Springmann-Stiftung/kgpz_web/providers" ) // INFO: Server is a meta-package that handles the current router, which it starts in a goroutine. @@ -31,16 +20,19 @@ const ( // - we reload all clients // - if data validity catastrophically fails, we restart the router to map error pages. type Server struct { - running *sync.WaitGroup + Config *providers.ConfigProvider + running chan bool shutdown *sync.WaitGroup } -func Start(k *app.KGPZ) *Server { - return &Server{} +func Start(k *app.KGPZ, c *providers.ConfigProvider) *Server { + return &Server{ + Config: c, + } } func (s *Server) Start() { - srv := &http.Server{Addr: ":8081"} + srv := &http.Server{Addr: s.Config.Address + ":" + s.Config.Port} s.runner(srv) } @@ -49,23 +41,28 @@ func (s *Server) Stop() { return } - s.running.Done() + s.running <- true + s.shutdown.Wait() +} + +func (s *Server) Kill() { + if s.running == nil { + return + } + + s.running <- false s.shutdown.Wait() } func (s *Server) Restart() { - if s.running != nil { - s.running.Done() - s.shutdown.Wait() - } + s.Stop() s.Start() } func (s *Server) runner(srv *http.Server) { - s.running = &sync.WaitGroup{} + s.running = make(chan bool) s.shutdown = &sync.WaitGroup{} - s.running.Add(1) s.shutdown.Add(1) cleanup := sync.WaitGroup{} @@ -82,6 +79,7 @@ func (s *Server) runner(srv *http.Server) { srv.Handler = mux if err := srv.ListenAndServe(); err != http.ErrServerClosed { + fmt.Println(err) fmt.Println("Error starting server") return } @@ -91,10 +89,20 @@ func (s *Server) runner(srv *http.Server) { go func() { defer cleanup.Done() - s.running.Wait() + clean := <-s.running - if err := srv.Shutdown(nil); err != nil { - fmt.Println("Error shutting down server") + if clean { + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(8*time.Second)) + defer cancel() + if err := srv.Shutdown(ctx); err != nil { + fmt.Println(err) + fmt.Println("Error shutting down server") + } + } else { + if err := srv.Close(); err != nil { + fmt.Println(err) + fmt.Println("Error closing server") + } } }() diff --git a/techstack.md b/techstack.md index 401170f..01c4e68 100644 --- a/techstack.md +++ b/techstack.md @@ -65,5 +65,21 @@ - URL values YYYY/ST and YYYY/ST/P and YYYY/ST/B/P? Are they unique? - Which names of places should be used? Example: Mitau, Jelgava, Jelgava (Mitau), Mitau (Jelgava) - Informationen zur Vorlage: not saved yet +- Titel der Werke: not saved yet - Übersetzer in Werke: geht tatsächlich +- Für die meisten Beiträge ist kein Akteur angegeben (Autor, Übersetzer etc.) +- Kurzzitat: KGPZ St. 2, 14 Januar 1774 ? + - Besser: KGPZ 2/1774, 14. Januar +- Die Seite ist sehr gelb???? +- Übersicht nach Werken = Übersicht nach Personen + - Besser: Person + Autor + Rezensiert + Todesanzeige + Werke + - Ansicht ist nicht strukturiert genug, kann man fixen +- Navigation: Galerie / Durchklicken?? +- Weniger Kästen / Volle Seitenbreite ausnutzen + - Horizontale Jahresnavigation durch vertikale ersetzen, so wie in der Einzelansicht +- Was ist "Link auf seite teilen"? - Bevorzugtes Datumsformat