Added option to hot reload templates for development.

This commit is contained in:
Marvin Blum
2019-12-27 20:24:24 +01:00
parent ef1223b4aa
commit 53e7d6dcf4
4 changed files with 41 additions and 10 deletions

View File

@@ -5,6 +5,7 @@ import (
"github.com/emvi/logbuch"
"os"
"path/filepath"
"strings"
)
const (
@@ -18,7 +19,7 @@ var (
)
func LoadTemplates() {
tplCache = util.NewTemplateCache()
tplCache = util.NewTemplateCache(strings.ToLower(os.Getenv("SCHNITTFEST_HOT_RELOAD")) == "true")
templateBase := os.Getenv("SCHNITTFEST_TEMPLATE_BASE")
if templateBase == "" {

View File

@@ -3,5 +3,6 @@ set SCHNITTFEST_LOGLEVEL=debug
set SCHNITTFEST_ALLOWED_ORIGINS=*
set SCHNITTFEST_TLS_ENABLE=false
set SCHNITTFEST_DISABLE_CACHE=true
set SCHNITTFEST_HOT_RELOAD=true
go run main.go

View File

@@ -5,5 +5,6 @@ export SCHNITTFEST_LOGLEVEL=debug
export SCHNITTFEST_ALLOWED_ORIGINS=*
export SCHNITTFEST_TLS_ENABLE=false
export SCHNITTFEST_DISABLE_CACHE=true
export SCHNITTFEST_HOT_RELOAD=true
go run main.go

View File

@@ -6,23 +6,30 @@ import (
"sync"
)
type cachedTemplate struct {
tpl *template.Template
files []string
}
// TemplateCache caches templates.
type TemplateCache struct {
templates map[string]*template.Template
templates map[string]cachedTemplate
disabled bool
mutex sync.RWMutex
}
// NewTemplateCache creates a new template cache.
func NewTemplateCache() *TemplateCache {
return &TemplateCache{templates: make(map[string]*template.Template)}
// If disabled is set to true, the templates are reloaded on each call.
func NewTemplateCache(disabled bool) *TemplateCache {
return &TemplateCache{templates: make(map[string]cachedTemplate), disabled: disabled}
}
// ParseFiles parses the given template files and stores them as one template called name.
func (tplcache *TemplateCache) ParseFiles(name string, files ...string) (*template.Template, error) {
if tplcache.templates[name] != nil {
if _, ok := tplcache.templates[name]; ok && !tplcache.disabled {
tplcache.mutex.RLock()
defer tplcache.mutex.RUnlock()
return tplcache.templates[name], nil
return tplcache.templates[name].tpl, nil
}
tplcache.mutex.Lock()
@@ -34,16 +41,27 @@ func (tplcache *TemplateCache) ParseFiles(name string, files ...string) (*templa
return nil, err
}
tplcache.templates[name] = tpl
tplcache.templates[name] = cachedTemplate{tpl, files}
return tpl, nil
}
// GetTemplate returns a cached template by name or nil if not found.
func (tplcache *TemplateCache) GetTemplate(name string) *template.Template {
if tplcache.templates[name] != nil {
tpl, ok := tplcache.templates[name]
if ok && tplcache.disabled {
newTpl, err := tplcache.ParseFiles(name, tpl.files...)
if err != nil {
logbuch.Error("Error parsing file on cache rebuild", logbuch.Fields{"err": err, "name": name})
return nil
}
return newTpl
} else if ok {
tplcache.mutex.RLock()
defer tplcache.mutex.RUnlock()
return tplcache.templates[name]
return tplcache.templates[name].tpl
}
return nil
@@ -51,5 +69,15 @@ func (tplcache *TemplateCache) GetTemplate(name string) *template.Template {
// Clear clears the template cache.
func (tplcache *TemplateCache) Clear() {
tplcache.templates = make(map[string]*template.Template)
tplcache.templates = make(map[string]cachedTemplate)
}
// Enable enables the cache, so that each template is loaded from cache.
func (tplcache *TemplateCache) Enable() {
tplcache.disabled = false
}
// Disable disables the cache, so that each template is reloaded on each call.
func (tplcache *TemplateCache) Disable() {
tplcache.disabled = true
}