CAS, Grails, and custom attributes

Recently my buddy Juan and I have been helping a client customize Jasig CAS, to provide single sign-on and identity management for various client systems that are written in Grails, Java, Ruby and PHP. I’m new to the CAS, so it took a while to piece together what’s possible and what isn’t. I relied pretty heavily on this post by Daniel Bower (thanks Daniel!) as well as some code that was in his Grails plugin. We didn’t actually use the plugin itself because it’s not official yet, and it was easy to just borrow some tips from the plugin source.

If you’re not interested in CAS, Grails, Spring Security, and passing custom attributes then I advise you to stop reading now!

Continue reading »

Whatever happened to static typing?

When I actually sit down to work on Loadster, I’ve noticed the work goes extremely fast compared with a lot of other projects I have built. There are a few obvious advantages: clean, pristine code base; well-defined scope; one person handling the roadmap and development. It’s pretty much the most efficient I have ever been.

But there’s another important advantage that I have noticed lately: everything is written in plain old Java code.

Continue reading »

Review of cloud-based load testing services

Just thought I’d explore some of the cloud-based load testing services out there. This is mostly for my own benefit, to see what impact if any it will have on Loadster’s market share, but I thought it might be of general interest so I am sharing my findings. Since Loadster is a client-side app, I don’t view these cloud offerings as direct competitors, but still… take my reviews with a grain of salt if you want.

There are 3 main services for cloud-based load testing that I am aware of: LoadStorm, LoadImpact, and BrowserMob.

Continue reading »

Some thoughts on cloud-based load testing

I’m finally jumping back into Loadster after a long, busy hiatus working on some other big projects. The market for load testing tools has changed a bit lately, but not as much as I expected.

The biggest change I noticed is (no surprise here) a big push to The Cloud. Unless you’ve been living under a rock, of course, you’ve noticed that everybody and their former roommate is making their apps run on the cloud.

There are some fairly compelling reasons for this. Treating hardware, bandwidth, and processing power in general as a commodity has some huge advantages for any company that wants to focus on core competencies. And there are economies of scale to be had by paying a big cloud provider such as Amazon or Microsoft to handle everything, and pay only for what you use.

As far as load testing is concerned, the cloud is appealing because it represents a cheap way to scale up simulated users as high as you want. One of the big barriers to entry of load testing (besides the shockingly high cost of licensing the software itself) is infrastructure. If you’re going to simulate 10,000 or so users hitting your production-like test servers, you need a decent amount of hardware and network throughput at your disposal to do so. Solutions like LoadStorm and BrowserMob seem to be gathering a lot of steam in this area.

There are a couple notable disadvantages to cloud-based load testing services, though:

  • They tend to be weaker on the scripting/recording features than the client-side tools. Sure, HTTP load testing just boils down to a bunch of GET and POST requests anyway, but for testing complex transactional systems it’s helpful to record realistic user flows, rather than just sending the same few requests over and over. If you are actually meticulous enough to hand-code each GET and POST request for a cloud-based tool, then more power to you.
  • The cloud can only generate traffic on sites that are publicly accessible. This is great for load testing your new WordPress blog or whatever, but most companies that are making serious web apps develop and test them in-house. It’s not realistic to put your new application in production before running load tests, and having a shadow production environment for this purpose (while ideal) can sometimes get expensive.

Finding the bottleneck

A question that often comes up is: Once I determine my site has a performance problem, how do I know what to fix? Since there are dozens of potential bottlenecks, how should I best decide where to spend my time?

I was reminded of this when I came across this post on performance tuning of SQL queries by Sam Saffron at Stack Overflow.

Sam talks in a lot of detail about the tools, queries, and specific optimizations he used to achieve a 10x improvement in baseline performance for some of their pages. That was useful, but not as interesting to me as his general methodology.

First of all, they were logging each query’s execution time through their own database connection class. So from the very beginning it was really easy to see how much of the page’s total load time was spent in database queries vs all the other factors (processing data, rendering, network latency, etc). Turns out in their case, as with many applications, the database access was the biggest chunk.

Once he realized this, he didn’t immediately start tweaking SQL. He looked at a month’s worth of production logs to see the impact in aggregate. Since this was one page in the system, it made sense to see the total impact over a period of time, to avoid wasting his time on a single page if there are bigger fish to fry.

Turns out over the course of 1 month, that slow page really did have a signifiant impact on site averages. So he proceeded to tune it. As an added bonus, some of the improvements he made had positive ripples through the rest of the application.

So, a couple little morals of the story:

  1. Measure everything! Track performance for all the key layers of your application, as well as total response times.
  2. Do a little cost-benefit analysis in your head before diving down rabbit holes. Before tweaking things, first determine where your time is best spent. Attack the worst bottlenecks first.

Of course, baseline performance is one thing but performance often changes unpredictably under heavy load. Most bottlenecks are non-linear. Something might do just fine for a while, and suddenly become exponentially slower once a certain load threshold is reached.

SWT drop shadow effect

Loadster uses SWT for its user interface. Mostly we’ve been really happy with it — while it’s not as slick as some of the newer non-Java frameworks like Adobe AIR, we’ve been able to do quite a bit with it and not much effort. It feels a lot more “native” and less clunky than other Java UI toolkits (*cough* Swing *cough*).

For our fancy new graphical script editor (coming soon) I was doing a custom drop shadow effect. Here’s what it boiled down to:


public static void fillRoundRectangleDropShadow(GC gc, Rectangle bounds, int xOffset, int yOffset, int radius) {
	gc.setAdvanced(true);
	gc.setAntialias(SWT.ON);
	gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
	gc.setAlpha(0x8f / radius);

	for (int i = 0; i < radius; i++) {
		Rectangle shadowBounds = new Rectangle(bounds.x + xOffset, bounds.y + yOffset, bounds.width - i, bounds.height - i);

		gc.fillRoundRectangle(shadowBounds.x, shadowBounds.y, shadowBounds.width, shadowBounds.height, radius, radius);
	}

	gc.setAlpha(0xff);
}

We could certainly get a lot fancier with the options; I use an arbitrary 0x8f for the shadow alpha because that looks good where we are using it. But you could parameterize that as "intensity" or something.

Querying for result in a map (Grails/Hibernate/HQL)

We use Grails for a lot of web stuff (not related to the Loadster tool itself), and sometimes we end up with rather funky collection types on our Hibernate entities.

In this case, we had a domain class called “Task” with a Map collection called “attributes”. The idea is to be able to shove rather unstructured metadata into that map, without polluting the domain class itself with a lot of extra fields that are seldom used.

Today I had to query for all tasks with a certain key in their “attributes” map, and was pleasantly surprised at how easy it is:

return Task.findAll(
    "from Task t where t.attributes['resident'] = :c",
    [c: resident.id]
)

No doubt you could do the same with the Criteria API. Another win for Grails/Hibernate!

Here we go! Announcing Loadster 1.1.1

Just got done releasing Loadster 1.1.1, which is the first version intended for really wide distribution. While we still have a list a mile long, this version is already a full-featured load testing tool by the usual standards: HTTP scripting, parameterized data, scenarios with multiple populations and schedules for ramping up/down, automated reports, etc.

But the next few months are going to be really exciting — a new visual approach to test scripting, really big load engines, monitors, and a couple other surprises. All these will be in the Loadster 1.x branch, so customers who purchase 1.1 will get the future updates for free.

Now comes the big publicity game: targeted ads, social media, blah blah blah. Not as fun as actually building software, but a necessary evil. :)