Josh SusserJosh Susser
Becoming more flexible
edit Posted by Josh Susser on Wednesday July 01, 2009 at 02:32PM

Our friends at Engine Yard have just launched the beta of their new cloud hosting product, Flex. If you're familiar with their Solo product you'll find Flex to be pretty similar, just more... flexible. Where solo lets you run your Ruby on Rails application on an Engine Yard stack on an Amazon EC2 instance, Flex lets you run it on a cluster of EC2 instances.

In the last month I've put a handful of applications up on Solo, mostly demo or staging servers for doing story acceptance and release testing. Solo is great for that. After you've gone through the setup process once, you can easily spool up a server for a few hours when you need it on just a few minutes notice, then turn it off when it's not needed anymore. Flex gives you that same kind of adaptability, allowing you to add instances to your cluster to match traffic demands as needed.

Last week I got my first production application running on Flex. The Pivotal Labs company website is now hosted on Flex, and it's humming along quite nicely. There were a few rough spots to work through since we were working with a pre-release product, but I'm pretty happy with our setup now. Since Flex is new, I thought it might be useful to share some of the things my fellow pivots and I learned getting things running there.

Parker ThompsonParker Thompson
Need a Job? Come Work With Pivotal Clients
edit Posted by Parker Thompson on Wednesday July 01, 2009 at 10:12AM

At Pivotal Labs, one of the services we provide is bootstrapping startups, including helping them interview and hire. We currently have clients looking for skilled engineers to build their development teams. This is an excellent opportunity to learn Extreme Programming by working side-by-side with Pivotal's talented and experienced developers while at the same time getting in on the ground floor of a small and dynamic product team.

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. General technical requirements include serious web development experience, and a significant subset of Ruby, Rails, CSS, JavaScript, or MySQL.

Here's a short description of ekoVenture, oneforty, Honk, and Mavenlink, Pivotal Labs clients currently looking for developers. Their full job postings follow at the end of this post.

ekoVenture is the world’s first social marketplace for adventure, experiential and active travel, a $250 billion market. Utilizing the best social networking technology on the web, we allow users to share their travel experiences, meet other travelers, and book trips online in real-time. Our revolutionary marketplace also features a comprehensive inventory management backend platform for tour suppliers, enabling them to manage their entire business and sell trips or drive leads directly online – this is already implemented across 500 tour suppliers…and adding several each day.

oneforty is a Twitter ecosystem/API venture with considerable traction. oneforty comes with all the excitement and opportunity of a Techstars startup backed by talented and successful investors/advisers who have built some of the best known companies on the web. The founder authored Twitter for Dummies and does tons of press and public speaking and the investors and advisors include Guy Kawasaki, Laura Rippy, Jeff Bennett and many others. oneforty has closed their angel round and is looking for RoR developers fired up about building something that will be highly visible and well-promoted.

Mavenlink is a funded startup that is changing the way people find experts who can help them and is providing the necessary tools to get their work done online. We are founded on the principle that virtually everybody needs qualified professional services that are readily accessible, affordable, and there when they need them. We’ve been working with Pivotal Labs to get our product launched, so we’re serious about being agile and we’ve got the right engineering process in place. This is a unique opportunity to join the Mavenlink team and contribute significantly to the direction of the company. We're looking for someone who is not only passionate about development, but also shares our vision for the tools and capabilities necessary for making remote work better than working in person for both the client and the maven.

Honk.com is a new online automotive website that will make car shopping fun and social. We will enable consumers to experience a new way to explore new cars. We have partnered with a top social website to deliver this new way of car shopping and are funded by one of the largest media companies in the world. Our small team is made up of an experienced group of humble, efficient, and hyper-passionate individuals who are veterans of the automotive industry and social media space. We are proud of our ego-less culture, one that promotes team thinking, not individual accolades. If you're interested in helping prove that social media and car buying go hand in hand, social networks serve a bigger purpose than keeping up with one's day, and a small team can outdo the work of an army - then we may have a seat waiting for you.

If you are interested or for more information please contact each company directly. This is an exclusive service provided to our clients, no external companies or recruiters please.

Full job postings follow.

Interesting Things

Help

"How do you permanently remove a git tag?"

  • One team would like a delete a tag created by their CI, but it keeps coming back if somebody who has pulled the tag locally does a push.

Jeff DeanJeff Dean
Equality and sameness in Ruby
edit Posted by Jeff Dean on Monday June 29, 2009 at 06:43AM

Let's say you are building a leetspeak that deals with w00ts. You might write a class that looks like this:

