Lots of stuff

This commit is contained in:
Simon Martens
2024-11-11 20:53:27 +01:00
parent 61a51130dd
commit 0aec995441
7 changed files with 117 additions and 33 deletions

12
controllers/controller.go Normal file
View File

@@ -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

View File

@@ -12,6 +12,11 @@ import (
"githib.com/Theodor-Springmann-Stiftung/kgpz_web/server" "githib.com/Theodor-Springmann-Stiftung/kgpz_web/server"
) )
const (
DEFAULT_CONFIG = "config.json"
DEV_CONFIG = "config.dev.json"
)
// 1. Check if folder exists // 1. Check if folder exists
// - If not, clone the repo, if possible or throw if error // - 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. // 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 // - Setup GitHub webhook if set
func main() { 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 { if err := cfg.Read(); err != nil {
helpers.MaybePanic(err, "Error reading config") helpers.MaybePanic(err, "Error reading config")
} }
@@ -32,7 +37,7 @@ func main() {
kgpz := app.NewKGPZ(cfg) kgpz := app.NewKGPZ(cfg)
Bootstrap(kgpz) Bootstrap(kgpz)
server := server.Start(kgpz) server := server.Start(kgpz, cfg)
Start(kgpz, server) Start(kgpz, server)
} }
@@ -50,11 +55,16 @@ func Start(k *app.KGPZ, s *server.Server) {
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() { go func() {
_ = <-sigs sig := <-sigs
fmt.Println("Received signal. Cleaning up.") fmt.Println("Received signal. Cleaning up.")
// INFO: here we add cleanup functions // INFO: here we add cleanup functions
if sig == syscall.SIGTERM {
s.Stop() s.Stop()
fmt.Println("Server stopped. Waiting for FS.") fmt.Println("Server stopped. Waiting for FS.")
} else {
s.Kill()
fmt.Println("Server killed. Waiting for FS.")
}
k.Shutdown() k.Shutdown()
fmt.Println("FS stopped. Exiting.") fmt.Println("FS stopped. Exiting.")
done <- true done <- true

View File

@@ -16,6 +16,10 @@ const (
DEFAULT_GIT_DIR = "data_git" DEFAULT_GIT_DIR = "data_git"
DEFAULT_GND_DIR = "cache_gnd" DEFAULT_GND_DIR = "cache_gnd"
DEFAULT_GEO_DIR = "cache_geo" DEFAULT_GEO_DIR = "cache_geo"
DEFAULT_PORT = "8080"
DEFAULT_ADDR = "localhost"
DEFAULT_HTTPS = false
) )
type ConfigProvider struct { type ConfigProvider struct {
@@ -34,6 +38,10 @@ type Config struct {
WebHookSecret string `json:"webhook_secret" envconfig:"WEBHOOK_SECRET"` WebHookSecret string `json:"webhook_secret" envconfig:"WEBHOOK_SECRET"`
Debug bool `json:"debug" envconfig:"DEBUG"` Debug bool `json:"debug" envconfig:"DEBUG"`
LogData bool `json:"log_data" envconfig:"LOG_DATA"` 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 { func NewConfigProvider(files []string) *ConfigProvider {
@@ -91,6 +99,14 @@ func readDefaults(cfg *Config) *Config {
cfg.GeoPath = DEFAULT_GEO_DIR 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 return cfg
} }

5
server/middleware.go Normal file
View File

@@ -0,0 +1,5 @@
package server
import "net/http"
type Middleware func(http.Handler) http.Handler

17
server/mux.go Normal file
View File

@@ -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
}

View File

@@ -1,26 +1,15 @@
package server package server
import ( import (
"context"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"sync" "sync"
"time"
"githib.com/Theodor-Springmann-Stiftung/kgpz_web/app" "githib.com/Theodor-Springmann-Stiftung/kgpz_web/app"
) "githib.com/Theodor-Springmann-Stiftung/kgpz_web/providers"
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. // 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 // - we reload all clients
// - if data validity catastrophically fails, we restart the router to map error pages. // - if data validity catastrophically fails, we restart the router to map error pages.
type Server struct { type Server struct {
running *sync.WaitGroup Config *providers.ConfigProvider
running chan bool
shutdown *sync.WaitGroup shutdown *sync.WaitGroup
} }
func Start(k *app.KGPZ) *Server { func Start(k *app.KGPZ, c *providers.ConfigProvider) *Server {
return &Server{} return &Server{
Config: c,
}
} }
func (s *Server) Start() { func (s *Server) Start() {
srv := &http.Server{Addr: ":8081"} srv := &http.Server{Addr: s.Config.Address + ":" + s.Config.Port}
s.runner(srv) s.runner(srv)
} }
@@ -49,23 +41,28 @@ func (s *Server) Stop() {
return 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() s.shutdown.Wait()
} }
func (s *Server) Restart() { func (s *Server) Restart() {
if s.running != nil { s.Stop()
s.running.Done()
s.shutdown.Wait()
}
s.Start() s.Start()
} }
func (s *Server) runner(srv *http.Server) { func (s *Server) runner(srv *http.Server) {
s.running = &sync.WaitGroup{} s.running = make(chan bool)
s.shutdown = &sync.WaitGroup{} s.shutdown = &sync.WaitGroup{}
s.running.Add(1)
s.shutdown.Add(1) s.shutdown.Add(1)
cleanup := sync.WaitGroup{} cleanup := sync.WaitGroup{}
@@ -82,6 +79,7 @@ func (s *Server) runner(srv *http.Server) {
srv.Handler = mux srv.Handler = mux
if err := srv.ListenAndServe(); err != http.ErrServerClosed { if err := srv.ListenAndServe(); err != http.ErrServerClosed {
fmt.Println(err)
fmt.Println("Error starting server") fmt.Println("Error starting server")
return return
} }
@@ -91,11 +89,21 @@ func (s *Server) runner(srv *http.Server) {
go func() { go func() {
defer cleanup.Done() defer cleanup.Done()
s.running.Wait() clean := <-s.running
if err := srv.Shutdown(nil); err != nil { 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") fmt.Println("Error shutting down server")
} }
} else {
if err := srv.Close(); err != nil {
fmt.Println(err)
fmt.Println("Error closing server")
}
}
}() }()
} }

View File

@@ -65,5 +65,21 @@
- URL values YYYY/ST and YYYY/ST/P and YYYY/ST/B/P? Are they unique? - 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) - Which names of places should be used? Example: Mitau, Jelgava, Jelgava (Mitau), Mitau (Jelgava)
- Informationen zur Vorlage: not saved yet - Informationen zur Vorlage: not saved yet
- Titel der Werke: not saved yet
- Übersetzer in Werke: geht tatsächlich - Ü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 - Bevorzugtes Datumsformat