Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Monday, August 09, 2010

Tapestry 5.2 leaves the gate

It's been a long time coming. Originally, I had thought we'd be producing Tapestry 5.2 six to eight months after Tapestry 5.1 ... instead, it's been more like 14 months just to get to the alpha release. Why? Well, in that time, I've personally changed jobs (back to an independent consultant), and I've been actively using the nightly snapshots of Tapestry 5.2 in two different projects for two different clients. I've had a lot of chances to see Tapestry in practice and, as always, identify the rough edges and smooth them out.

This new release enhances one of Tapestry secret strengths: meta-programming. It is now ridiculously easy to extend the behavior of components, or method or fields within components, using annotations .... without getting mixed up in all that Javassist business. I'm using that now just about everywhere you might think about using a base class: everything from securing page access, to caching, to integration with Google Analytics.

The big change here is the switch from pooled pages to singletons: In Tapestry 5.1 and earlier, Tapestry kept a pool for page instances. On each request, a localized page instance was pulled from the pool, used exclusively by the one request thread, then returned to the pool. The pool had to be able to expand dynamically, and shrink to release memory.

Starting with Tapestry 5.2, the page pool is deprecated (and only enabled with extra configuration). Instead, a single page instance is created and shared between threads. That may raise your red alert flag ... doesn't that make Tapestry non-thread-safe?

Nope. Tapestry now reworks your simple POJO classes, changing access to all local mutable fields to instead store the value in a per-thread Map. It's an extrapolation of how Tapestry already managed persistent fields (storing the persistent field values in the Session between requests) ... but it now applies to all request-scoped state.

It's an interesting trade off: a lot less memory (just a single instance of each page and all its components) for a bit more work during each request. Part of the reason for this alpha release is to get this code into more hands and get more performance analysis on the result. I'm confident that these changes will not noticeably affect small applications and reasonable request loads but will make a big difference in handling larger applications with heavy request loads.

Meanwhile, the goal is to keep the APIs stable, address a bunch of bugs, and get another release out soon, then vote that up as a beta release. Preferably before JavaOne!

1 comment:

semanticC said...

To my mind this is an example of one of the great benefits of Tapestry compared to Spring, as I become more familiar with Spring. Spring offers many different ways of achieving goals, it therefor hints and guides less. The choices must depend on the integration task to hand. There will be a negotiation between skills, preferences and demands of the task. Flexibility here is good. But building an application - pretty well any application I think, not just the very client side focused ones that Tapestry excels in, really needs many hints and guides, if you don't want to create long lists of essential features yourself. Here one needs knowledge and consistency, a clear voice. This is what Tapestry has with Howard and the T community.
Howard has just introduced a fundamental change to how Tapestry solves the problem of the balance between memory usage and processing speed in a high usage site.
I may be quite wrong, but my understanding is that to do this sort of architectural change in Spring (MVC) would be very difficult. And to have that solution tested and adopted who knows how much more so?
Howard, thank you.