diff options
author | Bjørn Erik Pedersen <[email protected]> | 2017-11-16 01:23:37 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2017-11-16 01:23:37 +0100 |
commit | f5ed04bd4a2ba1a62482b381470f04aad98375f5 (patch) | |
tree | b5d86ba6494daf02cc1cafb073484f79fe62490c /tpl/partials | |
parent | 7730d683e8b030c64c5f986b8166c8e65b777ab3 (diff) | |
download | hugo-f5ed04bd4a2ba1a62482b381470f04aad98375f5.tar.gz hugo-f5ed04bd4a2ba1a62482b381470f04aad98375f5.zip |
tpl/partials: Fix cache locking
To make sure a cached partial is ony executed exactly once.
Performance same:
```bash
name old time/op new time/op delta
TemplateParamsKeysToLower-4 17.2µs ± 0% 16.5µs ± 0% ~ (p=1.000 n=1+1)
Partial-4 18.6µs ± 0% 19.4µs ± 0% ~ (p=1.000 n=1+1)
PartialCached-4 64.2ns ± 0% 63.7ns ± 0% ~ (p=1.000 n=1+1)
name old alloc/op new alloc/op delta
TemplateParamsKeysToLower-4 2.66kB ± 0% 2.66kB ± 0% ~ (all equal)
Partial-4 1.31kB ± 0% 1.31kB ± 0% ~ (all equal)
PartialCached-4 0.00B 0.00B ~ (all equal)
name old allocs/op new allocs/op delta
TemplateParamsKeysToLower-4 92.0 ± 0% 92.0 ± 0% ~ (all equal)
Partial-4 41.0 ± 0% 41.0 ± 0% ~ (all equal)
```
Diffstat (limited to 'tpl/partials')
-rw-r--r-- | tpl/partials/partials.go | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/tpl/partials/partials.go b/tpl/partials/partials.go index d3a75edad..d999041be 100644 --- a/tpl/partials/partials.go +++ b/tpl/partials/partials.go @@ -110,27 +110,30 @@ func (ns *Namespace) IncludeCached(name string, context interface{}, variant ... return ns.getOrCreate(key, name, context) } -func (ns *Namespace) getOrCreate(key, name string, context interface{}) (p interface{}, err error) { - var ok bool +func (ns *Namespace) getOrCreate(key, name string, context interface{}) (interface{}, error) { ns.cachedPartials.RLock() - p, ok = ns.cachedPartials.p[key] + p, ok := ns.cachedPartials.p[key] ns.cachedPartials.RUnlock() if ok { - return + return p, nil } ns.cachedPartials.Lock() - if p, ok = ns.cachedPartials.p[key]; !ok { - ns.cachedPartials.Unlock() - p, err = ns.Include(name, context) + defer ns.cachedPartials.Unlock() - ns.cachedPartials.Lock() - ns.cachedPartials.p[key] = p + // Double-check. + if p, ok = ns.cachedPartials.p[key]; ok { + return p, nil + } + p, err := ns.Include(name, context) + if err != nil { + return nil, err } - ns.cachedPartials.Unlock() - return + ns.cachedPartials.p[key] = p + + return p, nil } |