morffix/server/server.go
Samuel Lorch b03e85db0b
All checks were successful
/ release (push) Successful in 42s
Queue Enable
2024-07-06 18:01:51 +02:00

145 lines
3.4 KiB
Go

package server
import (
"context"
"embed"
"fmt"
"html/template"
"log/slog"
"net/http"
"os"
"os/signal"
"time"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/pgx/v5"
"github.com/golang-migrate/migrate/v4/source/iofs"
"github.com/jackc/pgx/v5/pgxpool"
"git.lastassault.de/speatzle/morffix/config"
)
var conf config.Config
var templates *template.Template
var funcMap = template.FuncMap{
"sub": sub,
}
func sub(a, b int) int {
return a - b
}
var db *pgxpool.Pool
func Start(_conf config.Config, tmplFS embed.FS, staticFS embed.FS, migrationsFS embed.FS, resetDB bool) {
conf = _conf
// Static Files
staticServer := http.FS(staticFS)
fs := http.FileServer(staticServer)
// Templates
t := template.New("")
t.Funcs(funcMap)
t, err := t.ParseFS(tmplFS, "tmpl/*.tmpl")
if err != nil {
panic(fmt.Errorf("Parsing templates: %w", err))
}
templates = t
slog.Info("Connecting to Database...")
db, err = pgxpool.New(context.Background(), "postgres://"+conf.Server.Database)
if err != nil {
slog.Error("Unable to create connection pool", "err", err)
return
}
defer db.Close()
slog.Info("Connected to Database, Starting Migration")
driver, err := iofs.New(migrationsFS, "migrations")
if err != nil {
slog.Error("Unable to Create Migration Driver", "err", err)
return
}
m, err := migrate.NewWithSourceInstance("iofs", driver, "pgx5://"+conf.Server.Database)
if err != nil {
slog.Error("Unable to Setup migration", "err", err)
return
}
if resetDB {
slog.Info("Running Down Migrations...")
err = m.Down()
if err != nil {
slog.Error("Unable to Migrate Down", "err", err)
return
}
}
//err = m.Down()
err = m.Up()
if err == migrate.ErrNoChange {
slog.Info("No Migrations Required")
} else if err != nil {
slog.Error("Unable to Migrate", "err", err)
return
} else {
slog.Info("Migration Done")
}
mux := http.NewServeMux()
mux.HandleFunc("/worker", handleWorkerWebsocket)
mux.Handle("/static/", fs)
mux.HandleFunc("/tasks", handleTasks)
mux.HandleFunc("/files/{id}", handleFile)
mux.HandleFunc("/upload/{id}", handleUpload)
mux.HandleFunc("/tasks/{id}", handleTask)
mux.HandleFunc("/scan/{id}", handleScan)
mux.HandleFunc("/libraries/{id}", handleLibrary)
mux.HandleFunc("/libraries", handleLibraries)
mux.HandleFunc("/ffmpeg_commands", handleFfmpegCommands)
mux.HandleFunc("/queue_enable", HandleSetQueueEnable)
mux.HandleFunc("/", handleIndex)
server := &http.Server{
Addr: conf.Server.Address,
Handler: mux,
ReadTimeout: time.Hour,
WriteTimeout: time.Hour,
IdleTimeout: 30 * time.Second,
ReadHeaderTimeout: 10 * time.Second,
}
serverClose := make(chan bool)
go func() {
slog.Info("Listening...", "Address", conf.Server.Address)
err := server.ListenAndServe()
if err != http.ErrServerClosed {
slog.Error("Listen Failed", "err", err)
} else {
slog.Info("Server Closed")
}
serverClose <- true
}()
stopCleanup := make(chan bool, 1)
go manageWorkers(stopCleanup)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, os.Interrupt)
select {
case <-serverClose:
slog.Info("Exiting due to Listen Failure")
case sig := <-sigs:
slog.Info("Stopping Server...", "signal", sig)
stopCtx, cancel := context.WithTimeout(context.Background(), time.Second*10)
server.Shutdown(stopCtx)
cancel()
stopCleanup <- true
slog.Info("Done")
}
}