initial webapp
This commit is contained in:
1 parent
6c989c338c
commit
d32f2b3a66
18 files changed
+1145
-16
No files matched your search
@@ -0,0 +1,85 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"errors"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/nmoniz/any2anexoj/internal/web"
|
||||
)
|
||||
|
||||
//go:embed all:static
|
||||
var staticFS embed.FS
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
slog.Error("any2anexoj-web: fatal error", slog.Any("err", err))
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// run wires up the server, installs signal-driven cancellation, and blocks on
|
||||
// the HTTP server until it stops. It is split out from main so tests can drive
|
||||
// the same code paths if needed.
|
||||
func run() error {
|
||||
addr := os.Getenv("PORT")
|
||||
if addr == "" {
|
||||
addr = ":8080"
|
||||
}
|
||||
// A bare "8080" value is friendlier than the net.Listen-style ":8080".
|
||||
if addr[0] != ':' {
|
||||
addr = ":" + addr
|
||||
}
|
||||
|
||||
// Sub-mount the embedded FS so the static subtree is rooted at "" inside
|
||||
// the web package (matches /static/...).
|
||||
staticSub, err := fs.Sub(staticFS, "static")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
state := web.NewState()
|
||||
srv, err := web.NewServer(state, staticSub)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
httpServer := &http.Server{
|
||||
Addr: addr,
|
||||
Handler: srv.Handler(),
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
}
|
||||
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Kill, os.Interrupt, syscall.SIGTERM)
|
||||
defer cancel()
|
||||
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
slog.Info("any2anexoj-web: listening", slog.String("addr", addr))
|
||||
if err := httpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
errCh <- nil
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
slog.Info("any2anexoj-web: shutting down")
|
||||
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer shutdownCancel()
|
||||
if err := httpServer.Shutdown(shutdownCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user