Open pvgoran opened 5 years ago
Here is my use case: I keep a single, shared ConcurrentMapTemplateCache
instance to cache the templates, and a factory method that creates a Handlebars
object and configures it to use that single cache instance.
When I need to compile and apply a template, I call the factory method to acquire a new Handlebars
object, configure it with a MissingValueResolver
and some helpers, then compile and apply the template. MissingValueResolver
and the helpers may be different for different template invocations (even if the template text is the same), which triggers the problem.
The cache system for templates, as it's implemented now, is subtly broken with certain use cases, when a cache object is shared between different
Handlebars
objects.Specifically, a cache can remember a
Template
compiled by aHandlebars
object with settings A (which includes at least helpers,MissingValueResolver
, andEscapingStrategy
), and then return it from acompile
/compileInline
call for aHandlebars
object with settings B. In this situation, the caller expects the template to work according to settings B, but it will work according to settings A because a previously compiled, cached version is returned.This problem can be triggered even without sharing a cache object between different
Handlebars
objects: just compile a template, change theHandlebars
settings, and compile the same template again.The good way of resolving this problem would be to make the caches take into account
Handlebars
settings when looking up the cachedTemplate
, and only deliver the cachedTemplate
when the applicable settings are the same (MissingValueResolver
is the same,EscapingStrategy
is the same, the set of helpers is the same, probablyTemplateSource
is the same, and maybe some other settings too).The simple way of resolving this problem would be to disallow sharing of cache objects between different
Handlebars
objects, bind a cache object to aHandlebars
object, and invalidate the cache whenever applicable settings of theHandlebars
object are changed.