CloudyKit / jet

Jet template engine
Apache License 2.0
1.24k stars 103 forks source link

Add time-based template caching capability #179

Closed jiwandono closed 3 years ago

jiwandono commented 3 years ago

The use case: I want to be able to replace the templates on-the-fly but with reasonable termplate rendering performance. I know that there is 'development mode' flag already, but obviously I'm not going to use this on high-traffic production environment.

Proposal: Introduce time-based caching. With this I can have both high-performance rendering performance and the ability to replace the templates on-the-fly. The cache item expiration time should be configurable.

I have some ideas already on the implementation, but I'd like to hear your feedback first on the idea.

marcelloh commented 3 years ago

I've done this with a part of my own library, which is actually a wrapper around: github.com/ReneKroon/ttlcache With this, you can use caches that automatically expire (and of course, use it for a lot more than just templates)

jiwandono commented 3 years ago

Sure! To clarify, this proposal is not for caching the rendering result but instead the template parsing result.

Dynom commented 3 years ago

Instead of introducing a TTL, how about a mechanic that allows you to override an existing template. This way you can perform dirty checks and decide if a template should indeed be expired on not. Using a TTL might lack some fine-grained control.

Instead what could happen is:

This way Jet only needs to expose a mechanism to re-define a template, and users of Jet have all the freedom to determine what templates are in need of a fresh version.

sauerbraten commented 3 years ago

I added a new in-memory Loader in #182 which acts like a cache outside of the Set type, and I believe you can achieve what you want by writing a custom Loader type that keeps track of either a TTL or a per-template dirty flag and then redirects calls to Exists() and Open() to either an InMemLoader or an OSFileSystemLoader. (Or you could react to "pushed" from outside and re-load the template from file and set in in the InMemLoader proactively, without waiting for Jet to request it.) You would activate development mode on the Set in this case to prevent Jet from caching anything, so you have full control over caching behavior.

The new Loader still needs doc comments and isn't released yet, but you can try it out by requesting github.com/CloudyKit/jet/v5 master in your go.mod if you want. Let me know if this is an okay solution for you!

sauerbraten commented 3 years ago

Oh, I just realized that any Loader can of course not cache parsed templates, so this will not be very performant. Let me think about this some more.

sauerbraten commented 3 years ago

I added a Cache interface in #183 if you want to take a look at this. Would the ability to set your own custom cache solve your problem?