Scaling with Single Threading
August 9th, 2011
To scale applications, developers usually turn to multiple threads. This post discusses the use of single threading as an alternative.
Google Analytics makes tracking the metrics of a website easy by capturing the url of each page (gaTrackingOverview documentation). This works great for pages that have unique and meaningful urls, but when it comes to tracking pages that are included as part of a Grails web flow, tracking by the url becomes useless.
Grails uses a flow execution key to track the pages in each step of the flow, passing the key around as a parameter on the request. Within a Grails web flow, the url will look something like this http://hostName/appName/controllerName/flowName?execution=e1s2. The execution key isn’t reliable for tracking purposes, and would be meaningless to the person who will be looking at the Google Analytics report data.
One word of caution here, once you start tracking data from your website, you can never clear that data from your Google Analytics reports. So if you want to get this setup and test this without affecting up your production reports, start by reading Setting Up Google Analytics on localhost.
Once you have Google Analytics setup, your javascript will look something like this…
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxxx-x']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', 'true']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
Google Analytics tracks the pageview data using the trackPageview method ([\trackPageview documentation](http://code.google.com/apis/analytics/docs/gaJS/gaJSApiBasicConfiguration.html#gat.GATracker.trackPageview)). The _trackPageview method takes a url as an optional parameter. If you include a value for the url, Google Analytics will record this value as the url that shows up in your reports. Here’s an example of what the javascript would look like if you included an optional url…``To customize the url value for Grails web flow pages, you need to pass in the preferred url for each page in the flow. You could include the line of javascript code on every page in your flow, passing in a different url for each page. But this could be tedious and repetitive. I wanted a less invasive global solution, so I chose to write a Grails tag and include the tag in the
of the layout.gsp for our site.Here is the code for my tag…
class MyTagLib {
static namespace = "bc"
def googleAnalyticsWebflowUrl = { attrs, body ->
//Only include the custom url on pages in a web flow
if (request['flowExecutionKey']) {
ProgressData progressData = request['progressData']
def currentStep = progressData.currentStep()
def appName = grailsApplication.metadata['app.name']
out << "<script type='text/javascript'>_gaq.push(['_trackPageview', '${appName}/${controllerName}/${actionName}/${currentStep}']);</script>"
} else {
out << "<script type='text/javascript'>_gaq.push(['_trackPageview']);</script>"
}
}
}
To use the tag, here is the line of code I added to the
of the layout.gsp…<bc:googleAnalyticsWebflowUrl/>
This tag should be placed somewhere after the Google Analytics javascript that’s already been added to the site.
The code in my tag first checks to see if there’s a flowExecutionKey in the request. If there is a flowExecutionKey (meaning the page is part of a flow) the javascript added to the page will include the customized url value for Google Analytics to use to track the page. If the page is not part of a flow, the default javascript code is included on the page, and the url for the page is tracked normally by Google Analytics.
Quick notes about the attributes used in my tag code…
One last thing to note; since we’re adding the javascript to track page views via the tag, the line of code included in the original javascript should be removed, otherwise all the pages on the site will be tracked twice. Remove this line from the Google Analytics javascript…_gaq.push(['_trackPageview']);
Now the Google Analytics report looks much cleaner with the revised urls and it’s easier to analyze the data.
To scale applications, developers usually turn to multiple threads. This post discusses the use of single threading as an alternative.
With a fixed footer (using CSS position:fixed), you might make content invisible to your users. A workaround devolves into a discussion of the click event.
How to use the YUI3 global object instance and loader to help manage your custom modules and keep your code organized and optimized for reuse.
Insert bio here