Ben Gidley presented on how Tapestry was used to build the SeeSaw video on demand website. The initial site was built on Struts but later converted to Tapestry to better support reusable components with state and behavior. A prototype was first built to prove out Tapestry. The team was then trained on Tapestry and the site was gradually converted page by page. Customizations were also made, such as for caching, JavaScript combining, and Flash integration. In the end, Tapestry enabled reusability across the site and good performance under load.
1. Tapestry In Action
(for real)
Ben Gidley
Senior Technical Architect - ioko
2. Introductions….
• Presenter: Ben Gidley – Senior Technical Architect at
ioko
• ioko: A systems integrator specialising in the media
market. Responsible for Sky Player, 4OD, ITV Player and
bits of iPlayer
• SeeSaw: A Video on Demand (VOD) website build by
ioko. This has gone under a number of names including
‘Project Kangaroo’
3. Topics
• Some background about SeeSaw
• How and why we picked tapestry
• How we converted the site
• Some of our key customisations
• How we though it all worked out
5. A bit of history
Project Kangaroo started July 2007 as joint venture
between BBC, ITV and C4
The initial brief was to take the 4OD platform and share it
This didn’t last long! A new site built on the core ideas
from 4OD was required
Kangaroo started building the site on Struts 1, Spring and
Hibernate – the same technology stack as 4OD
7. The 1 st Framework Choice
• We considered Tapestry 5 at at the start of Kangaroo
but ruled it out as it was in early beta
• We considered Tapestry 4 and ruled it out as Tapestry
5 was coming and we didn’t want to have to convert.
• The plan at that time said we would launch by Jan 2008
(six months) so we picked Struts 1 as ioko had lots of
staff skilled in it
• We did design the site around a 3 tier model to let us
switch UI framework later
• We did expect we would want to take advantage of
better UI frameworks over time
9. Our Pain Point
• The Kangaroo project carried on into 2008 and the
timelines kept moving back (mainly due to business issues)
• Towards the end of the year the site was complete but
couldn’t be launched for at least 6 months due to being
investigated as a monopoly
• At this point we pitched changing the framework of the
UI to better support new features going forward
• We had been struggling to add more and more complex
AJAX behaviours to our struts/tiles based site
10. The big problem with
struts and tiles
The big problem for us was components with STATE and
BEHAVIOUR
We had lot of reusable modules (implemented as tiles) that
the CMS allowed to be moved around the site
This becomes very hard in struts as it doesn’t provide
infrastructure to support this (e.g. URL management,
state management)
13. The Solution
Tapestry has a coding model that allows
components with state and behaviour - both
client and server side
Components in web-sites are really powerful –
they let us build complex and re-usable
functionality
We did look at other frameworks such as JSF and
Wicket, but settled on Tapestry as we liked the
syntax and were convinced the performance
was good enough
14. Page
Class
TML
T5 Model
Each Page can contain N components
Class
Component
TML
Each Component can contain N components
16. The conversion challenge
Once we had decided to switch we had a huge challenge
• We had a large site (larger than the current
SeeSaw.com) that was tested and worked
• We didn’t want to start from scratch
• We still had to keep delivering new ‘business
functionality’
• We had a team of developers who mostly knew Struts
and Spring
17. The first POC
Our first step was to build a POC
• We needed a beta registration application and decided
to build it in T5
• This was a simple 3 dynamic page application that
gathered user details
• We used this to prove we could build a re-usable
component and get all the libraries we use integrated
• This application later was used in production
18. Converting the team
We had to teach our whole team tapestry we
kicked this off with a training course run by
Howard Lewis-Ship which got people up to
speed with the basics
We then started converting the application and
allowed people to learn ‘on the job’.
People on the team learnt the framework at
different speeds. We got those who got it
quicker to help those who took longer
There is definitely an ‘unlearning’ exercise for
those who are used to struts
19. Converting the site
The website code was originally structured as below
Spring
Hibernate
Struts and Business Business
SOLR
Tiles Facade Implementation
Quova
20. Converting the site
We changed our application to run Tapestry and Struts side
by side
Spring
Struts and Hibernate
Tiles Business Business
SOLR
Facade Implementation
T5 Pages
Quova
Tapestry IOC
21. Tapestry-ioc vs Spring
• We have got both Tapestry-ioc and Spring in the system
- why???
• They are both IOC containers, the both can wire beans
into pages
• Tapestry-ioc has a really neat XML less syntax and
supports combining modules in a way spring just doesn’t
• Spring has loads of helper libraries and is much most
commonly used
• So we use both
22. Converting the site
It is not difficult to run struts and tapestry in the same
application
Once we had this running we could
• Convert the site pages one at a time
• Use tapestry-spring to write our tapestry pages against
our existing spring beans
• Write new code in tapestry and tapestry-ioc
23. Extending the framework
Tapestry has a lot of feature out of the box but there were
a number of things we wanted it didn’t do so we started
to extend the framework.
The tapestry-ioc contribution and override methodology
makes extending the framework possible. It isn’t always
easy as it can be hard to find out what you need to
change!
24. Cache Control
Our site implements the Yahoo Performance Guidelines - so
we want to set cache headers on all pages.
We want to control this via an easy mechanism
We decided to implement this with Annotations in a library
To use it you just add
@CacheControl(cacheType =
CacheType.FAR_FUTURE) to your page
Or
cacheControlSupport.setCacheType
(CacheType.NONE);
To your AJAX event
25. Cache Control
To implement this in tapestry we
• Added a PageRenderRequestFilter to look up the
annotation
• Put the annotation value into a PerThread service
(CacheControlSupport)
• After render in MarkupRendererFilter read the
annotation and write the headers
The code for this is open source and at
tapestry.ioko.com
The hardest part of writing this was to find out where
to plug in the logic!
26. Caching
Our site heavily depends on caching to operate
under peak loads. We have multiple layers of
caching
EH Cache
Whole Page and Partial Page Materialised
AJAX Cache Cache Views
Zeus Tapestry Business Oracle
Hibernate
Objects
The partial page cache is a great example of a
custom tapestry component
27. Caching
The partial page cache listens to tapestry as it
renders areas of the page and stores the
generated HTML between requests keyed on a
configurable variable (so it can be user specific)
On subsequent calls it then short cuts the
rendering and returns the HTML string and
replays key API calls (e.g. to RenderSupport) to
allow the page to render
This can save substantially on the work required
to deliver a ‘personalised’ page.
28. Combination of JavaScript
and CSS
Tapestry supplies the @IncludeJavascript annotation to
allow javascripts to be included in a component
In 5.1 it assembles that javascript into a single ‘combined’
file per page.
This is a really nice mechanism for development but in
production has a number of issues
29. Combination of JavaScript
and CSS
In theory combining JS is a good idea
Prototype.js Tapestry.js Component1.js Component2.js
However if you have pages that differ by one or two
components you end up downloading several copies of
Prototype.js and Tapestry.js
Prototype.js Tapestry.js Component1.js Component3.js
30. Combination of JavaScript
and CSS
We decided to (reluctantly) abandon using
@IncludeJavascript.
Instead we have a Dispatcher that builds a single
Global.js and Global.css from all our component
javascript files.
This approach means users get all our javascript/css
in a single hit, but on second page render they
don’t need any more
We further improve the experience by compressing
the javascript/css (on the fly in development,
statically in production) with YUI Compressor
31. Combination of JavaScript
and CSS
This combination is really worth it – this site is quite
JavaScript heavy
- Compressing the JavaScript knocks 7 seconds off
the page render time
- Combining the JavaScript knocks 3 seconds off the
page render time
The downside is we now have to declare our
Javascript/CSS.
There is work in progress to fix this issue in
Tapestry 5.2 – though the solution is still being
debated.
32. Flash Integration
Our site uses a lot of flash and we wanted to be able to
feed it data via AJAX after page load
This is really easy in Tapestry – you create an event handler
on the component/page, call it direct from flash and
return JSON
There is a small component that ‘helps’ with this open
sourced at tapestry.ioko.com
The component includes the swfobject library to make it
easy to embed flash into your page
33. Performance
Tapestry claims to have excellent performance however
there was a shortage of evidence for this claim.
Our experience is that it performs well under load and
doesn’t have any resource leaks
To back this up I published a series of articles on my
blog of an ‘abstract’ load test - http://
blog.gidley.co.uk/2009/05/tapestry-load-testing-
round-up.html
Our load testing for SeeSaw (which was much more
through but confidential) shows a similar
performance profile.
34. The Good Points
• Components - allows re-use across the site
• Templates are HTML makes it very easy for our web
developers to work with them
• Default components are easy to use
• Excellent Exception Reporting - it tells you what went
wrong and where!
35.
36. The Bad Points
• Learning Curve
• Documentation – A common theme is although there is
reference documentation it is often hard to find what you
are after. A lot of people say they would like a good book
on it. That said the (shameless plug) Tapestry training
materials do fill the gap nicely.
• Choice of prototype - our web devs would much prefer
to use JQuery and we are stuck with prototype
• IF constructs in TML are not very smart so we often end
up using blocks to workaround
37. Was it worth it?
• Overall I think it was (but I would say that!)
• The site has ended up looking nice, performing well
and the components are paying back dividends
• The team once they learnt tapestry are able to work it.
We do have issues still teaching new people tapestry
• Our big challenges are now around making more use
of the framework to deliver all the new and exciting
features for SeeSaw
38. The end results
To help make it a bit more real lets look at SeeSaw.com
and see if we can spot ‘Tapestry In Action’!
39. Further Resources
• Training via Skillsmatter
• Tapestry Load Tests http://blog.gidley.co.uk/2009/05/
tapestry-load-testing-round-up.html
• The Tapestry site http://tapestry.apache.org/
• ioko Tapestry Commons – http://tapestry.ioko.com/
• The tapestry mailing list archive http://
tapestry.markmail.org/
• Yahoo Performance Rules - http://developer.yahoo.com/
performance/
41. Acknowledgements
• Thanks to the Tapestry 5 developers
• Thanks to Skillsmatter for hosting this talk
• Some images and examples produced by Howard
Lewis-Ship for his CodeMesh talk
• Some code examples are from ioko-tapestry-commons
- tapestry.ioko.com
• Thanks to all at SeeSaw.com for allowing us to talk
about how this was built