Managing Software Development

Hiring Great Engineers in Six Easy Steps

I gave a talk tonight on how to recruit great engineers ( a common pain-point for New York startups) tonight at the NYC Technology meetup. In six months, we grew Cinchcast Tech into an amazing team from six to fifteen people. In this talk, we discussed: - What it takes to hire and retain great engineers in New York area. - Qualities you should look for in a technical co-founder. - Does it make sense to outsource? - As well as other topics raised by the audience. The slides are posted below:

Daily scrum for the Cinchcast tech team

Daily scrum for the Cinchcast tech team

BlogTalkRadio Performance Improvements

Cinchcast provides the technology that powers BlogTalkRadio. We recently made some performance improvements on blogtalkradio.com that we are really excited about. You can read about them on the BlogTalkRadio Blog.

The Rake Build System
by Luis López de Quintana, Front End Architect

We at Cinchcast consider ourselves an “alt.NET” shop. This means we use C# and the .NET framework on Windows to do most of our heavy lifting, but we also rely on non-MS technologies extensively, because they are the right tool for the job. While we use .NET MVC on IIS for our web applications, we use REDIS for an ACID-compliant high-QPS datastore, and Rake for building our .NET projects.

When writing our Rake build system, we found that there was no “one true HOWTO” on the topic of writing Rakefiles, especially from the perspective of a complete Ruby n00b. Some articles covered some parts of the syntax, others other parts, and to make it worse, the Rake syntax changed over the iterations of Rake, and many high-PageRank’d Rake tutorials are hopelessly out of date. Here we aim to provide the most conclusive introduction to Rakefile syntax for Rake/Ruby neophytes.

This HOWTO is current as of Ruby 1.9 and Rake 0.9.2.

What is Rake?

Rake is the Ruby build system, meant to replace UNIX make. Buildmasters write Rakefiles, which define how the application is built. These Rakefiles are full-fledged Ruby scripts which can be run through a Ruby interpreter with no issues. This attribute of Rakefiles is the core reason why Rake is more attractive than the historical build systems which use a bespoke, declarative DSL such as make, ant, or MSBuild. Conditionals, loops and encapsulation are all much easier to implement and debug when using a first-class imperative language like Ruby for the build language.

Rake became popular for building .NET apps when Derick Bailey published his Rake tasks for .NET: the Albacore library. The flexibility of using Ruby in Rakefiles and the solid out-of-the-box functionality provided by Albacore makes for a very compelling build system for .NET projects.

Installing Rake

We at Cinchcast use the excellent MinGW-based RubyInstaller Ruby distribution for Windows. RubyInstaller comes with a version of Rake installed, but it’s not the most recent major version, so upgrade to the latest Rake fire by running:


$ gem install rake --version '0.9.2'

Linux users probably already have Ruby installed. Try ruby --version to see if you’re running Ruby 1.9. If not, use your package manager like apt-get install ruby to get the latest version.

Mac users can use the RubyOSX distribution of ruby and run the command above for installing the latest version of Rake.

Rakefiles and Rake Tasks

Rakefiles contain Rake Tasks, which define units of work. One task can invoke MSBuild.exe on a .csproj, another can recursively traverse a directory tree and minify Javascript files. Tasks are arbitrary Ruby code, so the sky’s the limit.

Running tasks

Each task can be individually executed on the command like like so:


rake mytask othertask task3

That will execute the tasks named ‘mytask’, ‘othertask’, ‘task3’ which are defined in .\Rakefile.rb (an alternate name may be used and supplied to rake), in order from left to right.

Tasks in Rakefiles

Here’s a sample task definition found in a Rakefile:


desc "Minifies all JS files in the project. loren ipsum dolor sit amet loren\n" +
     "loren ipsum dolor sit amet."
closurecompile :minify_js_working do |cc|
  cc.include_pattern = '.+\.js$'
end

The first line defines a description for the task which enables Rake to display help about your task on the rake command like rake --describe minify_js_working. This is convenient for someone trying to run your Rakefile so they don’t have to open it up in an editor to get descriptions of your tasks. Note the line breaks, task description lines should be optimized for console display, so a line break every 73 characters is a good rule for descriptions.

‘closurecompile’ is the type of task you are defining. In this case, closurecompile is a task type I wrote which is imported into the Rakefile using the ruby ‘require’ statement.

‘:minify_js_working’ is the name of the task. The colon means that it is a Ruby symbol, all rake tasks are named using Ruby symbols. This task would be executed by running ‘rake minify_js_working’ on the command line.

