Files
cv-site/internal/handlers/cv.go
T
juanatsap 71d9258c58 feat: add application-level data caching for CV/UI
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)
2025-12-06 15:57:23 +00:00

37 lines
1.2 KiB
Go

package handlers
import (
"time"
"github.com/juanatsap/cv-site/internal/cache"
"github.com/juanatsap/cv-site/internal/pdf"
"github.com/juanatsap/cv-site/internal/services"
"github.com/juanatsap/cv-site/internal/templates"
)
// CVHandler handles CV-related requests
// Methods are split across multiple files for better organization:
// - cv_pages.go: Page rendering (Home, CVContent, DefaultCVShortcut)
// - cv_pdf.go: PDF export (ExportPDF)
// - cv_htmx.go: HTMX toggles (ToggleLength, ToggleIcons, SwitchLanguage, ToggleTheme)
// - cv_contact.go: Contact form submission (HandleContact)
// - cv_helpers.go: Helper functions (skills, dates, git, templates, cookies)
type CVHandler struct {
templates *templates.Manager
pdfGenerator *pdf.Generator
emailService *services.EmailService
serverAddr string
dataCache *cache.DataCache
}
// NewCVHandler creates a new CV handler
func NewCVHandler(tmpl *templates.Manager, serverAddr string, emailService *services.EmailService, dataCache *cache.DataCache) *CVHandler {
return &CVHandler{
templates: tmpl,
pdfGenerator: pdf.NewGenerator(30 * time.Second),
emailService: emailService,
serverAddr: serverAddr,
dataCache: dataCache,
}
}