Jinja: imported templates are being cached for too long

Created on 16 Jul 2013  ·  4Comments  ·  Source: pallets/jinja

I have a template called main.html. It {% imports %} a module called module_a (without context). module_a {% imports %} module_b in the same way.

When I change module_a, the template loader recognizes this and reloads it.

When I change module_b, the template loader does not recognize it. I have to restart the process.

I believe this is due to the fact that the generated code for module_a does the imports in its root() function. get_template sees that module_a is up to date, so does not reload it, so does not rerun its root() function.

I'm not sure how to address this. Obviously calling root() on each call to get_template is bad. The fullest solution would be to keep track of each template's dependencies, but that's a lot of work.

Most helpful comment

The problem is that imports are cached but not tracked. I'm not sure sure what the best way to deal with this would be.

All 4 comments

We're running into this as well. (I almost didn't find this bug because you didn't use the term auto_reload -- this is only relevant when auto_reload=True).

It looks like this would be quite tricky to fix; ideally you'd want the uptodate method returned from get_source to check not only the source file itself, but also any source file it imports, extends, or includes. But at the point when uptodate is defined, all you have is the raw un-parsed source, so that information isn't available.

It might be implementable at a higher level (e.g. in Template.is_up_to_date) but that seems like it would also require significant surgery to get the dependency info back from the compiler.

I just ran into this as well. This is pretty annoying in development because it means that I have to set cache_size to 0, and then things get very slow (as one could expect).

I'll try to dig in the internals to see if I come up with something. In the meantime, if someone with more experience could suggest with a solution or even some direction that would be really great!

The problem is that imports are cached but not tracked. I'm not sure sure what the best way to deal with this would be.

Ok, so the problem here isn't with the caching of the template but the caching of variables passed into the imported macros.
(at least in my case)

My workaround was to use a method that returns my updated context values to be rendered.

In my scenario I was making a macro for pagination. The macro needed the request object.

initial approach within the macro
{% set pagenum, limit = request.args.pg , request.args.limit %}
This will work initially, but on subsequent requests the macro context values are forever cached unless a server reboots

working approach within the macro
{% set pagenum, limit = request.get_params() %}
This will now return my updated request parameters on every call without sacrificing the caching of my macros.

I also noticed that caching the macros has an ~2.5 x speed up in my response times.
Without caching ~= 450ms
With caching ~= 150ms

Was this page helpful?
0 / 5 - 0 ratings