refactor(worker): lazy-init embedded static assets via sync.OnceValues

Remove package-level init() and globals; resolve the embedded sub-FS once on first use, preserving handler behavior.
This commit is contained in:
2026-06-19 14:26:34 +01:00
parent 86ee0e28ed
commit 70a6eb2e52
+14 -18
View File
@@ -5,33 +5,28 @@ import (
"io/fs" "io/fs"
"net/http" "net/http"
"strings" "strings"
"sync"
"github.com/rs/zerolog/log"
) )
//go:embed static/* //go:embed static/*
var staticFS embed.FS var staticFS embed.FS
// staticSubFS is the static subdirectory filesystem // staticFiles lazily resolves the embedded "static" subdirectory exactly once.
var staticSubFS fs.FS // Using sync.OnceValues avoids an init() and package-level mutable state while
// preserving the previous behavior: the dashboard is served when resolution
// staticInitErr stores any error from static filesystem initialization // succeeds and reports a clear error otherwise.
var staticInitErr error var staticFiles = sync.OnceValues(func() (fs.FS, error) {
return fs.Sub(staticFS, "static")
func init() { })
staticSubFS, staticInitErr = fs.Sub(staticFS, "static")
if staticInitErr != nil {
log.Warn().Err(staticInitErr).Msg("Static filesystem initialization failed - dashboard will be unavailable")
}
}
// serveIndex serves the index.html file for the root path // serveIndex serves the index.html file for the root path
func serveIndex(w http.ResponseWriter, r *http.Request) { func serveIndex(w http.ResponseWriter, r *http.Request) {
if staticInitErr != nil { sub, err := staticFiles()
if err != nil {
http.Error(w, "Dashboard unavailable: static files not initialized", http.StatusServiceUnavailable) http.Error(w, "Dashboard unavailable: static files not initialized", http.StatusServiceUnavailable)
return return
} }
content, err := fs.ReadFile(staticSubFS, "index.html") content, err := fs.ReadFile(sub, "index.html")
if err != nil { if err != nil {
http.Error(w, "Dashboard not found", http.StatusNotFound) http.Error(w, "Dashboard not found", http.StatusNotFound)
return return
@@ -46,14 +41,15 @@ func serveIndex(w http.ResponseWriter, r *http.Request) {
// serveAssets serves static assets from the embedded filesystem // serveAssets serves static assets from the embedded filesystem
func serveAssets(w http.ResponseWriter, r *http.Request) { func serveAssets(w http.ResponseWriter, r *http.Request) {
if staticInitErr != nil { sub, err := staticFiles()
if err != nil {
http.Error(w, "Assets unavailable: static files not initialized", http.StatusServiceUnavailable) http.Error(w, "Assets unavailable: static files not initialized", http.StatusServiceUnavailable)
return return
} }
// Strip the /assets/ prefix and serve the file // Strip the /assets/ prefix and serve the file
path := strings.TrimPrefix(r.URL.Path, "/") path := strings.TrimPrefix(r.URL.Path, "/")
content, err := fs.ReadFile(staticSubFS, path) content, err := fs.ReadFile(sub, path)
if err != nil { if err != nil {
http.Error(w, "Asset not found", http.StatusNotFound) http.Error(w, "Asset not found", http.StatusNotFound)
return return