<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Grinding Gears</title>
	<atom:link href="http://engineering.freeagent.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://engineering.freeagent.com</link>
	<description>Tales of code crunching from the FreeAgent Engineering team</description>
	<lastBuildDate>Mon, 30 Apr 2012 23:57:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Conference Pairs</title>
		<link>http://engineering.freeagent.com/2012/04/30/conference-pairs/</link>
		<comments>http://engineering.freeagent.com/2012/04/30/conference-pairs/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 22:04:33 +0000</pubDate>
		<dc:creator>Olly</dc:creator>
				<category><![CDATA[Conferences]]></category>

		<guid isPermaLink="false">http://engineering.freeagent.com/?p=379</guid>
		<description><![CDATA[At FreeAgent we strive to create the best working environment we can for our Engineering team. A happy employee is a productive employee and, as an engineer myself, I understand that there&#8217;s little that makes us happier than fast interwebs, &#8230; <a href="http://engineering.freeagent.com/2012/04/30/conference-pairs/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>At FreeAgent we strive to create the best working environment we can for our Engineering team.  </p>
<p><img alt="" src="http://freeagent-engineering-blog.s3.amazonaws.com/engineering-office.jpg" title="Engineering &#039;Dev Pit&#039;" class="aligncenter" width="600" height="300" /></p>
<p>A happy employee is a productive employee and, as an engineer myself, I understand that there&#8217;s little that makes us happier than fast interwebs, great coffee (or tea, served from a teapot, naturally), free beer (or <a href="http://www.irn-bru.co.uk/">Irn Bru</a>), shiny new toys and an endless supply of challenging code to craft.  This is why we use <a href="http://ruby-lang.org">Ruby</a>, buy <a href="http://www.hermanmiller.com/products/seating/work-chairs/aeron-chairs.html">Herman Miller chairs</a>, top-of-the-line <a href="http://www.apple.com/imac/performance.html">Apple</a> <a href="http://www.apple.com/uk/macbookair/performance.html">gear</a> and have ended up with an amazing office full of brilliant people.</p>
<p>In the &#8216;enterprise world&#8217; it&#8217;s called Investing in People, but it&#8217;s full name is actually Investing in Shiny Stuff for Nice People™.</p>
<p>Which leads me onto the subject of conferences.  </p>
<p>Today&#8217;s tech conferences are fun, sociable, held in hip cities across the globe and have genuinely useful content presented by engaging, inspiring people.  This is especially true for the Ruby community, which has a wealth of conferences to choose from.  It&#8217;s very hard to attend one of these conferences and not come back inspired by your craft and the people involved in the community.  </p>
<p>Yet despite this, it can often be difficult to convince one&#8217;s boss that it&#8217;s worth shelling out a grand to fly staff on a jolly to Barcelona for the weekend for two days of presentations and parties. Funny that.  </p>
<p>But we don&#8217;t think this way.  It&#8217;s crucial to us that our engineers feel inspired by their craft, and we recognise that attending (not to mention speaking at) conferences is an important way to get inspiration for your work, to socialise with engineers from other like-minded companies and get to feel part of a real community, a movement.  We also don&#8217;t want our engineers to feel in any way lonely in another city either, so we always try and make sure we send people in pairs (or more!).  I&#8217;m convinced this is money well spent.</p>
<p>So if you&#8217;re involved in the Ruby or Web community, here are the conferences you&#8217;ll find some FreeAgents at in the coming months:</p>
<ul>
<li><a href="http://nordicruby.org">Nordic Ruby</a></li>
<li><a href="http://scottishrubyconference.com">Scottish Ruby Conference</a> (of course!)</li>
<li><a href="http://baruco.org">Barcelona Ruby Conference</a></li>
<li><a href="http://windycityrails.org">Windy City Rails</a></li>
<li><a href="http://rockymtnruby.com">Rocky Mountain Ruby</a></li>
<li><a href="http://arrrrcamp.be">ArrrrCamp</a></li>
<li><a href="http://twitter.com/rubyconf">RubyConf</a></li>
</ul>
<p>If you&#8217;re attending any of these, be sure to hunt us down (via <a href="https://twitter.com/#!/freeagent/team/members">Twitter</a> or just look out for people in FreeAgent hoodies!) for a chat over a cup of tea.  From a teapot, naturally.</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.freeagent.com/2012/04/30/conference-pairs/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CoffeeScript with jQuery sprinkles</title>
		<link>http://engineering.freeagent.com/2012/03/23/coffeescript-with-jquery-sprinkles/</link>
		<comments>http://engineering.freeagent.com/2012/03/23/coffeescript-with-jquery-sprinkles/#comments</comments>
		<pubDate>Fri, 23 Mar 2012 11:01:30 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://engineering.freeagent.com/?p=265</guid>
		<description><![CDATA[This is part two of a two part intro to CoffeeScript. part one part two So my last article on CoffeeScript certainly seemed to provoke some thought. Some of you even found it useful, which is all sorts of awesome. &#8230; <a href="http://engineering.freeagent.com/2012/03/23/coffeescript-with-jquery-sprinkles/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>
  This is part two of a two part intro to CoffeeScript.<br />
</h3>
<ul>
<li><a href="http://engineering.freeagent.com/2012/01/30/coffeescript-two-sugars-no-bitter-aftertaste/">part one</a></li>
<li>part two</li>
</ul>
<p>
  So my <a href="http://engineering.freeagent.com/2012/01/30/coffeescript-two-sugars-no-bitter-aftertaste/">last article</a> on CoffeeScript certainly seemed to provoke some thought. Some of you even found it useful, which is all sorts of awesome. If you haven&#8217;t had a look at that article, I&#8217;d advise doing that first, as this one builds on it.
</p>
<hr />
<p>
  There is one more thing I’d like to touch on with our <a href="http://engineering.freeagent.com/2012/01/30/coffeescript-two-sugars-no-bitter-aftertaste/">CoffeeScript example</a>. We’re using an inline event handler to validate the form, which is ugly and obtrusive. With something like <a href="http://jquery.com/" title="jQuery">jQuery</a>, fixing this would be a cinch, but CoffeScript doesn’t give us any nice, cross-browser tools to achieve this.
</p>
<p>
  So let’s just use jQuery in our CoffeeScript!
</p>
<p>
  I’m going to use the current version from jQuery’s content delivery network:
</p>
<pre>
<code>&lt;script src="http://code.jquery.com/jquery-1.7.2.min.js"&gt;&lt;/script&gt;
&lt;script src="/script/form.js"&gt;&lt;/script&gt;</code>
</pre>
<p>
  but you can <a href="http://docs.jquery.com/Downloading_jQuery" title="Download jQuery">download the latest one</a> itself if you wish.
</p>
<p>
  Let’s also remove the inline submit handler from the form tag:
</p>
<pre>
<code>&lt;form id="contact_form"&gt;</code>
</pre>
<p>
  Now, to wire it all up. If this was simply jQuery, we’d do something like:
</p>
<pre>
<code>$('#contact_form').submit(function(){
  return validate(this);
});</code>
</pre>
<p>
  Look at all those brackets and braces! In CoffeeScript, this becomes simply:
</p>
<pre>
<code>$('#contact_form').submit -&gt;
  validate this</code>
</pre>
<p>
  Let’s step through this:
</p>
<ol>
<li>
<p>
      strip out brackets and semi-colons:
    </p>
<pre>
<code>$('#contact_form').submit function()
  return validate this</code>
</pre>
</li>
<li>
<p>
      remove explicit returns:
    </p>
<pre>
<code>$('#contact_form').submit function()
  validate this</code>
</pre>
</li>
<li>
<p>
      replace <code>function()</code> with <code>-&gt;</code>:
    </p>
<pre>
<code>$('#contact_form').submit -&gt;
  validate this</code>
</pre>
</li>
</ol>
<p>
  And as a final simplification, we can drop this to one line:
</p>
<pre>
<code>$('#contact_form').submit -&gt; validate this</code>
</pre>
<p>
  Which reads well, and conveys its intent perfectly: “When submitted, validate this”. One thing that may be annoying you is the brackets around <code>'#contact_form'</code>. Why can’t we lose those? Consider:
</p>
<pre>
<code>$ '#contact_form'.submit -&gt; validate this</code>
</pre>
<p>
  This will compile out to:
</p>
<pre>
<code>$( '#contact_form'.submit(function(){ return validate(this); }) );</code>
</pre>
<p>
  In other words, the <em>whole line</em> will be taken as the argument to the <code>$</code> function call. This is actually a precedence issue, and the idiomatic CoffeeScript way to resolve this is to lose the brackets around the argument, but add them in around the operation you want to take precendence. In other words:
</p>
<pre>
<code>($ '#contact_form').submit -&gt; validate this</code>
</pre>
<p>
  What we’re saying here is “call <code>submit</code> on the result of <code>$ '#contact_form'</code>”. This looks odd if you’re used to JavaScript, but is more in-keeping with the use of brackets in CoffeeScript to denote precedence, not to pass arguments.
</p>
<p>
  We’re nearly there. Lobbing this into our <code>form.coffee</code> file right now won’t quite work, as we need to wait until the document is ready before applying it. jQuery gives us that mechanism idiomatically:
</p>
<pre>
<code>$(function(){
  // do things on page load
});</code>
</pre>
<p>
  or, after applying our CoffeeScript transliteration:
</p>
<pre>
<code>$ -&gt; // do things on page load</code>
</pre>
<p>
  which gives us, in this case:
</p>
<pre>
<code>$ -&gt; ($ '#contact_form').submit -&gt; validate this</code>
</pre>
<p>
  Add this as the first line of <code>form.coffee</code> and we’re in business.
</p>
<p>
  Finally, since we’re no longer calling the <code>validate</code> function from outside the <code>form.coffee</code> file, we can switch from attaching the function to the <code>window</code> object, keeping everything nice and encapsulated:
</p>
<pre>
<code>$ -&gt; ($ '#contact_form').submit -&gt; validate this

validate = (form) -&gt;
  errors = get_errors form, ['name','email']
  report errors
  errors.length == 0

get_errors = (form,field_names) -&gt;
  errors = []
  fields = (form.elements[name] for name in field_names)
  field.name for field in fields if field.value == ''

report = (errors) -&gt;
  alert "The form has errors:\n\n- " + errors.join("\n- ") if errors.length &gt; 0</code>
</pre>
<p>
  Fifteen lines of fresh, readable Coffee or forty lines of JavaScript? Now <em>that</em> is a wakeup call.</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.freeagent.com/2012/03/23/coffeescript-with-jquery-sprinkles/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>CoffeeScript: two sugars, no bitter aftertaste</title>
		<link>http://engineering.freeagent.com/2012/01/30/coffeescript-two-sugars-no-bitter-aftertaste/</link>
		<comments>http://engineering.freeagent.com/2012/01/30/coffeescript-two-sugars-no-bitter-aftertaste/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 09:53:57 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://engineering.freeagent.com/?p=254</guid>
		<description><![CDATA[This is part one of a two part intro to CoffeeScript. part one part two The FreeAgent web application runs on Rails, and around the corner for us is an upgrade to Rails 3.1. This will bring many benefits to &#8230; <a href="http://engineering.freeagent.com/2012/01/30/coffeescript-two-sugars-no-bitter-aftertaste/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>
  This is part one of a two part intro to CoffeeScript.<br />
</h3>
<ul>
<li>part one</li>
<li><a href="http://engineering.freeagent.com/2012/03/23/coffeescript-with-jquery-sprinkles/">part two</a></li>
</ul>
<hr />
The FreeAgent web application runs on Rails, and around the corner for us is an upgrade to Rails 3.1. This will bring many benefits to performance, but one of the things I&#8217;m most excited about is the asset pipeline. This makes JS and CSS assets first-class Rails citizens, and as a bonus, allows us built-in access to pre-compilers like CoffeeScript and Sass.</p>
<p>I&#8217;ve been cutting JavaScript for as long as I&#8217;ve been coding for the web, so CoffeeScript has me all excited.</p>
<h2>Waiter! There&#8217;s some soup in my coffee!</h2>
<p>JavaScript isn’t very readable, and unreadable code is hard to maintain. Compared with Ruby or Python, there are brackets, braces and quotes everywhere. Often, there’s more syntactical soup than software.</p>
<p><a title="CoffeeScript" href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a> isn’t a framework, but instead compiles to runnable JavaScript. You write CoffeeScript, compile it, and out pops clean, tight JavaScript ready for the browser. You get optimised JavaScript, but work with clean, understandable, maintainable code.</p>
<p>CoffeeScript starts to make real sense once you’ve written some, so we’ll get to that as fast as we can. First, let’s look at installing the CoffeeScript compiler, so we can have it convert our CoffeeScript files into JavaScript that we can load in our browser.</p>
<p>To get CoffeeScript installed on your development machine, you’ll need a *nix-like environment, a text editor, a terminal, and a browser to check the results. First we install <a title="Node.js" href="http://nodejs.org/">node.js</a> (a JavaScript runtime that CoffeeScript needs to do its magic). We then install node’s package manager (npm) and use that to install CoffeeScript itself. On Mac OS X, the simplest way to do this is with Homebrew. Make sure you have XCode installed, then follow the instructions to install Homebrew, or just open a terminal session and type:</p>
<pre><code>/usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"</code></pre>
<p>Then use Homebrew to install node.js:</p>
<pre><code>brew install node</code></pre>
<p>Finally, install <a title="npm" href="http://npmjs.org/">npm</a> (a package manager for node), and use that to install CoffeeScript:</p>
<pre><code>curl http://npmjs.org/install.sh | sh
npm install -g coffee-script</code></pre>
<p>If you’re running Linux, your package manager can install node, then install npm and CoffeeScript. If, on the other hand, you’re using Windows, try following Matthew Podwysocki’s instructions at <a title="Getting Started with node.js on Windows" href="http://codebetter.com/matthewpodwysocki/2010/09/08/getting-started-with-node-js-on-windows/">CodeBetter</a>.</p>
<p>Okay, so now you’re up and running with CoffeeScript. Let’s dive in.</p>
<h2 id="coffeescriptyouvalidateme">CoffeeScript, you validate me</h2>
<p>What I want to run through here is the CoffeeScript syntax, and how expressive it can be. I could build up a really complicated little app, and that would be fun, but it would also be, well, complicated. Let’s keep things simple but practical so we can focus on CoffeeScript, not the problem domain.</p>
<p>Let’s validate a form!</p>
<pre><code>&lt;form id="contact_form"&gt;
  &lt;ol&gt;
    &lt;li&gt; 
      &lt;label&gt;Name&lt;/label&gt;
      &lt;input type="text" name="name"&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;label&gt;Email&lt;/label&gt;
      &lt;input type="email" name="email"&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;label&gt;Enquiry&lt;/label&gt;
      &lt;textarea name="enquiry"&gt;&lt;/textarea&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;input type="submit"&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/form&gt;</code></pre>
<p>Woo! Exciting! Let’s crack open <code>form.coffee</code> and see what mischief we can get up to.</p>
<pre><code>required_field_names = ['name', 'email']</code></pre>
<p>So far, so boring. That’s just JavaScript! True, but let’s drop to the shell and compile that file out to JavaScript:</p>
<pre><code>coffee -c form.coffee</code></pre>
<p>gives us <code>form.js</code>, which looks like this:</p>
<pre><code>(function(){
  var required_field_names;
  required_field_names = ['name','email];
}).call(this);</code></pre>
<p>Woah.</p>
<p>What’s happened? The <code>required_field_names</code> variable has been scoped by <code>var</code>, and the whole script has been wrapped in a namespace. This protects us against one of the most common sources of bugs in JavaScript: accidental global variables. In CoffeeScript, variables are local by default, instead of global as in regular JavaScript. If you’ve never worried about scoping in JavaScript before, you’re very lucky. If you have, then this is a lifesaver.</p>
<h2 id="thefirstsip">The first sip</h2>
<p>Let’s include the js file in our form:</p>
<pre><code>&lt;head&gt;
  &lt;script src="form.js"&gt;&lt;/script&gt;
&lt;/head&gt;</code></pre>
<p>And then, horribly, let’s add an event handler to the form. Remember, CoffeeScript isn’t a framework:</p>
<pre><code>&lt;form onsubmit="return validate(this);"&gt;</code></pre>
<p>Let’s declare our required fields array within this <code>validate</code> function, and <code>return false</code> to prevent the form from submitting during development. In plain JS, we might write the following:</p>
<pre><code>var validate = function( form ) {
  var required_fields_names = ['name', 'email'];
  return false;
}</code></pre>
<p>Now, CoffeeScript handles the variable declaration, so we can lose <code>var</code>. Additionally, function declarations use a more concise notation, so</p>
<pre><code>function( args ) { ... some code ... }</code></pre>
<p>becomes</p>
<pre><code>( args ) -&gt; ... some code ...</code></pre>
<p>and instead of braces, we use indentation to describe blocks. So we get:</p>
<pre><code>validate = (form) -&gt;
  required_field_names = ['name', 'email']
  return false</code></pre>
<p>We’ve also lost the semi-colons at the end of each line. Finally, like Ruby, the result of the last statement executed in the function is automatically returned. So we can lose the explicit return:</p>
<pre><code>validate = (form) -&gt;
  required_field_names = ['name', 'email']
  false</code></pre>
<p>Compile it out with <code>coffee -c form.coffee</code>, check <code>form.js</code>, reload the form in your browser and… the form submits. What’s gone wrong?</p>
<p>CoffeeScript creates everything in a namespace with a local scope. That means our <code>validate</code> function is so far only available to be called within the scope of the <code>form.js</code> file, and not outside. This prevents another function called <code>validate</code> from clobbering our definition, but isn’t very helpful. To get around this, CoffeeScript makes us explicitly declare variables we wish to have a global scope:</p>
<pre><code>window.validate = (form) -&gt; …</code></pre>
<p>is what we need. Compile again, reload the form, submit and… no submission. Progress!</p>
<p>If you’re anything like me, typing <code>coffee -c form.coffee</code> each time you make a change is starting to get annoying. If you’re so inclined, you could use something like <a title="Code Kit" href="http://incident57.com/codekit/">CodeKit</a>, but me, I like my command line. Luckily, the <code>coffee</code> command has a <code>watch</code> option. Running:</p>
<pre><code>coffee -cw *.coffee</code></pre>
<p>will launch the compiler and leave it running, recompiling any file that matches the pattern as it changes. Nice.</p>
<h2 id="grindingthebeans">Grinding the beans</h2>
<p>We have a list of required field names, and a submit handler to check them. Let’s get stuck into grabbing the fields themselves. Again, in JavaScript, you might do something like:</p>
<pre><code>var required_fields = [];
for ( var name in required_field_names ) {
  var field = form.elements[name];
  required_fields.push( field );
}</code></pre>
<p>to build up an array of actual fields to check. Yes, jQuery would make this simpler, but we’ll see about that later. Transliterating into CoffeScript, as a first pass, we might write:</p>
<pre><code>required_fields = []
for name in required_field_names
  field = form.elements[name]
  required_fields.push( field )</code></pre>
<p>Not a huge saving, but we can go one better with the <code>for</code> loop:</p>
<pre><code>required_fields = for name in required_field_names
  form.elements[name]</code></pre>
<p>In other words, <code>for</code> will act as a <code>map</code>, collecting together the returns of each iteration and returing those in an array.</p>
<p>Finally, CoffeeScript gives us a little bit of magic to turn this into a one liner:</p>
<pre><code>required_fields = (form.elements[name] for name in required_field_names)</code></pre>
<p>This reads like a sentence:</p>
<blockquote><p>Required Fields are the form elements for each Required Field Name</p></blockquote>
<p>But wait. Parentheses? I thought this was CoffeeScript! We don’t need no stinking parentheses!</p>
<p>Well, turns out we do. Parentheses in CoffeeScript are still allowable. In fact, they are used primarily to ensure precedence (just as they are in JavaScript), or sometimes simply to increase readability.</p>
<p>We’ve distilled five lines of JavaScript down to a single, clean line of code that expresses precisely what it does. <code>validate</code> itself is now four lines long. The compiled JavaScript is sitting at around 18 lines of bullet-proof, tight and memory efficient code.</p>
<p>There’s a lot to like about CoffeeScript.</p>
<h2 id="checkingtheroast">Checking the roast</h2>
<p>We have an array of input elements, so let’s check that each has a value. In JavaScript, we could do this:</p>
<pre><code>var errors = [];
for ( var field in required_fields ) {
  if ( field.value == '' ) {
    errors.push( field.name );
  }
}</code></pre>
<p>This would correct an array of bad field names. Let’s CoffeeScript this up:</p>
<pre><code>errors = []
for field in required_fields
  if field.value == ''
    errors.push field_name</code></pre>
<p>This doesn’t seem much of a saving. Notice, however, that there’s only a single statement in the <code>if</code> block. This means we can use the same trick we employed in the <code>for</code> block — putting the conditional statement in front of the condition:</p>
<pre><code>errors = []
for field in required_fields
  errors.push field_name if field.value == ''</code></pre>
<p>Now there’s only a single line in the <code>for</code> block, so we could repeat the trick and move everything on to a single line:</p>
<pre><code>errors = [] ( errors.push field_name if field.value == '' ) for field in required_fields</code></pre>
<p>Note our parentheses again, to help clarify what’s happening to what.</p>
<p>So, our CoffeeScript now looks like this:</p>
<pre><code>window.validate = (form) -&gt;
  required_field_names = ['name', 'email']
  errors = []
  required_fields = (form.elements[name] for name in required_field_names
  (errors.push field.name if field.value == '') for field in required_fields
  false</code></pre>
<p>There are two things left to do: prevent the form from submitting only if we have errors, and then report those errors back to the user.</p>
<h2 id="servingtheperfectcup">Serving the perfect cup</h2>
<p>Preventing submission on error is now trivial. Replace the last line of the function with a check on the number of errors:</p>
<pre><code>window.validate = (form) -&gt;
  ...
  errors.length == 0</code></pre>
<p><code>validate</code> now explicitly provides the “yes or now” answer to: are there zero errors on the form? This is very readable and maintainable: the final line of the function sums up perfectly what the function does. The error reporting could be similarly simple, adding the following before the return line:</p>
<pre><code>alert errors.join(',') if errors.length &gt; 0</code></pre>
<p>This is too simple for me, though: no descriptions, just a list of field names. Let’s break this out into an error handling function — <code>report</code>. Add this line instead of the <code>alert</code>:</p>
<pre><code>report errors</code></pre>
<p>then add the following function below <code>validate</code>:</p>
<pre><code>report = (errors) -&gt;
  alert "This form has errors:\n\n" + errors.join("\n- ") if errors.length &gt; 0</code></pre>
<p>Our final source looks like this:</p>
<pre><code>window.validate = (form) -&gt;
  required_field_names = ['name', 'email']
  errors = []
  required_fields = (form.elements[name] for name in required_field_names)
  (errors.push field.name if field.value == '') for field in required_fields
  report errors
  errors.length == 0

report = (errors) -&gt;
  alert "This form has errors:\n\n" + errors.join("\n- ") if errors.length &gt; 0</code></pre>
<p>Since we’ve started extracting concerns, let’s go a step further. Looking at the <code>validate</code> function, it does four things: defines fields that should be completed; collects errors from those fields; reports those errors, and returns false unless it has found no errors.</p>
<h2 id="cleaningup">Cleaning up</h2>
<p>This sort of quick extraction has always been a pain in JavaScript. Creating functions can lead to scoping issues, and the syntactical soup to ensure correct scope often prevents extraction from adding to the readability of the code. With CoffeeScript, pulling out functionality such as the error handling is trivial and does nothing but aid readability. We could continue this to clean up validation further:</p>
<pre><code>window.validate = (form) -&gt;
  errors = get_errors form, ['name', 'email']
  report errors
  errors.length == 0</code></pre>
<p>where <code>get_errors</code> just extracts the error-scanning code:</p>
<pre><code>get_errors = (form, field_names) -&gt;
  errors = []
  fields = ( form.elements[name] for name in field_names )
  field.name for field in fields when field.value == ''</code></pre>
<p>we could get even more concise and make <code>report</code> return a value dependent on whether there are any errors to report, which would let us boil <code>validate</code> down to:</p>
<pre><code>window.validate = (form) -&gt;
  report( get_errors form, ['name', 'email] )</code></pre>
<p>This is probably a step to far for just now, but look what we’re doing: we’re actually discussing how to make the code tidier and more readable instead of simply trying to figure out what the heck the code is trying to do in the first place.</p>
<p>That, alone, is the biggest win CoffeeScript gives you: You’re no longer tasked with first conquering your language before you can tackle the domain problem.</p>
<p><strong>Updated:</strong> the <code>get_errors</code> function definition thanks to a suggestion by <a href="http://engineering.freeagent.com/2012/01/30/coffeescript-two-sugars-no-bitter-aftertaste/#comment-113">Robin Wellner</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.freeagent.com/2012/01/30/coffeescript-two-sugars-no-bitter-aftertaste/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Hack Week round up</title>
		<link>http://engineering.freeagent.com/2012/01/23/hack-week-round-up/</link>
		<comments>http://engineering.freeagent.com/2012/01/23/hack-week-round-up/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 17:08:49 +0000</pubDate>
		<dc:creator>Olly</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://engineering.freeagent.com/?p=320</guid>
		<description><![CDATA[Hack Week has been and gone and I&#8217;ve finally got around to collating feedback from the team. To give you better insight into what everyone worked on, and the outcome of their efforts, each team has written about the projects &#8230; <a href="http://engineering.freeagent.com/2012/01/23/hack-week-round-up/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hack Week has been and gone and I&#8217;ve finally got around to collating feedback from the team.  To give you  better insight into what everyone worked on, and the outcome of their efforts, each team has written about the projects they took on and what they achieved.</p>
<h2 id="testsuitespeed1">Test Suite Speed #1</h2>
<p>Ben:</p>
<blockquote><p>I investigated the effects of garbage collection on our test suite speed. I tried turning off GC entirely (our tests run in parallel in child processes that exit before they use up too much memory) and deferring GC runs to every few seconds (using code from <a href="http://37signals.com/svn/posts/2742-the-road-to-faster-tests">http://37signals.com/svn/posts/2742-the-road-to-faster-tests</a>). I discovered that turning deferring GC runs was the best strategy &#8211; it reduced our test suite time by about 20%!</p></blockquote>
<blockquote><p>During hack week, I had a ton of fun and worked with team members with whom I don&#8217;t normally get an opportunity to collaborate. Plus we have faster tests, which is a huge benefit for the whole team. I&#8217;m looking forward to the next one!</p></blockquote>
<h2 id="app-widesearch">App-wide Search</h2>
<p>Mihai:</p>
<blockquote><p>
As we are about to move to <a href="http://www.elasticsearch.org">Elasticsearch</a> for indexing our logs, my Hack Week idea was to experiment with building an app-wide search function. It is just a prototype but it enables users to search across Contacts, Projects and Expenses and can easily be extended. Elasticsearch is accessed from Rails using the <a href="https://github.com/karmi/tire">Tire gem</a>. Instead of using Tire&#8217;s <code>after_save</code> callback to keep the index up to date, Elasticsearch has the concept of <a href="http://www.elasticsearch.org/guide/reference/river/">rivers</a> which pulls new data. Every update triggers an AMQP message using <a href="https://github.com/ruby-amqp/bunny">Bunny</a> which is then picked up by <a href="https://github.com/elasticsearch/elasticsearch-river-rabbitmq/blob/master/README.md">Elasticsearch RabbitMQ river</a>.</p></blockquote>
<blockquote><p>It was an exciting idea and I really enjoyed the hack week and had the opportunity of experimenting with new pieces of infrastructure which we hope to use soon.</p></blockquote>
<h2 id="apiclient">API Client</h2>
<p>Graeme B:</p>
<blockquote><p>Murray and I, with design input from Tane, built CashAgent: a simple mobile cashflow forecasting app using the new version 2 of the FreeAgent API.  We developed the server side of the app in Ruby using <a href="http://www.sinatrarb.com/">Sinatra</a>, and the UI of the app in Javascript using <a href="http://emberjs.com/">Ember.js</a>.</p></blockquote>
<blockquote><p>Our goals: </p>
<ul>
<li>It was Murray and Tane&#8217;s first week at FreeAgent and we wanted them to jump straight into building apps. </li>
<li>Give the new version of the API a good work out, especially our new OAuth 2.0 authentication system.</li>
<li>Try out the Ember.js framework (which is great by the way!)</li>
</ul>
</blockquote>
<blockquote><p>We had loads of fun building the app and are looking forward to releasing API v2 and the next Hack Week.</p></blockquote>
<h2 id="revisitinghttploadbalancing">Revisiting HTTP load balancing</h2>
<p>Thomas:</p>
<blockquote><p>
Bugged by a number of shortcomings in the &#8220;traditional&#8221; approach to scaling via HTTP load-balancing, I spent the time prototyping an approach to this problem based on an idea that has been rattling around in my head for some time. Rather than configuring the address of each of our app-servers in a front-end load-balancer and having this load-balancer &#8220;push&#8221; traffic to the servers, I inserted a Message Queueing server (<a href="http://www.rabbitmq.com/">RabbitMQ</a>) into the mix, writing a small server to &#8220;publish&#8221; HTTP requests onto a queue, and letting our app workers subscribe to this queue to do the work for each request.</p></blockquote>
<blockquote><p>By the end of the week, I had built a relatively robust prototype which we&#8217;ve used in a testing environment internally, which has demonstrated that it&#8217;s both fast and scalable enough, and also simplified the configuration and maintenance of our infrastructure.</p></blockquote>
<blockquote><p>Which is nice.</p></blockquote>
<blockquote><p>Blog posts and open-sourcing hopefully to follow.</p></blockquote>
<h2 id="bigdecimalruby1.9.3">BigDecimal / Ruby 1.9.3</h2>
<p>Graeme M:</p>
<blockquote><p>
We started out the Hack Week by looking at the performance of Ruby&#8217;s BigDecimal, which we use extensively, based on my gut feeling that it was slow, and my secret desire to mess around with C extensions. However, after a spot of performance testing, we discovered that it wasn&#8217;t that slow, and it definitely wasn&#8217;t a bottleneck.</p></blockquote>
<blockquote><p>So we switched tack and worked on upgrading FreeAgent to Ruby 1.9.3 (we&#8217;re on 1.9.2 right now).  This upgrade, whilst still not complete, will decrease our test suite run time as well as greatly improving Rails boot time.  We hope to move the app fully onto 1.9.3 in the near future.</p></blockquote>
<h2 id="testhygiene">Test Hygiene</h2>
<p>JB:</p>
<blockquote><p>We test everything at FreeAgent, before, during and after development. This means we have a huge suite of tests which we run any time we make a change. It also means that suite takes a long time to run. Any developer will tell you that Test Driven Development requires fast turnaround on your tests. Waiting ten seconds to find out if you&#8217;ve broken anything can be deemed too long. The full suite of unit tests in FreeAgent takes several minutes.</p></blockquote>
<blockquote><p>Instead of starting from the premise of making tests &#8220;faster&#8221;, we thought we&#8217;d start by making them &#8220;better&#8221;. Any fool can speed up tests by reducing the number or scope of them. Our goal: get faster while actually increasing coverage.</p></blockquote>
<blockquote><p>Result? We won, spectacularly. Reviewing our tests in a concerted effort revealed a number of anti-patterns, chiefly:</p></blockquote>
<blockquote>
<ul>
<li>hitting the database when we didn&#8217;t need to</li>
<li>testing things more than once, in more than one place</li>
<li>trusting our factory-girl factories</li>
</ul>
</blockquote>
<blockquote><p>the first two were easily spotted and dealt with, and led to a massive speed up. The third was more subtle. Something as innocent-looking as:</p></blockquote>
<blockquote><pre>Factory(:bill)</pre>
</blockquote>
<blockquote><p>was causing a huge overhead. Why? Because a bill needs a contact to be valid, and a contact needs a company to be valid, and a company needs a bank account to be valid, and all of these objects were being created and destroyed every time we needed a bill. Replacing with:</p></blockquote>
<blockquote><pre>Bill.new</pre>
</blockquote>
<blockquote><p>made all of that go away. When all you want to do is check that bill correctly decides when it&#8217;s overdue, you don&#8217;t care about the rest of the object, and you certainly don&#8217;t need the overhead of going to the database to create a load of relationships you aren&#8217;t testing. Our factories had grown, but our tests hadn&#8217;t evolved with them.</p></blockquote>
<blockquote><p>Obvious stuff, but sometimes you need to take that step back and ask &#8220;what am I trying to do&#8221; instead of &#8220;how has this been done before&#8221;.</p></blockquote>
<blockquote><p>Especially when it takes you from 150 seconds to four.</p></blockquote>
<p>It goes without saying that Hack Week was an enormous success.  Everyone enjoyed it (although on reflection, some wished they had picked something a bit more &#8216;exciting&#8217;!) and it has definitely had a positive impact on the team and the way we&#8217;ll approach things going forward (tests in particular).  We&#8217;re also really excited about driving some of the concepts through to production, such as the new load-balancing solution.  And of course we&#8217;ll be blogging more about the technologies as they progress (and are hopefully open sourced!).</p>
<p>Watch this space.</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.freeagent.com/2012/01/23/hack-week-round-up/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Engineering Summer Interns</title>
		<link>http://engineering.freeagent.com/2012/01/11/engineering-summer-intern/</link>
		<comments>http://engineering.freeagent.com/2012/01/11/engineering-summer-intern/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 16:34:31 +0000</pubDate>
		<dc:creator>Olly</dc:creator>
				<category><![CDATA[Hiring]]></category>

		<guid isPermaLink="false">http://engineering.freeagent.com/?p=297</guid>
		<description><![CDATA[Every summer we invite at least one intern to join our Edinburgh-based Engineering team for three months between June and September and today we&#8217;re officially opening the doors to the Class of 2012! If you&#8217;re a CompSci student at a &#8230; <a href="http://engineering.freeagent.com/2012/01/11/engineering-summer-intern/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Every summer we invite at least one intern to join our Edinburgh-based Engineering team for three months between June and September and today we&#8217;re officially opening the doors to the Class of 2012!  If you&#8217;re a CompSci student at a UK university and you want to do something amazing this summer, please <a href="mailto:jobs@freeagent.com">get in touch</a>!</p>
<p>Find out all the details on our <a href="http://www.freeagent.com/company/jobs/engineering-summer-interns">Jobs Page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.freeagent.com/2012/01/11/engineering-summer-intern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack Week update</title>
		<link>http://engineering.freeagent.com/2012/01/11/hack-week-update/</link>
		<comments>http://engineering.freeagent.com/2012/01/11/hack-week-update/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 15:50:50 +0000</pubDate>
		<dc:creator>Olly</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://engineering.freeagent.com/?p=287</guid>
		<description><![CDATA[We&#8217;re two days into our first Hack Week and we&#8217;re already seeing good progress. Testing is a common theme being worked on by two teams. The FreeAgent code base is fairly large and is complemented by an even larger automated &#8230; <a href="http://engineering.freeagent.com/2012/01/11/hack-week-update/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re two days into our first <a href="http://engineering.freeagent.com/2012/01/09/hack-week-initial-commit/">Hack Week</a> and we&#8217;re already seeing good progress.  </p>
<p>Testing is a common theme being worked on by two teams.  The FreeAgent code base is fairly large and is complemented by an even larger automated test suite, containing unit, functional and integration tests.  This test suite is a massive win for us, enabling developers to aggressively refactor code and be confident that they haven&#8217;t introduced any unwanted side effects by doing so.  The downside to the tests is the time it takes to run them all, which is currently ~20 minutes.  That&#8217;s 20 minutes parallelised over 4 hyperthreaded cores on a beefed up i7 iMac.</p>
<p>We have one team looking at reducing the total run time of the test suite, and also reducing the time it takes to execute a single test which, due to Ruby 1.9.2 and Rails, can be frustratingly slow due to the boot-up time, hindering <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a> flow.  Another team is looking at removing unused test dependencies and refactoring test cases by removing scenarios where we&#8217;re testing things too often or sometimes unnecessarily.  We&#8217;ve already seen one particular test case run time drop from over one minute down to four seconds! </p>
<p>We have a team developing a handy new web app against our new API (currently <a href="https://staging.dev.freeagent.com/docs">in beta</a>), and another team looking at optimising floating point arithmetic, which we do a lot of in FreeAgent as you might imagine, and we&#8217;re also experimenting with <a href="http://www.elasticsearch.org/">elasticsearch</a> as a foundation for an app-wide search feature for FreeAgent.</p>
<p>Our design and front-end development team are collaborating on a new prototype area of the app, thinking about the past, present and future of your business.</p>
<p>Finally, leading on from the work we&#8217;ve been doing at <a href="http://engineering.freeagent.com/2011/11/29/speeding-up-ssl/">Speeding up SSL</a>, we&#8217;re prototyping an evented and queue-based middleware by attempting a novel approach at load balancing web requests.  </p>
<p>Now, back to the hack.</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.freeagent.com/2012/01/11/hack-week-update/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hack Week [initial commit]</title>
		<link>http://engineering.freeagent.com/2012/01/09/hack-week-initial-commit/</link>
		<comments>http://engineering.freeagent.com/2012/01/09/hack-week-initial-commit/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 09:43:18 +0000</pubDate>
		<dc:creator>Olly</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://engineering.freeagent.com/?p=269</guid>
		<description><![CDATA[Starting today we’re going to be trying something a little different in our development team. For the entire week our project schedules are being put on ice while all our engineers and designers (12 of them) are being left to &#8230; <a href="http://engineering.freeagent.com/2012/01/09/hack-week-initial-commit/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Starting today we’re going to be trying something a little different in our development team. For the entire week our project schedules are being put on ice while all our engineers and designers (12 of them) are being left to their own devices to hack on whatever they want, so long as it’s FreeAgent-related.</p>
<p><a href="http://en.wikipedia.org/wiki/Hackathon">Hackathons</a> like this are nothing new in the software development world – Google offer 20% time, Atlassian have <a href="http://www.atlassian.com/fedex-day">FedEx day</a> . It’s no surprise that developer-centric companies are doing this more frequently. Hack days provide an opportunity for developers to get properly <a href="http://en.wikipedia.org/wiki/Flow_(psychology)">in the zone</a> and push themselves to deliver something different; to learn and apply a new technology; to deliver that project they’ve always wanted to kick off but haven’t yet been able to prioritise; to take that crazy idea they’ve been thinking about for ages and prove the concept with a working prototype; to pair-up and <em>have fun</em>.</p>
<p>A lot of hackathons are for an exhausting 24 or 48 hours, with long nights and lots of caffeine. Our developers are more than welcome to stay late and hack (we’ll buy in pizza – or more likely, <a href="http://www.illegaljacks.co.uk/">burritos</a> – and everyone can help themselves from our resident beer fridge), but we don’t want to make that mandatory just to get stuff done. Instead, we’re just making the hackathon a whole week long.</p>
<p>Hack Week is a prototype itself. Expectations are high but of course <a href="http://www.codinghorror.com/blog/2006/05/the-long-dismal-history-of-software-project-failure.html">software projects often fail</a>. We’re cool with that though, because we know we’ll learn something valuable from the experience and we’ll enjoy the ride!</p>
<p>I’ll be blogging during the week about all the projects we’re undertaking and I&#8217;ll post again about what we accomplished on Friday.</p>
<p>Go FreeAgents!</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.freeagent.com/2012/01/09/hack-week-initial-commit/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Puppet and MCollective Talk</title>
		<link>http://engineering.freeagent.com/2011/12/09/puppet-and-mcollective-talk/</link>
		<comments>http://engineering.freeagent.com/2011/12/09/puppet-and-mcollective-talk/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 10:12:53 +0000</pubDate>
		<dc:creator>Olly</dc:creator>
				<category><![CDATA[Platform]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[mcollective]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://engineering.freeagent.com/?p=235</guid>
		<description><![CDATA[Thomas Haggett, one of our senior platform engineers, recently gave a talk at a Scottish Ruby User Group meetup about Puppet and MCollective, two technologies we&#8217;ve been embracing in anger at FreeAgent in 2011. We&#8217;ll be blogging about what we&#8217;re &#8230; <a href="http://engineering.freeagent.com/2011/12/09/puppet-and-mcollective-talk/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Thomas Haggett, one of our senior platform engineers, recently gave a talk at a <a href="http://scotrug.org">Scottish Ruby User Group</a> meetup about <a href="http://projects.puppetlabs.com/projects/puppet">Puppet</a> and <a href="http://puppetlabs.com/mcollective/introduction/">MCollective</a>, two technologies we&#8217;ve been embracing in anger at FreeAgent in 2011.  We&#8217;ll be blogging about what we&#8217;re doing with these technologies in detail in the coming months but in the meantime, here&#8217;s a little taster video:
</p>
<p><iframe src="http://player.vimeo.com/video/33049334?title=0&amp;byline=0&amp;portrait=0" width="550" height="309" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
<p>
Thanks to <a href="http://edgecase.com/">EdgeCase UK</a> for recording this.</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.freeagent.com/2011/12/09/puppet-and-mcollective-talk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speeding up SSL</title>
		<link>http://engineering.freeagent.com/2011/11/29/speeding-up-ssl/</link>
		<comments>http://engineering.freeagent.com/2011/11/29/speeding-up-ssl/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 10:47:35 +0000</pubDate>
		<dc:creator>Thomas</dc:creator>
				<category><![CDATA[Platform]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[tls]]></category>

		<guid isPermaLink="false">http://engineering.freeagent.com/?p=189</guid>
		<description><![CDATA[SSL is great; widely supported, easy to set-up, relatively cheap these days and (relatively) secure. We&#8217;ve required it from our early days and it hasn&#8217;t caused us too many issues other than needing us to renew our SSL certificates from &#8230; <a href="http://engineering.freeagent.com/2011/11/29/speeding-up-ssl/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>SSL is great; widely supported, easy to set-up, relatively cheap these days and (relatively) secure. We&#8217;ve required it from our early days and it hasn&#8217;t caused us too many issues other than needing us to renew our SSL certificates from time to time and requiring a few more IP addresses than we otherwise would have needed<a href="http://en.wikipedia.org/wiki/Secure_Sockets_Layer#Support_for_name-based_virtual_servers"><sup>1</sup></a>.</p>
<p>That said, I recently visited Portland to attend <a href="http://puppetconf.com/">PuppetConf</a> (all about <a href="http://projects.puppetlabs.com/projects/puppet">Puppet</a>, a configuration management technology that we&#8217;re using, blog post to follow) and when I tried to access FreeAgent from the West Coast I had experience, first-hand, of one of SSLs major drawbacks &#8211; namely the effect of latency.</p>
<p>SSL, or <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security">TLS</a> to use it&#8217;s more up-to-date name, effectively wraps a normal HTTP connection, transparently encrypting data as it is transmitted between the web browser and the server. To establish this secure channel, the client and server must first exchange certain pieces of information in a phase known as the &#8220;handshake&#8221;. This negotiation typically comprises of: <sup>(see </sup><a href="http://en.wikipedia.org/wiki/Secure_Sockets_Layer#Simple_TLS_handshake"><sup>wikipedia</sup></a><sup> for more detailed information)</sup></p>
<ol>
<li>The client opens a standard TCP connection to a port appropriate for the wrapped application protocol (by default 443 for HTTPS).</li>
<li>The client sends a &#8220;ClientHello&#8221; message specifying its support for protocol versions and encryption algorithms.</li>
<li>The server responds with a &#8220;ServerHello&#8221; message, agreeing a specific protocol version and algorithm to use. It also sends a certificate (which is part of a <a href="http://en.wikipedia.org/wiki/X.509">remarkably clever mechanism</a> allowing you to trust a previously unknown remote server), and a &#8220;ServerHelloDone&#8221; indicating the server is happy with a given set of parameters.</li>
<li>The client then sends a &#8220;ClientKeyExchange&#8221; message which, using asymmetric cryptography and the trusted server identity from the certificate, shares a value crucial to establish a &#8220;shared secret&#8221; which can be used to encrypt all further communication.  A &#8220;ChangeCipherSpec&#8221; message is also sent by the client, to mark that all subsequent communication is encrypted, and a &#8220;Finished&#8221; message is sent which can be used by the server to work out if the negotiation was successful.</li>
<li>The server then uses the clients &#8220;Finished&#8221; message to perform checks and responds with its own &#8220;ChangeCipherSpec&#8221; and encrypted &#8220;Finished&#8221; messages.</li>
<li>The client receives the server&#8217;s &#8220;Finished&#8221; message and verifies it, at which point the server and client have enough information to transparently encrypt all further (HTTP) data.</li>
</ol>
<p>Looking at this exchange, it requires two full round-trips from client to server and back to complete, whilst the peer simply waits, before HTTP can take over. Bear in mind all this takes place over a TCP connection, so this is in addition to the usual TCP SYN/ACK dance that must also happen for the connection to exist.</p>
<p>Since we&#8217;re a Scottish company and our product is currently geared towards a UK audience, our servers are based in the UK. For an average user hooked up via ADSL, even with a relatively poor 50-60ms round-trip time, the time taken for this SSL handshake, 100ms in this case, pales into insignificance compared to the time our servers spend crunching numbers to handle the request. And that is a poor link. My home ADSL2+ line, for example, actually takes 18ms for a round trip, so this handshake just isn&#8217;t a problem.</p>
<p>However, the further you travel from the UK, the more this picture changes. When a customer in the US will have to wait, on a good day, 120ms for a packet to get to our servers and back, these small but necessary exchanges begin to add up. And it turns out we actually have a sizeable international customer base using our Universal product. Travel out to Japan and you find the back-forth trip of a message will take a good 260ms. Also consider that, due to the number of links these packets are hopping across to reach their destination, this latency can vary much more wildly (generally increasing!). All things considered, it really was a surprise that we still have paying customers using the site in Australia.</p>
<h2>So, the fix!</h2>
<p>The trivial fix for this is to simply move the server (geographically and logically) closer to the client, thereby reducing the round-trip-time, and speeding up the handshake. It&#8217;s not, however, going to be <em>that</em> simple. In my ideal world, we&#8217;d be shipping users&#8217; traffic to a set of servers geographically close to them; splitting and moving our databases around to accomplish this. We&#8217;re, sadly, not quite there in terms of international demand to be able to prioritise the work of sharding our database and managing the overheads of multiple, geographically separate clusters. Not to mention overcoming potential policy issues with shipping and storing customer&#8217;s data on international servers. Not yet, anyway.</p>
<p>So, we can&#8217;t move the app servers or the database. The next logical conclusion is to move the machines which are actively handling the server side of the SSL handshake.</p>
<p>Our infrastructure is composed of multiple application servers handling the requests (we&#8217;re using <a href="http://unicorn.bogomips.org/">unicorn</a>, by the way), with traffic distributed to these using load-balancer software (<a href="http://nginx.com">nginx</a>, in our case). Since both the app servers and load-balancers reside securely within our production data-center, the SSL encryption and decryption takes place on the load-balancers and unencrypted HTTP is used between internal servers. Since we use Puppet to automate our configuration, it&#8217;s now straightforward to create and manage a new remote load-balancer, closer to some of our international clients, which takes care of the SSL termination and uses HTTP (without the SSL/TLS overhead) across the latent link to communicate with our production machines.</p>
<p>Great, but I&#8217;m sure you&#8217;re politely coughing, ready to interject with a suggestion that sending unencrypted HTTP requests and responses half way around the world might not be the best idea. Pfft to that, I say.</p>
<p>Actually, you&#8217;d be right. So the next step is to encrypt this traffic. It would be silly to use HTTPS on a per-connection basis, incurring the handshake penalty for each request again. So instead I&#8217;m using the excellent <a href="http://openvpn.org/">OpenVPN</a> software to establish a single long-lived TLS tunnel between the remote load-balancer and our UK servers. This is ideal as the handshake happens once, it&#8217;s only renegotiated every hour and is persistent &#8211; able to carry multiple HTTP requests securely, without the penalty of HTTPS negotiation for each request.</p>
<p>So I spent a couple of hours throwing together a proof of concept, just to see what the potential improvement may be.</p>
<h2>Ok, ok. The numbers&#8230;</h2>
<p>To play around with this, I configured an <a href="http://aws.amazon.com/ec2/">Amazon EC2</a> instance in their Japan region, configured to proxy traffic, as described above, to our UK load-balancers. To get a &#8220;finger-in-wind&#8221; idea of the improvement, I&#8217;m using the <a href="http://httpd.apache.org/docs/2.0/programs/ab.html">apachebench</a> utility on another EC2 instance.</p>
<p>To get a feel for the latency involved here, I ping&#8217;ed our UK datacenter from the EC2 instance:</p>
<pre>[thomas@ap-lb1.production:~]$ ping -c3 94.236.51.2
PING 94.236.51.2 (94.236.51.2) 56(84) bytes of data.
64 bytes from 94.236.51.2: icmp_seq=1 ttl=44 time=<strong>268 ms</strong>
64 bytes from 94.236.51.2: icmp_seq=2 ttl=44 time=<strong>259 ms</strong>
64 bytes from 94.236.51.2: icmp_seq=3 ttl=44 time=<strong>267 ms</strong>

--- 94.236.51.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 259.616/<strong>265.232</strong>/268.772/4.037 ms</pre>
<p>So we&#8217;re seeing a round-trip time of ~265ms, as expected. The next step is to do a &#8220;baseline&#8221; HTTP request from a UK server to the UK app &#8211; to see the time spent on the server actually rendering the page. The page I&#8217;m using, incidentally, is our login page as it doesn&#8217;t require any pesky session cookies, and is relatively lightweight.</p>
<pre>ab -n 50 https://tdhtest.freeagentcentral.com/login
              min  mean[+/-sd] median   max
Connect:       14   14   0.4     14      16
Processing:    12   18  22.1     16     171
Waiting:       11   18  22.0     15     170
Total:         26   <strong>32</strong>  22.1     30     185</pre>
<p>So, the best-case is roughly 30ms. Let&#8217;s see how the app currently performs for international users, by requesting the page from our remote EC2 instance, via the UK load-balancers:</p>
<pre>ab -n 50 https://tdhtest.freeagentcentral.com/login
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      985 1043  28.0   1042    1095
Processing:   260  279  26.2    276     453
Waiting:      259  278  26.1    275     452
Total:       1246 <strong>1322</strong>  43.3   1318    1501</pre>
<p>Woah! 1.3 seconds to receive a login page. Now, let&#8217;s try with going through the EC2 load-balancer, with traffic tunnelled back to the UK:</p>
<pre>ab -n 50 https://tdhtest.freeagent.com/login
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       16   16   0.8     16      18
Processing:   507  540  12.5    539     567
Waiting:      507  540  12.4    539     567
Total:        523  <strong>557</strong>  12.4    556     583</pre>
<p>557ms &#8211; not bad! Less than half the original time, which I&#8217;d call quite an improvement. Just to get a slightly different take, I used a remote browser timing tool, <a href="http://loads.in">loads.in</a>, to time the page load from these locations, from the request sent to the page rendered in the browser. For completeness, the tests were using Safari 4:</p>
<ul>
<li>Baseline reading was <strong>1.9 seconds</strong></li>
<li>A browser in Japan hitting our UK load-balancers took <strong>9.4 seconds</strong></li>
<li>A browser in Japan hitting our remote load-balancers took <strong>6.7 seconds</strong></li>
</ul>
<p>Whilst, this is a less marked improvement, it&#8217;s worth considering that we load our static assets; images, css files, javascripts, animated gifs, flash videos, background sounds, etc. from a separate domain &#8211; and this <em>won&#8217;t</em> have been routed via the remote load-balancer, so will be having quite a detrimental impact on the overall page load-time.</p>
<p>I&#8217;ll re-try the test, some time, without this offloading, to see what the actual improvement could be.</p>
<h2>Now what?</h2>
<p>So we can now route specific customers&#8217; traffic through this load-balancer, but what we&#8217;d ideally want to do is select which load-balancer to use based on the origin of the traffic. To do this &#8220;properly&#8221; would require us to have DNS servers configured to return records based on the source IP of the requests. This is more work than I care to undertake for a few hours messing with SSL, but thankfully Dynect (our DNS provider) is able to take care of this for us. They have multiple <a href="http://en.wikipedia.org/wiki/Anycast#Domain_Name_System">anycast&#8217;ed DNS</a> servers and offer a <a href="http://dyn.com/dns/dynect-managed-dns/traffic-management/">traffic management system</a> which is perfect.</p>
<p>We&#8217;ve not yet enabled this, as it&#8217;s little more than a proof-of-concept, but if you&#8217;re an international FreeAgent user and would like to try it out, please <a href="mailto:sslbeta@freeagent.com">get in touch</a>.</p>
<h2>Anything else?</h2>
<p>Since we&#8217;re now managing both ends of the crazy long link, a world of tweaks and optimisation becomes possible. For starters, the two things I&#8217;m currently playing with:</p>
<ul>
<li>Endless tweaks to the TCP congestion control and windowing algorithms. These regulate the maximum amount of un-acknowledged data that can be sent between the client and server which, as long as packets aren&#8217;t dropped, reduces the time either party has to spend waiting for data acknowledgements. Google do crazy things with this to make their homepage super fast, <a href="http://research.google.com/pubs/pub36640.html">check it out</a>.</li>
<li>TCP parameters are &#8220;tuned&#8221; as connections transfer more data, so having many short-lived HTTP connections &#8211; i.e. one per request &#8211; kills any benefit, as well as each HTTP connection having an associated TCP connection setup cost (of one round-trip). I&#8217;m currently playing around with multiplexing all HTTP requests down a single persistent TCP connection established between the remote and local load-balancers, which overcomes the connection set-up cost, and will allow this connection&#8217;s parameters to be tuned as time goes on.</li>
</ul>
<p>I&#8217;ll see how I get on, and perhaps even post a follow up blog post if things go well.</p>
<p>Wow. You made it to the bottom. In that case, I should probably mention to you that <a href="http://www.freeagent.com/company/jobs/senior-platform-engineer">we&#8217;re hiring</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.freeagent.com/2011/11/29/speeding-up-ssl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Friday Link Party 11-11-11</title>
		<link>http://engineering.freeagent.com/2011/11/11/friday-link-party-11-11-11/</link>
		<comments>http://engineering.freeagent.com/2011/11/11/friday-link-party-11-11-11/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 12:59:11 +0000</pubDate>
		<dc:creator>Olly</dc:creator>
				<category><![CDATA[Link Party]]></category>

		<guid isPermaLink="false">http://engineering.freeagent.com/?p=174</guid>
		<description><![CDATA[Totally forgot to post here last week so this week it&#8217;s a special, bumper, &#8216;rollover&#8217; edition of link goodness.  Here we go&#8230; We&#8217;re hard at work putting the finishing touches to our second generation API right now.  The new API &#8230; <a href="http://engineering.freeagent.com/2011/11/11/friday-link-party-11-11-11/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Totally forgot to post here last week so this week it&#8217;s a special, bumper, &#8216;rollover&#8217; edition of link goodness.  Here we go&#8230;</p>
<ul>
<li>We&#8217;re hard at work putting the finishing touches to our <a href="https://groups.google.com/d/msg/freeagent_api/_xf-4Kz9esg/kbh1rAb9x7EJ">second generation API</a> right now.  The new API uses OAuth as opposed to HTTP Basic for authentication, so <a href="https://code.google.com/oauthplayground/">OAuthPlayground</a> popped up at just the right time.</li>
<li>In the <a href="http://www.cleancoders.com/codecast/clean-code-episode-7/show">latest Clean Coders episode</a>, <a href="https://twitter.com/unclebobmartin">&#8216;uncle&#8217; Bob Martin</a> talks about the architecture of &#8220;web-based accounting systems&#8221;!</li>
<li>Nicholas Henry published an article on the Firsthand Web Design blog called <a href="http://blog.firsthand.ca/2011/10/rails-is-not-your-application.html">Rails is not your application</a>.</li>
<li>The <a href="http://www.bcs.org/category/16216">2012 Turing Lecture</a> will be coming to our home town of Edinburgh.</li>
<li>We don&#8217;t use <a href="http://nodejs.org/">node.js</a> right now at FreeAgent but if it&#8217;s something you&#8217;re interested in, <a href="http://www.nodebeginner.org/">The Node Beginner Book</a> looks like a great place to start.</li>
<li>Do we need another browser?  The people at <a href="http://raven.io/">Raven</a> certainly think so.  Anyone used this yet?</li>
<li>We&#8217;re big fans of AWS here at FreeAgent (we use S3 in production and we&#8217;ve been playing around with EC2). Amazon have expanded their regions with <a href="http://aws.typepad.com/aws/2011/11/now-open-us-west-portland-region.html">a new one in Oregon, USA</a>.</li>
<li>If you find yourself unable to keep on top of your gems in your Ruby app and you want someone to just tell you when new versions are available, maybe <a href="https://gemnasium.com/">Gemnasium</a> is for you.</li>
<li>If you&#8217;re using plain MD5 hashes for passwords, take a look at <a href="https://github.com/juuso/BozoCrack">BozoCrack</a> to see how secure they are.</li>
<li>Finally, we reminisced about the good old days of writing <a href="http://en.wikipedia.org/wiki/Hungarian_notation ">Hungarian Notation</a>, that <em><a href="http://thc.org/root/phun/unmaintain.html">tactical nuclear weapon of source code obfuscation technique</a></em>. I particularly like the <a href="http://msdn.microsoft.com/en-us/library/aa260976(v=vs.60).aspx">MSDN guide</a> examples: <br/><br/><code>int* pbsy = &amp;rgbsyHash[(wHash&amp;077777)%cwHash];</code></li>
</ul>
<p>And on that note&#8230; laters.</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.freeagent.com/2011/11/11/friday-link-party-11-11-11/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