class Woot
  def ==(other)
    true
  end
end

In theory, any Woot is equal to anything else:

puts Woot.new == Woot.new # true

You might think that with this setup, you could do something like this:

x = [ Woot.new ]
y = [ Woot.new ]
z = x - y

You might expect z to be an empty array in the case, but oh how wrong you would be. In the example above, the == is never called at all.

Joe MooreJoe Moore
Standup 06/26/2009: Poor ScrewUnit...
edit Posted by Joe Moore on Friday June 26, 2009 at 01:45PM
  • JQuery Events/live + ScrewUnit = :-(. ScrewUnit swaps the DOM "out from under" the elements that Events/live is watching, which messes with ScrewUnit. Call die on the DOM elements that live events are watching.

  • ScrewUnit + CI + IE = :'-( Also, When ScrewUnit suites become large, they trigger IE's "slow script" warning, which can freeze your continuous integration build. Check out the Registry Hack to set your own timeout.

  • We have a fan of Thor in the house: "Map options to a class. Simply create a class with the appropriate annotations, and have options automatically map to functions and parameters." Which, as is (not) obvious, indicates that Thor is a replacement for rake.

Steve ConoverSteve Conover
Automated Configuration @ Velocity 2009
edit Posted by Steve Conover on Friday June 26, 2009 at 08:05AM

Theo Schlossnagle: "I don't care what you use: puppet, chef, bcfg2, cfengine - choose one and automate your configuration." (Theo's presentation was a highlight, check out the slides here.)

Allspaw and Hammond from Flickr: "If there's only one thing you do, automate your infrastructure."

There were lots of Puppet users at the conference, and Luke Kaines gave a good talk on it.

Interested in a Chef intro? Watch the video of Adam and Ezra's talk:

From the Chef BoF:

  • If you're just doing application deployment of a typical webapp then running chef-solo on deploy might be just fine for you (it is for the Remix team).
    • Ezra points out that he has a chef subproject on git that even strips out cap - chef-deploy (vs cap sudo'ing out to chef).
  • Adam gave a good explanation of the Chef run model.
    • It's important to understand the basics of what's going on behind the scenes - otherwise you'll shell out right in the middle of your Chef scripts and be surprised by the run order.
    • In short, all your Chef Resource statements are evaluated in a first pass. Then they're executed.
    • This gives Chef the opportunity to evaluate what's to be done and optimize. Adam noted that included recipes are only executed once (analogous to ruby require's)
    • Adam also mentioned something kind of cool - if I have this right - Resource statements return the associated Resource object. And when you refer to the Resource the same way twice, you're getting back the same Resource instance. So your included Recipes (for example) each have the opportunity to decorate a Resource defined earlier - if, say, it ought to be configured differently based on a combination of what else is getting installed on the box. Nice.

Steve ConoverSteve Conover
Flickr "10+ Deploys Per Day" @ Velocity 2009
edit Posted by Steve Conover on Thursday June 25, 2009 at 04:00PM

My favorite talk at Velocity was by Paul Hammond and John Allspaw from Flickr, who are doing real lowercase-a agile:

UPDATE

Here's the video, highly recommended:

"If there's one thing you do, it should be automated infrastructure". This was a refrain through the conference - as Theo Schlossnagle put it, it doesn't matter if it's chef, puppet, bcfg2, cfengine - whatever works for you, just do it.

Some of their techniques:

  • One-step build. They literally go to a web page and click a button and watch the build take the full site from soup to nuts.
  • Deploys: Who. What. When. You want to make all the meta-details of a deploy easily visible to anyone. Deploy logs are readily accessible.
  • Always ship trunk. In a webapp this is possible. It vastly simplifies - everyone knows where to look for what's going out, and what's live.
    • Flickr does their branching in the code (take note git people), and these become natural ops levers (i.e. uh-oh turn that feature off / turn it down).
  • "Dark launches". Facebook does this too: launch the guts of a new feature with the UI turned off so you can see how the technology works in real production.
    • Which results in anticlimactic launches, the best kind
  • They roll forward (not back) to turn features off that aren't working.
  • "Gather shitloads of metrics". System metrics, app metrics, everything. John has a great writeup on their Ganglia setup in his book.
    • Developers watch the metrics just as obsessively as ops. Visualization is a powerful tool used day-to-day by the whole group.
    • Developers have a way of putting in their own metrics via a little framework.
  • They're all on IRC. This kept coming up at the conference - teams are on some chat tool like IRC, Skype chat LINK, or Campfire LINK.
    • Important events are piped into IRC, so you'll be right in the middle of a conversation and an alert will pop in.
  • Logs are piped into a search engine so they can find things in the log history, easily.

Culture, philosophy:

  • There's an ongoing conversation between dev and ops. They're learning to solve the Flickr problem together. Each side's way of thinking informs the other (major conference theme as well)
  • Failure will happen. Develop your ability to respond. Like ER doctors you practice on failures, that makes you better/competent at handling what comes along next.
  • In addition to the ops people on call, there's always a developer who has a pager

More:

Joe MooreJoe Moore
Standup 06/25/2009: return vs. next vs. break vs. yslow vs. cap
edit Posted by Joe Moore on Thursday June 25, 2009 at 01:40PM

Interesting Things

  • You can never return: ... except when you can. From a block, that is. Returning from a block rarely works:

    result = ['one', 'two'].each do |x|
     return x
    end
    => LocalJumpError: unexpected return
    

    But, you can pass next and break arguments, which will allow you to assign return values from the block:

    result = ['one', 'two'].each do |x|
      break(x)
    end
    => "one"
    
    
    result = ['one', 'two'].each do |x|
      next(x)
    end
    => ["one", "two"]
    

You can return from a lambda, though.

  • Check out Google Page Speed, which is like Yahoo's YSlow, only "better."

    Page Speed is an open-source Firefox/Firebug Add-on. Webmasters and web developers can use Page Speed to evaluate the performance of their web pages and to get suggestions on how to improve them.

  • Like chef? Love capistrano? Check out chef-deploy, which "... Uses the same directory layout as capistrano and steals the git remote cached deploy strategy from cap and adapts it to work without cap and under chef."

  • SFTUG FTW! Another successful SF Tracker User Group Meetup on 06/24. Watch for future events on the Meetup site.

Zach BrockZach Brock
An easy way to write named scope tests
edit Posted by Zach Brock on Thursday June 25, 2009 at 03:12AM

The project I'm working on has a lot of named scopes which are really great. If you're not using them already you should really try them out. Since we test drive everything we do, we needed a really easy way to write tests for all these named scopes. We came up with a little test helper method that I thought I'd share so that other people could use it.

Here's the code:

def test_named_scope(all_objects, subset, condition)
  subset.should_not be_empty
  subset.each do |obj|
    condition.call(obj).should be_true
  end

  other_objects = all_objects - subset
  other_objects.should_not be_empty
  other_objects.each do |obj|
    condition.call(obj).should be_false
  end
end

To use it, just pass a superset of objects, the subset you want to test and then a lambda as a condition. The lambda should be true for all items in the subset and false for all the items outside of it.

It sounds complicated but it's really easy! Here's an example Let's look at a simple tag class that has a status column indicating whether the tag is on a whitelist or a blacklist. It could look like this.

class Tag < ActiveRecord::Base
   WHITELISTED = 1
   BLACKLISTED = 0
 end

We want to be able to easily grab all the whitelisted tags, so we need to add a named scope.

Here's the spec we write first:

describe Tag do
    describe "whitelisted named_scope" do
      it "returns the whitelisted tags" do
        test_named_scope(Tag.all, Tag.whitelisted, lambda{|tag|
                                     tag.status == Tag::WHITELISTED })
      end
    end
  end
end

We run the spec, watch it fail and then go add the named scope to our Tag class.

class Tag < ActiveRecord::Base
  WHITELISTED = 1
  BLACKLISTED = 0
  named_scope :whitelisted, :conditions => {:status => WHITELISTED}
end

Then we just rerun the spec and watch it pass. Easy!

Update: Josh Susser emailed me a really nice refactoring with the enumerable partition method

def test_named_scope(all_objects, subset, condition)
  scoped_objects, other_objects = all_objects.partition(&condition)
  scoped_objects.should == subset
  other_objects.should == all_objects - subset
end

Joe MooreJoe Moore
Standup 06/24/2009: Nginx URL Rewrite Fu?
edit Posted by Joe Moore on Wednesday June 24, 2009 at 03:34PM

Ask for Help

"Does anyone have Nginx URL rewriting fu?"

The pretty documentation is actually quite hard to work with. Does anyone else have a good reference?

Interesting Things

Some developers who were granted early access to Palm's new operating system said it was worth the wait. "We find it's the easiest one to develop for," said Christian Sepulveda, vice president for business development at Pivotal Labs. "It allows for a richer experience, like having a pop-up menu and background processing, which is helpful."

Mr. Sepulveda's company developed four of the first programs available for download through Palm’s app store, including an item for Twitter called Tweed.

Other articles: