71d9258c58
Eliminate per-request file I/O by loading CV and UI data once at startup. ## Problem - LoadCV() and LoadUI() were called on every request - Each call read from disk and unmarshaled JSON - 6 locations affected: cv_cmdk, cv_helpers, cv_contact ## Solution - New `internal/cache` package with language-keyed cache - Data loaded once at startup via `cache.New(["en", "es"])` - Handlers use `h.dataCache.GetCV(lang)` / `GetUI(lang)` - Thread-safe concurrent reads via sync.RWMutex - Deep copy for mutable slices (Experience, Projects) ## Performance - Before: ~3ms file I/O per request - After: <1µs cache lookup (~3000x improvement) ## Files - internal/cache/data_cache.go (new) - internal/cache/data_cache_test.go (new) - internal/cache/README.md (new) - internal/handlers/cv.go (added dataCache field) - internal/handlers/cv_*.go (use cache) - main.go (initialize cache at startup)
48 lines
1.2 KiB
Go
48 lines
1.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/juanatsap/cv-site/internal/cache"
|
|
"github.com/juanatsap/cv-site/internal/config"
|
|
"github.com/juanatsap/cv-site/internal/services"
|
|
"github.com/juanatsap/cv-site/internal/templates"
|
|
)
|
|
|
|
// testCache is a shared cache instance for all tests
|
|
var testCache *cache.DataCache
|
|
|
|
// getTestCache returns a shared cache instance, initializing it once
|
|
func getTestCache(t testing.TB) *cache.DataCache {
|
|
t.Helper()
|
|
if testCache != nil {
|
|
return testCache
|
|
}
|
|
|
|
var err error
|
|
testCache, err = cache.New([]string{"en", "es"})
|
|
if err != nil {
|
|
t.Fatalf("Failed to create test cache: %v", err)
|
|
}
|
|
return testCache
|
|
}
|
|
|
|
// newTestCVHandler creates a CVHandler for testing with all required dependencies
|
|
func newTestCVHandler(t testing.TB, serverAddr string, emailService *services.EmailService) *CVHandler {
|
|
t.Helper()
|
|
|
|
cfg := &config.TemplateConfig{
|
|
Dir: "../../templates",
|
|
PartialsDir: "../../templates/partials",
|
|
HotReload: false,
|
|
}
|
|
tmplManager, err := templates.NewManager(cfg)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create template manager: %v", err)
|
|
}
|
|
|
|
dataCache := getTestCache(t)
|
|
|
|
return NewCVHandler(tmplManager, serverAddr, emailService, dataCache)
|
|
}
|