[Geoserver-devel] Replace custom template loader with custom configuration (freemarker)

Hi,
today I had a serious look at freemarker and the template
loading subsystem.

Overall it's very nice, but I found something that may cause
either performance or functionality issues.

At the moment we have a GeoserverTemplateLoader, that can be
configured with a class and a feature type name to alter they
way it'll look for a template file. The freemarker configuration
is handled as a static object in the KML writer, and its configured
with a different template loader instance each time.

Now, I don't know exactly how the freemarker internals do work,
but when we repeatedly call:

templateConfig.setTemplateLoader(templateLoader);
template = templateConfig.getTemplate("kmlDescription.ftl");

I gues we either:
* make the config throw away its template cache, which is bad from
a performance point of view. Template parsing is expensive, we don't want to do that for each call.
* if the templateconfig does not wipe out its internal cache, make the config return a cached version which may not be the one we're looking
for (maybe it has cached the generic template and now we need a feature type specific one).

I may be wrong, since I haven't checked the freemarker sources,
but in my opinion we should create a Configuration subclass that exposes a getTemplate(class, typeName, templatePath) method, and use that to locate the template and do "the right thing" when it comes to cache stuff. It would also allow to have a Geoserver global cache, which may
be useful if there are lots of templates (again, I don't know how this
works in the freemarker internal, but it may be that their cache is
made with hard references and based on a LRU, size limited, list).

Comments?
Cheers
Andrea

Hi Andrea,

The cache is stored with the Configuration, not with the TemplateLoader
so I think we are ok on that one. The issue about hitting the cached
"generic" version of the template when a featureType specific one has
been added is legitimate though, never thought about that case.

Lucky for us the caching implementations in freemarker are pluggable
with a hard, soft, and mru implementation to choose from, with the
default being mru.

I think we could solve this problem by writing a decorating cache that
wrap up another caching implementation but recognize the case above.

-Justin

Andrea Aime wrote:

Hi,
today I had a serious look at freemarker and the template
loading subsystem.

Overall it's very nice, but I found something that may cause
either performance or functionality issues.

At the moment we have a GeoserverTemplateLoader, that can be
configured with a class and a feature type name to alter they
way it'll look for a template file. The freemarker configuration
is handled as a static object in the KML writer, and its configured
with a different template loader instance each time.

Now, I don't know exactly how the freemarker internals do work,
but when we repeatedly call:

templateConfig.setTemplateLoader(templateLoader);
template = templateConfig.getTemplate("kmlDescription.ftl");

I gues we either:
* make the config throw away its template cache, which is bad from
a performance point of view. Template parsing is expensive, we don't
want to do that for each call.
* if the templateconfig does not wipe out its internal cache, make the
config return a cached version which may not be the one we're looking
for (maybe it has cached the generic template and now we need a feature
type specific one).

I may be wrong, since I haven't checked the freemarker sources,
but in my opinion we should create a Configuration subclass that exposes
a getTemplate(class, typeName, templatePath) method, and use that to
locate the template and do "the right thing" when it comes to cache
stuff. It would also allow to have a Geoserver global cache, which may
be useful if there are lots of templates (again, I don't know how this
works in the freemarker internal, but it may be that their cache is
made with hard references and based on a LRU, size limited, list).

Comments?
Cheers
Andrea

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Geoserver-devel mailing list
Geoserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel

--
Justin Deoliveira
The Open Planning Project
jdeolive@anonymised.com

Justin Deoliveira ha scritto:

Hi Andrea,

The cache is stored with the Configuration, not with the TemplateLoader
so I think we are ok on that one. The issue about hitting the cached
"generic" version of the template when a featureType specific one has
been added is legitimate though, never thought about that case.

Lucky for us the caching implementations in freemarker are pluggable
with a hard, soft, and mru implementation to choose from, with the
default being mru.

I think we could solve this problem by writing a decorating cache that
wrap up another caching implementation but recognize the case above.

Hmmm... Configuration does not know about the feature type, and the
cache is fed with keys that look like:

new TemplateKey(name, locale, encoding, parse);

I don't see how we can put the feature type in the mix... maybe we
could abuse the template name and encode it somehow, for example
by having a name looking like a http get request:
featureType=xxx&path=yyy

That could be hidden behind an utility class, to shield users from
this mess.

Cheers
Andrea