Skip to content

Appendix: Mutex Protected Variable Map

Matt Mc edited this page Jul 4, 2018 · 1 revision

As mentioned in Rendering Templates, here's a basic implementation of a mutex-protected variable map that you can use if the need arises:

// VarMapMx defines a mutex-protected jet.VarMap that's usable concurrently.
type VarMapMx struct {
  mx     sync.RWMutex
  varMap jet.VarMap
}

// NewVarMapMx returns an initialized VarMapMx instance that is ready to be used.
func NewVarMapMx() *VarMapMx {
  return &VarMapMx{varMap: jet.VarMap{}}
}

// Get returns the value for a key in the embedded jet.VarMap.
// The returned reflect.Value is not valid if the key does not exist.
func (scope *VarMapMx) Get(name string) reflect.Value {
  v, _ := scope.Lookup(name)
  return v
}

// Lookup returns the value for a key in the embedded jet.VarMap
// as well as whether the key was found or not.
func (scope *VarMapMx) Lookup(name string) (reflect.Value, bool) {
  scope.mx.RLock()
  defer scope.mx.RUnlock()
  v, ok := scope.varMap[name]
  return v, ok
}

// Set adds the key value pair in the embedded jet.VarMap.
func (scope *VarMapMx) Set(name string, v interface{}) *VarMapMx {
  scope.mx.Lock()
  defer scope.mx.Unlock()

  scope.varMap.Set(name, v)
  return scope
}

// SetFunc adds a jet.Func to the embedded jet.VarMap.
func (scope *VarMapMx) SetFunc(name string, v jet.Func) *VarMapMx {
  scope.mx.Lock()
  defer scope.mx.Unlock()

  scope.varMap.Set(name, v)
  return scope
}

// SetWriter adds a jet.SafeWriter to the embedded jet.VarMap.
func (scope *VarMapMx) SetWriter(name string, v jet.SafeWriter) *VarMapMx {
  scope.mx.Lock()
  defer scope.mx.Unlock()

  scope.varMap.Set(name, v)
  return scope
}

// GetVarMap returns the embedded jet.VarMap for use in template executions.
func (scope *VarMapMx) GetVarMap() jet.VarMap {
  return scope.varMap
}

Usage is the same as with the regular jet.VarMap:

vars := NewVarMapMx()
vars.Set("user", &User{}).Set("userID", "1234")

if err = t.Execute(&w, vars.GetVarMap(), nil); err != nil {
    // error when executing template
}
Clone this wiki locally