Clone properties of `Tera`
I'm using Tera with actix-web, which creates a separate app state (including a Tera instance in my case) per thread. I was originally doing something like this:
// Compile the templates only once
let tera = Tera::new(...)?;
HttpServer::new(move || {
App::new()
.data(tera.clone()) // Cloning a `Tera` here
})
I looked into the struct Tera and realized that I'm actually cloning a bunch of stuff (such as HashMaps and Vecs), so I decided to do this instead:
let tera = Arc::new(Tera::new(...)?);
HttpServer::new(move || {
App::new()
.app_data(Data::from(Arc::clone(&tera))) // Cloning an `Arc<Tera>` here
})
But then I noticed that there are already Arcs inside Tera, which I think is wasteful in this case. I could be totally wrong and maybe Tera is designed this way for a reason, but I think it'd be more flexible if we replace the Arcs inside Tera with Rcs. This will have several consequences:
- The
Test,FilterandFunctiontraits will no longer need to beSend. This should be a backwards-compatible change. - The
Terastruct will no longer beSend. We need to wrap it in anArcif we want to send it between threads.
This change will bring the following benefits:
- Less overhead when using
Terafrom multiple threads (which I suppose all server frameworks require) since we don't have doubleArcs anymore. - Less overhead when using
Terafrom a single thread since we don't needArcat all.
The only downside I can think of is that making Tera not Send is a breaking change. I'd like to hear your opinions.
Another way to do this while keeping backwards compatibility is:
- Replace the
Arcs insideTerawithRcs - Move whatever is inside
Teranow to aTeraInnerandArc-wrap it insideTera:
struct Tera {
inner: Arc<TeraInner>,
}
struct TeraInner {
/* a bunch of stuff */
}
However, I still think externalizing the Arc is the most flexible approach.
I do want tests/filters/functions to be Send though. Would https://github.com/getzola/zola/blob/master/components/templates/src/global_fns/mod.rs (+ rayon) still work without too much overhead?
Would https://github.com/getzola/zola/blob/master/components/templates/src/global_fns/mod.rs (+ rayon) still work without too much overhead?
I'm not sure I follow...?