‘do |cc| … end’ do .. end defines a Ruby code block. This code block is executed when the task is executed. You can put any ruby code in this block, which is the power of Rake. But the closurecompile task does all the heavy lifting for us. All we have to do is configure the closurecompile task object.

‘|cc|’ defines one parameter variable ‘cc’ to our block. This reference to the closurecompile task object allows us to configure it in the next statement. The first parameter to any Rake task block is the instance of the task object itself.

‘cc.include_pattern = ‘.+.js$” is where we configure the closurecompile task object.

Task syntax explained

By now you might have noticed that the word ‘task’ is overloaded. Unfortunately, this is a feature of rake lingo. When referring to a ‘task’, you could refer to:

  • A thing that has a name and is executed via the command line, such as the whole code sample above (I’ll call these tasks)
  • Type of task that does something so you don’t have to, such as ClosureCompile used via ‘closurecompile’ above (I’ll call these task types)
  • An instance of a task type that is passed into the task block, such as cc above (I’ll call these task objects)

Now that we’ve got that out of the way, I’ll explain exactly what is happening from a Ruby perspective when you define a task. Here’s the example again:


desc "Minifies all JS files in the project."
closurecompile :minify_js_working do |cc|
  cc.include_pattern = '.+\.js$'
end

Let’s take it apart:

desc "Minifies all JS files in the project."

Passing a string to a method called desc. This desc method registers the description string with the Rake runtime for display when doing rake --describe taskname.

closurecompile :minify_js_working do...end

closurecompile is acually a method. You’re passing the name of the task and the block to execute when the task is run to it. The closurecompile method is defined in a library. It registers with the Rake runtime two things: that a task called minify_js_working exists, and that when this task is executed, Rake shall instantiate a ClosureCompile Task object, pass it to the block given so the Rakefile author can configure it, and then execute the ClosureCompile fun.

Task dependencies


task :print_hello do
  print 'hello '
end

task :print_goodbye do
  print 'goodbye '
end

task :dosomething => [:print_hello, :print_goodbye] do
  print 'doing something'
end

Note that you can define a task using the basic Task task type that does nothing extra for you using ‘task’ like above. Since Task does nothing on its own, there’s no reason to configure the task object, so there’s no block |parameter| after the do.

Executing dosomething executes print_hello, then print_goodbye, then dosomething itself:


$ rake dosomething
hello goodbye doing something
Documenting dependencies

Rake has no built-in mechanism for showing dependencies of tasks with --describe, so we follow this convention:


desc "A useful description for foo.\n" +
     "Dependencies: dep1, dep2"
task :foo => [:dep1, :dep2] do
end
Dependency Syntax details

:dosomething => [:print_hello, :print_goodbye]

This snippet defines a one-element Ruby hash, with the key being the symbol :dosomething, and the value being an array of two symbols: :print_hello, and :print_goodbye.

So we are passing a Ruby hash instead of a name symbol to the ‘task’ method. This works because the dynamic nature of Ruby allows the ‘task’ method (and the methods for any other task type) to inspect the type of the first parameter, and behave differently based on the type:


def task(name_sym) # symbol param means no dependencies
def task({name_sym => [dep_sym,...]}) # hash param means dependencies

Note that a task with only one dependency doesn’t have to use an array:


task :dosomething => :print_hello do
end

Task parameters


task :print_stuff, [:stuff1, :stuff2, :stuff3] do |t, args|
  print args[:stuff1] + "\n"
  print args[:stuff2] + "\n"
  print args[:stuff3]
end

Here’s a sample run of print_stuff:


$ rake print_stuff[1,2,3]
1
2
3

So print_stuff that has three parameters: stuff1, stuff2 and stuff3. The task code accesses the parameters via the block parameter args, which is a hash containing the values passed in via the command line using the taskname[params] syntax.

The values are always strings.

There’s no way to pass parameters by name on the command line. Set up default values and check for empty string like so:


task :print_stuff, [:stuff1, :stuff2, :stuff3] do |t, args|
  stuff1 = args[:stuff1] == "" ? "default1" : args[:stuff1]
  stuff2 = args[:stuff2] == "" ? "default2" : args[:stuff2]
  stuff3 = args[:stuff3] == "" ? "default3" : args[:stuff3]

  print stuff1 + "\n"
  print stuff2 + "\n"
  print stuff3
end

Then you can safely omit parameter values on the command line:


