Mike Barinek's blog
Cory Flanigan and Justin Searls are hosting a two day Jasmine workshop very soon in Denver on 9/8 & 9/9 at Uncubed. Details here: http://www.regonline.com/builder/site/Default.aspx?EventId=1004029
The event is non-profit. There's a fee of $120, but it is intended to only cover costs. If proceeds manage to exceed our costs, they'll be donated to charity.
Their objectives are to introduce people to Jasmine, pair on a basic kata, pair on spec'ing some behavior that would involve DOM interactions/jQuery, illustrate patterns for using spies on dependencies and callbacks (like AJAX), and also to spend time working through methods for rigging up Jasmine specs in CI.
In addition, they're inviting everyone who attends to bring some of their own existing JavaScript (especially if it's untested). As time permits on the second day they'd like to mob program on these real-world examples by characterizing legacy JavaScript code with Jasmine and then refactoring with our tests as a safety net.
At Pivotal Labs, one of the services we provide our clients is helping them interview and hire. Pivotal Labs and our clients place a strong emphasis on Agile development and its many aspects: Pair Programming, Test-Driven Development, rapid iterations, and frequent refactoring.
Summary:
We're looking for a brilliant Rails developer to join our star team in Boulder, CO and take the lead on all web development projects. If you want to share your knowledge while learning from others, work smart, and contribute to some awesome projects, we think you'll have a blast with us. As a bonus you'll get to play with robots, games and mobile devices all day long.
Job Description:
- 2+ year experience with the Ruby language and the Rails framework, must have a proficiency with the entire Ruby on Rails stack.
- 4+ years of standards compliant HTML/XHTML, CSS, JavaScript, and JQuery.
- 4+ years of Java, PHP or equivalent platform experience (including related DB experience such as MySQL, PostgreSQL, etc).
- Awesome attitude and fun personality.
- Ability to communicate with both technical and non-technical team members
About Orbotix
Although you are encouraged to send a traditional resume, a resume will not alone won't make you stand out. So along with your resume please send a brief explanation about who you are and why you would be a good fit for Orbotix. Include pictures, videos, or screenshots of your previous projects, both professional and personal. We’re just geeks like you so don’t hold back. Email us… jobs [at] orbotix (dot) com.
Orbotix is a venture backed startup with the vision that you shouldn’t be limited to emailing, getting directions, and playing a game of scrabble on your mobile device. You should be able to just as easily download an app to control all of the physical devices around you. No more remotes. No more clunky interfaces. No more keys. Everything is done with the powerful mobile device that you already carry with you. We’re looking for someone great to join our small but hardcore engineering team to help design and implement our products, starting with Sphero, a powerful robotic entertainment device.
Sure it's a noop test and running on a iMac i7, but 80K requests per second is pretty impressive for 40 lines of code.
package manual;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
public class NoopHandler {
public static void main(String[] args) throws Exception {
QueuedThreadPool pool = new QueuedThreadPool();
pool.setMaxThreads(50);
Server server = new Server();
server.setThreadPool(pool);
server.setGracefulShutdown(1000);
server.setHandler(new AbstractHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setStatus(200);
response.getWriter().write("noop");
baseRequest.setHandled(true);
}
});
server.start();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(8080);
server.addConnector(connector);
connector.start();
}
}
Here's the apache benchmark information.
juniper:~ pivotal$ ab -n10000 -c20 -k http://localhost:8080/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
Server Software: Jetty(7.2.2.v20101205)
Server Hostname: localhost
Server Port: 8080
Document Path: /
Document Length: 4 bytes
Concurrency Level: 20
Time taken for tests: 0.127 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 10000
Total transferred: 980392 bytes
HTML transferred: 40016 bytes
Requests per second: 78840.73 [#/sec] (mean)
Time per request: 0.254 [ms] (mean)
Time per request: 0.013 [ms] (mean, across all concurrent requests)
Transfer rate: 7548.32 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 0 0 0.1 0 3
Waiting: 0 0 0.1 0 3
Total: 0 0 0.1 0 3
Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 0
90% 0
95% 0
98% 0
99% 1
100% 3 (longest request)
I've also been playing around with Mizuno and jruby-rack quite a bit recently. We're hoping to find a high-performing solution for jruby.
As some of you may know, I've been writing a bit of Java in Boulder recently. Overall, it's pretty exciting and a nice change from Ruby.
That being said, I've somewhat isolated our Java development to server-side components. I still consider Ruby/Rails to be the best solution for web application development, although recently had a need for Java.
Anyway, I've been playing around with Avro and I thought I'd share a small example that marshals a domain object to bytes. The bytes are later passed around several queues within application.
package com.barinek.devourer.avro;
import com.barinek.devourer.rest.resources.Activity;
import org.apache.avro.Schema;
import org.apache.avro.file.DataFileWriter;
import org.apache.avro.reflect.ReflectData;
import org.apache.avro.reflect.ReflectDatumWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ReflectMarshaller {
private final Schema schema = ReflectData.get().getSchema(Activity.class);
public byte[] marshal(Activity activity) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ReflectDatumWriter< Activity > reflectDatumWriter = new ReflectDatumWriter< Activity >(schema);
DataFileWriter< Activity > writer = new DataFileWriter< Activity >(reflectDatumWriter).create(schema, outputStream);
writer.append(activity);
writer.close();
return outputStream.toByteArray();
}
}
The interesting bit is that I don't have a .proto file or .json representation of the type. The Activity class is a Plain Old Java Object.
The above snippet is a candidate to replace some proto files, assuming the MicroBenchmark test suite passes.
Look for more Java posts in the near future.
Recently, we have been experimenting with a few new pairing configurations in Boulder, I thought I would share an early photo.

