This article is the second one in my article series about fast loading web pages. The first article dealt with the Django Framework while this one is about Grails which I have recently elected as my preferred rapid web application framework. Ever since I switched from Django to Grails there was one issue that bothered me and that was the loss of the ability to serve complete pre-rendered pages from a distributed cache to the enduser while bypassing the application server.
The solution described in this article is in use on the production servers powering mmogle.com where it ensures page response times below 100ms for cached content.
Let me summarize the concept for readers not familiar with my first article: The goal we want to achieve is to greatly decrease the load on the application server (container) by storing the raw HTML output of rendered pages in a (distributed-) cache to be picked up by a Frontend Web Server without even bothering the application server behind it for the current request. Since we would need stuff like Edge Side Includes (ESI) for dealing with personalized pages, we are going limit ourselves to anonymous users.
[More]
Did you ever had to implement a menu in Grails GSP where every link element should be seperated from its predecessor by a separator character and where some of the elements can be missing when certain conditions are not met (security etc)?
The part with the optional elements can turn the separator handling into a real mess. So today I decided to end this nonsense. The result is a tiny taglib which can be integrated into every grails project. The usage is pretty self explanatory:
<mx:toolbar separator=’|'>
<mx:item>
<shiro:hasPermission permission=”topic:delete”>
<g:link controller=”topic” action=”delete” id=”${topic.id}”><g:message code=”topic.delete”></g:message></g:link>
</shiro:hasPermission>
</mx:item>
<mx:item>
<shiro:hasPermission permission=”topic:lock”>
<g:link controller=”topic” action=”lock” id=”${topic.id}”><g:message code=”topic.lock”></g:message></g:link>
</shiro:hasPermission>
</mx:item>
</mx:toolbar>
[More]
The other day I was writing a medium complex HQL query for a Grails App and no matter what the line executing the query would crash like this:
java.lang.NullPointerException
at $Proxy13.createQuery(Unknown Source)
at com.acme.PerformanceService.makePerformanceSheet(PerformanceService.groovy:38)
... |
So how the hell do we figure out what the problem given so few information? Turns out that grails sanitizes the exception stacktrace, resulting in better readability by removing a lot of clutter. Sometimes though this optimization will also hide some important details from you. Luckily we can still refer to stacktrace.log which usually resides in the project root folder in development mode. In this particular case opening the file reveiled this:
java.lang.NullPointerException
at org.hibernate.dialect.Dialect$3.getReturnType(Dialect.java:125)
at org.hibernate.hql.ast.util.SessionFactoryHelper.findFunctionReturnType(SessionFactoryHelper.java:405)
at org.hibernate.hql.ast.tree.AggregateNode.getDataType(AggregateNode.java:44)
at org.hibernate.hql.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:165)
at org.hibernate.hql.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:727)
at org.hibernate.hql.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:551)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:645)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:281)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:229)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:251)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:134)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:94)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
... |
Which almost instantly gave me the hint that something’s wrong with the aggregate part of my query:
org.hibernate.hql.ast.tree.AggregateNode.getDataType |
And indeed the problem was that I had ported an SQL Query to HQL and forgot to rename the sum() aggregate argument from the column name to the domain class property name:
sum(some_property) instead of sum(foo.someProperty)
I’m a big fan of using memcached for improving the scalability of websites so when I recently fell in love with the Grails Framework I began to look for a way to configure the memcached client which blends in with the framework. Luckily Grails provides a very easy way to configure Spring Beans using a DSL Just create grails-app/conf/spring/resources.groovy and add this:
beans =
{
memcachedClient(MemcachedClient,
net.spy.memcached.AddrUtil.getAddresses(
ConfigurationHolder.config.memcached_servers))
{ bean ->
bean.scope = 'singleton'
}
} |
Voila, from now on you can get a memcached client instance anywhere in your application either by standard dependency injection or by calling applicationContext.getBean(’memcachedClient’).
It is important to note that this example assumes that you have configured your memcached server(s) in grails-app/conf/Config.groovy like this:
environments
{
development
{
memcached_servers = "192.168.230.2:11211"
}
production
{
memcached_servers = "localhost:11211"
}
} |
Every Web Application Project I’ve been involved in the recent past had one thing in common: the client demanded more and more rich-client features at an ever increasing pace – without committing itself to real rich-client frameworks such as Flex or Silverlight. This leaves us with Javascript / AJAX for implementing highly dynamic User Interfaces for Web Applications. A very common problem when working with Ajax is the requirement to update multiple parts of a page in response to a single request. This post aims to familiarize the reader with my own approach to this problem.
At its core my solution consists of just two functions – one running server side and the other executing on the client. The first function is intended to run on the server and is written in Groovy. It was originally written in Python for use with the Django framework and I’ve ported it to Groovy when I switched to Grails as my primary RAD Web framework. This function takes a map as argument and returns a JSON encoded map where the key is a valid jQuery Selector designating the targets for the update and the value is a map containing information how the matched elements should be modified and how the content for the update shall be produced. Don’t worry if you find this confusing at first. There’s a sample further down.
[More]
I’ve been doing a serious amount of Grails Development lately and if there’s one Grails Plugin I consider mandatory for any serious production deployment then it is the UI-Performance plugin by Burt Beckwith. One of the features of the plugin that reduces server load is versioning and far-future “Expires” and “Cache-Control” headers for static resources.
Each time you generate a new WAR for deployment, a new version is applied to all image, .js, and .css files so files can be cached forever. The next time you deploy a new version of your application, all of the resource file names will have changed, so only then will files be requested. The default process for determining the version is to look at the version of the root project folder in the Subversion metadata files. Since I’ve switched to GIT for all my projects a while ago the plugin would fallback to “System.currentTimeMillis().toString()” to compute the version.
My solution is to include the following line in my projects Config.groovy:
uiperformance.determineVersion = { -> "git rev-list --max-count=1 HEAD".execute().text.trim() } |
This allows the HEAD commit SHA1 hash of the current branch to be used as the uiperformance version for deployment.
This is one of the very rare occasions where Microsoft actually did something cool. A couple days ago I needed to test one of my web apps with Internet Explorer 8 and just for giggles with IE6 – although we’ve dropped support for that dinosaur a while ago. Remembering my previous experience with IE8 and my inability to go back to 7 all too well – yes don’t laugh at me, I should have known better I know – I was preparing to fire up VMWare and create two XP Images, one for each browser version. But imagine my surprise when I discovered that Microsoft actually offers pre-configured ready to launch Windows XP VirtualPC Images for every possible IE version for free.
Be advised that these images expire in a couple of months but Microsoft seems to make new images available shortly before the old ones expire.
Here’s the link: http://www.microsoft.com/downloads/details.aspx?FamilyID=7c2b5317-a40f-4e86-8835-d37170c5923e&displaylang=en
I admit it – I’m a performance junkie. I can’t stand code that just works but performs poorly. Being said, I recently fell in love with Django (a fantastic Python powered web application framework). In one of my current projects – xarmory.com – the number of requests for static resources issued during page load began to bother me. The project makes intensive use of jQuery and it’s my personal belief that Django + jQuery is a match made in heaven. When working with jQuery you will find yourself often in the situation to rely in cool little jQuery plugins – each distributed as a seperate javascript file of course. When a project grows, those files begin to add up. In the case of xarmory.com we now had eleven javascript references in the header section of the page. Although the individual files are were only 3-11k in Size, the request overhead for all those tiny files became unacceptably in my eyes.
To alleviate the problem I decided to resort to a simple solution and just merge the individual script files into a single file. A pretty common practice. Before reinventing the wheel I surfed the net for existing solutions and found two which I gave a shot. Short story, both solutions had their share of problems mostly stemming from the fact that they wanted to do it all and integrate their own Javascript Minifier in addition to the merging. During my short evaluation both Minifiers choked on fifty percent of my javascript files, even on the official jquery 1.2.6 script. A bit frustrated I decided to roll out my own Django Template Tag based on this code.
[More]
Inspired by this article I decided to find out if the same technique can be exploited in my current project which is developed in django.
My first problem was to come up with a viable cache key scheme since simply using the full request URI as suggested in the article wouldn’t work for me because my site renders a different version of a navigation menu depending on the authentication state of current the user. After weighing in the advantages and disadvantages between the super clean variant of factoring the session cookie and all other cookies into the memcached key and a less heavy weight method that would only append a server supplied abstract “page version” field to the request URI, I went for the latter. My resulting nginx virtual host config was looking like this:
[More]
About a year ago I’ve switched over to IntelliJ as my primary Java IDE. When I began to dabble a bit in Django a few days ago, I realized that IntelliJ had me spoiled when it comes to Editor Features – especially when working with Javascript and HTML files. Notepad++ – although a great text editor on its own right – simply didn’t cut it for me for web development.
When I tried opening my Django files in IntelliJ I had to realize that IntelliJ needs a project context for opening a file. Even for a simple html file. Fortunately the solution was pretty straight forward. Navigate to your Django project root directory and create a new file .project. Some of you have guessed it: we are pretending to be Eclipse. Open the file in a text editor and paste the following snipped into it:
<?xml version=”1.0″ encoding=”UTF-8″?>
<projectDescription>
<name>myproject</name>
<comment></comment>
<projects></projects>
</projectDescription>
Edit the <name> tag value and change it to your liking.
[More]