Skip to content

Instantly share code, notes, and snippets.

@zeebo
Last active December 13, 2015 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeebo/4954914 to your computer and use it in GitHub Desktop.
Save zeebo/4954914 to your computer and use it in GitHub Desktop.
complicated locking strategy
package main
import (
"html/template"
"path/filepath"
"sync"
)
// i like this inline struct style thing. it's fun.
var cachedTemplates = struct {
sync.RWMutex
t map[string]*template.Template
}{t: map[string]*template.Template{}}
// this lock is to make sure only one thing is compiling
// at a time. helps reduce contention on the map lock.
var compileLock sync.Mutex
// set of functions to add to our template
var funcs = template.FuncMap{
"reverse": reverse,
}
func T(name string) *template.Template {
// fast path: grab a read lock and return the template if it
// exists
cachedTemplates.RLock()
t, ok := cachedTemplates.t[name]
cachedTemplates.RUnlock()
if ok {
return t
}
// goal: we don't want to compile the same template twice
// and we want to hold the write lock on the map as minimally
// as possible to avoid blocking requests that already have it
// so we have a compiling lock here.
compileLock.Lock()
defer compileLock.Unlock()
// maybe two threads missed on the same name, so check if we lost
// the race to grab the compile lock and it has been fufilled by
// the other thread. note we don't need a read lock here because
// the write lock below is a subset of the compile lock. There can
// be no concurrent writers to the template map during this read.
if t, ok := cachedTemplates.t[name]; ok {
return t
}
// nope we definitely have to compile the template
t = template.New("_base.html").Funcs(funcs)
t = template.Must(t.ParseFiles(
"templates/_base.html",
filepath.Join("templates", name),
))
cachedTemplates.Lock()
cachedTemplates.t[name] = t
cachedTemplates.Unlock()
return t
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment