Improved page rendering and caching and disabled tracking for not found handler.

This commit is contained in:
Marvin Blum
2020-06-21 23:18:52 +02:00
committed by Marvin Blum
parent 38bfac3a8a
commit 619924b4ec
3 changed files with 78 additions and 65 deletions

View File

@@ -3,11 +3,11 @@ package tpl
import (
"bytes"
"github.com/emvi/logbuch"
"github.com/emvi/pirsch"
"github.com/gosimple/slug"
"html/template"
"net/http"
"os"
"sync"
"time"
)
@@ -15,61 +15,68 @@ const (
templateDir = "template/*"
)
var (
type Cache struct {
tpl *template.Template
tplCache = make(map[string][]byte)
cache map[string][]byte
hotReload bool
)
var funcMap = template.FuncMap{
"slug": slug.Make,
"format": func(t time.Time, layout string) string {
return t.Format(layout)
},
m sync.RWMutex
}
func LoadTemplate() {
func NewCache() *Cache {
cache := &Cache{
cache: make(map[string][]byte),
hotReload: os.Getenv("MB_HOT_RELOAD") == "true",
}
cache.load()
return cache
}
func (cache *Cache) load() {
logbuch.Debug("Loading templates")
funcMap := template.FuncMap{
"slug": slug.Make,
"format": func(t time.Time, layout string) string {
return t.Format(layout)
},
}
var err error
tpl, err = template.New("").Funcs(funcMap).ParseGlob(templateDir)
cache.tpl, err = template.New("").Funcs(funcMap).ParseGlob(templateDir)
if err != nil {
logbuch.Fatal("Error loading template", logbuch.Fields{"err": err})
}
hotReload = os.Getenv("MB_HOT_RELOAD") == "true"
logbuch.Debug("Templates loaded", logbuch.Fields{"hot_reload": hotReload})
logbuch.Debug("Templates loaded", logbuch.Fields{"hot_reload": cache.hotReload})
}
func renderTemplate(name string) {
logbuch.Debug("Rendering template", logbuch.Fields{"name": name})
var buffer bytes.Buffer
func (cache *Cache) Render(w http.ResponseWriter, name string, data interface{}) {
cache.m.RLock()
if err := tpl.ExecuteTemplate(&buffer, name, nil); err != nil {
logbuch.Fatal("Error executing template", logbuch.Fields{"err": err, "name": name})
}
if cache.cache[name] == nil || cache.hotReload {
cache.m.RUnlock()
cache.m.Lock()
defer cache.m.Unlock()
logbuch.Debug("Rendering template", logbuch.Fields{"name": name})
var buffer bytes.Buffer
tplCache[name] = buffer.Bytes()
}
func Get() *template.Template {
return tpl
}
func ServeTemplate(name string, tracker *pirsch.Tracker) http.HandlerFunc {
// render once so we have it in cache
renderTemplate(name)
return func(w http.ResponseWriter, r *http.Request) {
tracker.Hit(r)
if hotReload {
LoadTemplate()
renderTemplate(name)
if err := cache.tpl.ExecuteTemplate(&buffer, name, data); err != nil {
logbuch.Error("Error executing template", logbuch.Fields{"err": err, "name": name})
w.WriteHeader(http.StatusInternalServerError)
}
if _, err := w.Write(tplCache[name]); err != nil {
logbuch.Error("Error returning page to client", logbuch.Fields{"err": err, "name": name})
}
cache.cache[name] = buffer.Bytes()
} else {
cache.m.RUnlock()
}
if _, err := w.Write(cache.cache[name]); err != nil {
logbuch.Error("Error sending response to client", logbuch.Fields{"err": err, "template": name})
w.WriteHeader(http.StatusInternalServerError)
}
}
func (cache *Cache) Clear() {
cache.m.Lock()
defer cache.m.Unlock()
cache.cache = make(map[string][]byte)
}