$ rake print_stuff[,,3]
default1
default2
3

You can define a task with both dependencies and parameters:


task :foo, [:arg1, :arg2] => [:task1, :task2] do |t, args|
end
Documenting Parameters

Rake doesn’t provide a built-in way to provide parameter documentation for --describe, so we follow this convention:


desc "foo task description. This is a useful summary.\n" +
     "Param 'p1': Useful p1 description. loren ipsum dolor sit amet loren ipsum\n" +
     "  More p1 useful information.\n" +
     "Param 'p2': Useful p2 description. loren ipsum dolor sit amet loren ipsum\n" +
     "  More p2 useful information."
task :foo do
end

Note the two-space hanging indent for long descriptions.

Parameter Syntax Details

For a task with params:


task :foo, [:arg1, :arg2] do |t, args|
end

We pass two arguments to the ‘task’ method (besides the block): the name symbol and an array containing the name symbols of our arguments.

For a task with params and dependencies:


task :foo, [:arg1, :arg2] => [:task1, :task2] do |t, args|
end

We still pass two arguments, but the second argument isn’t the array of dependency task names, it’s a hash with a key of an array of argument name symbols, and the value is the array of dependency task names that’s passed in alone for a no-dependency task.

We can share the same ‘task’ method with parameterless and parameterized task definitions because ‘task’ is overloaded:


def task(name_sym_or_dep_hash) # Defines parameterless tasks
def task(name_sym, args_definition) # Defines parameterized tasks

We can use the same overload of ‘task’ for parameterized tasks with and without dependencies because the ‘task’ method uses parameter type detection like so:


def task(name_sym, [arg_sym,...]) # 2 param args array
def task(name_sym, {[arg_sym,...] => [dep_sym,...]}) # 2 param args hash

The first overload handles the dependency-less parameterized case, the second handles parameterized tasks with dependencies.

Conclusion

So that’s it for our Rake primer. Hope it helps!

Picture of our new office.

Picture of our new office.

Analyzing Your Site’s Front-End Performance With Just a Browser

by Alex Yampolskiy, CTO
The first rule of optimization is to remember you are not optimizing a website but actually optimizing the user experience. According to the research done by Aberdeen Groupa one second delay in rendering a web page resulted in a 7% decrease of conversions. In order to build web applications that meet your performance criteria, you need to know where the bottlenecks occur, what their causes are, and what steps you can take to prevent them.

In this article, we discuss several online tools that you can use to check the performance of your site and to find out where the bottlenecks are. We do not discuss many excellent tools that need to be downloaded and installed on a computer, such as Apache Benchmark orYSlow plugin. The only thing that’s needed for the tests we describe is a browser and an Internet connection. When comparing functionality of these online tools, we ran them against the same website - CNN news (http://www.cnn.com).

1. PageSpeed (http://pagespeed.googlelabs.com/)
Google Page Speed test generates a score out of a maximum of a 100 for your webpage. It can also analyze performance of the webpage when viewed on mobile devices. Along with the score, PageSpeed generates suggestions of how to improve your site’s performance. I’ve found that PageSpeed often generates a large amount of false positives, so I would take these suggestions with a grain of salt.

2. WebPageTest (http://www.webpagetest.org/)

This is my favorite tool to use. WebPagetest is a tool that was originally developed for internal use by AOL but later open-sourced in 2008. It allows to check performance of your site from various geographical locations, using different browsers (IE7,8,9 and Chrome).


Moreover, it provides an extensive optimization check-list which measures your usage of optimization techniques like caching, use of CDN, compression, etc.
3. Gomez Instant Test (http://www.gomeznetworks.com/custom/instant_test.html)

Gomez provides a free tool to check how long it takes to load your website from various geographical locations. It measures characteristics such as DNS lookup time, connection time, first byte interval, content download, etc. It doesn’t provide any recommendations but it can be used to diagnose front-end bottlenecks.


4. Web Services Analysis (http://www.websiteoptimization.com/services/analyze/)

This is a useful tool which computes total object sizes (for javascript, images, stylesheets, etc.), loading times, and provides recommendations on how you an make your site load faster.


5. Browser Shots (http://browsershots.org/)
Finally, performance may depend on the browser and OS you are using.
This site allows you to check how your website will function when viewed on a variety of browsers and OS platforms. While the Browser Shots site won’t help you analyze the bottlenecks, you will be able to see how large the file size is across various browsers, how long it took to load, and if the site looked corrupted.