diff --git a/pages/template.go b/pages/template.go index 4764309..51b45fe 100644 --- a/pages/template.go +++ b/pages/template.go @@ -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 == "" { diff --git a/run_dev.cmd b/run_dev.cmd index f4a38f4..efb3f43 100644 --- a/run_dev.cmd +++ b/run_dev.cmd @@ -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 diff --git a/run_dev.sh b/run_dev.sh index f7c3d31..052cddd 100755 --- a/run_dev.sh +++ b/run_dev.sh @@ -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 diff --git a/util/cache.go b/util/cache.go index 29da355..fa2daa1 100644 --- a/util/cache.go +++ b/util/cache.go @@ -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 }