These are 27-inch iMac's paired with 27-inch Apple Cinema Displays.
We've experimented with both side-by-side configurations as well as a variety of angles between 15-90 degrees.
I have to admit, I really like the angled configuration. +1 for not always needing to stretch to see opposite corners of the screen.
Here are a few notes on how to get individual CruiseControl.rb project Builders running with RVM.
[Note: I'm making an assumption here that you know and understand Bundler and RVM.]
[Also: Cruise may or may not be running on RVM]
Create and check in a .rvmrc file in your rails root directory. Here's an example.
rvm ruby-1.8.7-p174@rails-example
Then, add a project build command to your cruise_config.rb file.
Project.configure do |project| project.build_command = './cruise_build.sh' end
Finally, create a cruise_build.sh file. The bash script setups rvm and just calls your cruise control build task.
[Note: Your cruise rake task should probably call Bundler's "bundle install".]
#!/bin/sh source $HOME/.rvm/scripts/rvm && source .rvmrc rake cc:build
...and your cruise project builder is now using RVM!
Inspired by Aaron Patterson at the Mountain.rb Conference, I thought I'd share my favorite programming/software engineering books.
- C Programming Language (2nd Edition) by Brian W. Kernighan and Dennis M. Ritchie (1988)
- Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (1994)
- Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development by Craig Larman (1995)
- Refactoring: Improving the Design of Existing Code by Martin Fowler, Kent Beck, John Brant, and William Opdyke (1999)
- Peopleware: Productive Projects and Teams (Second Edition) by Tom DeMarco and Timothy Lister (1999)
- Extreme Programming Explained: Embrace Change by Kent Beck (1999)
- Effective Java by Joshua Bloch (2001)
- Test Driven Development: By Example by Kent Beck (2002)
- Refactoring to Patterns by Joshua Kerievsky (2004)
- Java Concurrency in Practice by Brian Goetz, Tim Peierls, Joshua Bloch, and Joseph Bowbeer (2006)
- Restful Web Services by Leonard Richardson, Sam Ruby, and David Heinemeier Hansson (2007)
- Getting Real: The smarter, faster, easier way to build a successful web application by Jason Fried, Heinemeier David Hansson, and Matthew Linderman (2009)
If you’re thinking about starting a software project, here’s the recipe that I’ve been giving people.
Have complete visibility into your feature backlog
(i.e. what is happening with your software)
Use a tool like Pivotal Tracker. Have 1 week iterations. Include features, chores, and bugs. Assign points to features. Work should be getting done (i.e. stories should be marked as finished, and you should have a weekly point total). If work isn’t getting done (i.e. point count is low for an iteration), this is a ‘smell’, something might be going wrong. Regularly review and accept the work the developers are doing.
Outsource your infrastructure
- Sign up for an account on GitHub
- Sign up for an account on Heroku, Engine Yard, or Amazon.
- Use Gmail, GoogleApps
Own your source code
Use git. Own your github account and give collaborator access to developers. Developers may move on or off the project, but you’ll always have access to the code base.
Plan for multiple Environments
You should plan for 3 environments, Continuous Integration (CI), Review, and Production. You’ll accept stories in the review environment and push tagged releases to production.
Keep a high Bus Count
Rotate developers through your application feature set. Avoid siloing developers at all costs, “code with a buddy”. Give complete infrastructure access to your developers (DNS, Google Apps/Email, and infrastructure), trust them completely.
Write tests and setup a continuous integration environment
Tests are essential for describing application features and intentions within the code base. Tests are essential for knowledge transfer between developers (it’s unlikely that you’ll have the same developer on the project at all times). Tests give you the confidence to change product direction without breaking or rewriting the entire code base. Without tests, you should quit now. (This is especially true for interpreted languages like ruby). Test drive.
Keep the deployment process nimble
Because you are test driving and have continuous integration, you can deploy at any time. Give your hosting credentials (engine yard, amazon, etc.) to your developers. They should be able to deploy to review or production within minutes (not hours).
Invest in your team
Don’t let bad technology choices effect your startup, there are plenty of risks out there. Find a platform and team that will guarantee minimal technical risk. There’s a huge difference developer skill sets theses days. Find a great team and pay them well. Good software is expensive, build and invest in your development team. Expect this to be your budget and hire generalists.
Recently I've been working on a small spike intended to help jumpstart our Rails application development in the Pivotal Labs Boulder office.
Until Rails 3 was officially released, new projects used the Pivotal "rails-template" to help bootstrap development. The template is really just a GitHub repo that installs dependencies in our Rails 2 project.
There's are few new interesting new features in Rails 3, including a "--builder=" option to the "rails new APP_PATH [options]" command. I thought this might be an interesting solution to bootstrapping an application, especially when your dependencies include Rails generators.
The spike makes a few choices regarding dependencies and testing preferences. For example, we tend to use things like RSpec and Cucumber as well as Cruise.rb, Engine Yard Cloud, and NewRelic. To make life a bit easier, I also used RVM and Gemsets to help set the initial set of dependencies. Even more interesting, I'm able to bootstrap from a GitHub Gist or any directly downloadable file URL.
Initial Setup
For everything to work without a hitch, I have both a local .rvmrc file and Bundler Gemfile within my ~/workspace/mahan directory with the below Gems installed.
[Note: I'm making an assumption here that you know and understand Bundler and RVM]
Here's the .rvmrc file I used within the ~/workspace/mahan directory.
rvm_archflags="-arch x86_64" rvm 1.8.7-p174@mahan
And here's a few commands to get you started.
$ cd workspace/ $ mkdir mahan $ cd mahan/ $ vi .rvmrc rvm_archflags="-arch x86_64" nrvm 1.8.7-p174@mahan"
Also, here's the Gemfile I used within the ~/workspace/mahan directory.
You'll need to run "gem install bundler --version 1.0" from this directory and then run "bundle install".
source 'http://rubygems.org' gem 'rails', '3.0.0' gem 'mysql2' gem "rspec-rails", '2.0.0.beta.22' gem "rspec", '2.0.0.beta.22' gem 'capybara', '0.3.9' gem 'database_cleaner', '0.5.2' gem 'cucumber-rails', '0.3.2' gem 'cucumber', '0.9.0' gem 'rspec-rails', '2.0.0.beta.22' gem 'spork', '0.8.4' gem 'launchy', '0.3.7' gem 'jasmine', :submodules => true gem 'json_pure', '1.4.6'
Agin, a few commands to get you started.
$ cd ~/workspace/mahan/ $ rvm gemset create 'mahan' $ rvm gemset use mahan $ gem install bundler --version 1.0 $ vi Gemfile [Add the above Gemfile contents] $ bundle install
Rails Builder
Next, I'll dive right into the Rails command. From your ~/workspace/mahan directory run
rails new rails_example --builder=http://gist.github.com/611035.txt
The command creates a new Rails 3 application with our default set of dependencies.
Feel free to take a look at the actual Gist. You'll notice that I extend "class AppBuilder < Rails::AppBuilder". If you're interested in the Rails guts, take a look around line 316 in railties-3.0.0/lib/rails/generators/rails/app/app_generator.rb. The Rails AppGenerator looks for custom builders and then performs an instance_eval on the file.
You'll also notice that I "override" the test method within my custom AppBuilder to include RSpec, Cucumber, and Jasmine. The actual method then call the associated Rails install generator. And yes, you'll notice we're working on the Jasmine Rails 3 support.
def test append_test_gems rspec cucumber jasmine end
I also override the "leftovers" method to include things like Cruise.rb, Engine Yard Cloud, and NewRelic dependencies and configurations. The "leftovers" method gets call from the AppGenerator "finish_template" method. With a few of the "leftovers", I simply pull the from the associated GitHub repo and copy the necessary files and/or directories.
I've also experiment with a Gem that includes a Thor wrapper around a custom Rails AppGenerator. The benefit for this approach is that now I'm now able include my own custom Rails options. For example
class PivotalAppGenerator < Rails::Generators::AppGenerator
include Thor::Shell
source_root File.expand_path('../templates', __FILE__)
class_option :skip_rspec, :type => :boolean, :aliases => "-R", :default => false, :desc => "Skip rspec"
class_option :skip_cucumber, :type => :boolean, :aliases => "-C", :default => false, :desc => "Skip cucumber"
class_option :skip_jasmine, :type => :boolean, :aliases => "-J", :default => false, :desc => "Skip jasmine"
We'll probably use a combination of the AppBuilder and AppGenerator approach, although at this time I thought some feedback would be interesting.
We've recently scoped several projects in Boulder. While scoping, several clients asked how we're able to estimate a project's cost with such confidence. I've thought about this a bit and I actually think this is pretty interesting and remarkably similar to something we've all been doing for a while: estimating user stories in Tracker.
Scoping a project is very similar to determining the number of points or weight you might assign to a user story or feature in an Agile backlog. Similar to measuring the relative size or complexity of a feature, we're just measuring the relative size or complexity of the project against similar projects that we've completed. The important piece here is that we're measuring against completed projects.
With stories or features you estimate size and then derive duration in order to achieve a running feature velocity. Feature velocity is essential and the key to predictability. Completing features and measuring their associated duration is the empirical data we use to determine when a future set of stories will be completed or delivered. When scoping a project we're missing this empirical data, although we still need to actually provide a duration to calculate the project's cost. So how do we estimate a project's scope and cost?
Imagine estimating a feature that you just completed for another project. You'd probably be pretty close on the points assignment as well as confidence. Now apply this to a project. It's becomes easier to scope a project when you've completed a few similar projects. The more projects the better the comparison and resultant estimate.
Completed projects are valuable because we know how long they took to complete. For example, client A's CRM was roughly 1 pair for 2 months. Client B's CRM required 2 pairs for 4 months. And client C's CRM, the one we're currently estimating, is slightly more complex than client A's although much less complex than client B's. We'll likely estimate client C's CRM at 2 pairs for 2 months.
It's actually not all gravy. There are several risks that may increase a project's scope. For example, if we're up against an aggressive timeline, we may include an additional pair for a few weeks to help increase feature velocity. Similarly, if there are complex integrations, like a 3rd party billing system or external messaging subsystems, we may include an additional pair for a month.
During an initial scoping we help reveal or tease out high level risks and then prioritize theses risks against constraints like timeline and budget. The more similar the risks we've resolved on completed projects, the more confidence we have to estimate risks during a new project scoping. Again, pretty similar to how we estimate features in a backlog. We're just estimating the size or complexity of risks against similar risks with known durations.
