Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker
Mike Gehard

Interacting with AWS S3 in ruby…

Mike Gehard
Friday, October 15, 2010

If you are looking for a ruby gem to interact with S3, you may want to choose the S3 gem over the AWS::S3 gem.

The S3 gem seems to be under active development while the AWS::S3 gem gem seems to have gotten a little stale.

I mistakenly chose the AWS::S3 gem gem based on the number of downloads on rubygems.org but it was missing the ability to copy from one S3 bucket to another without having to move the files through my local machine. That will teach me for not reading the source code…

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mike Gehard

Packaging Cucumber step definitions for reuse

Mike Gehard
Monday, September 20, 2010

So I’ve been doing a bunch of BDD development these days using Cucumber as a starting point.

While working with client, the question came up about how they could share step definitions across multiple teams of developers.

I then remembered that the Aruba gem is just that, a collection of Cucumber step definitions.

So if you are looking for a way to start packaging up those step definitions that you have used on multiple projects and are tired of copying across projects, check out how the Aruba gem does it and go from there.

Thanks to the Cucumber and Aruba folks for sharing some very useful technology that allows us all to raise the bar when it comes to delivering quality software.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mike Gehard

Testing Rails3 Generators using Cucumber and Aruba

Mike Gehard
Wednesday, September 15, 2010

In an effort to continue my contributions to the open source Ruby/Rails ecosystem, I decided to help the factory_girl_rails team move the Rails3 generators from the rails3-generators project into the factory_girl_rails project.

Like all good Ruby/Rails developers, they asked to make sure that I had tests written around the generators. I thought for a bit on how I was going to do this and then I wandered across the Cucumber feature files in the rspec-rails repo and found my answer.

Rspec-rails (and RSpec2 as well) uses a gem called Aruba to easily write Cucumber features around things that happen from the command line.

If you’d like to check out the result of using Cucumber and Aruba to test Rails3 generators, head over to my fork of the factory_girl_rails gem and check out the features/generators.feature file.

Hopefully the changes will be merged into the official factory_girl_rails repo soon and the generators will live closer to home.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Sam Coward

Identify memory abusing partials with GC stats

Sam Coward
Monday, September 13, 2010

Recently we had to investigate a page that had very poor performance. The project used newrelic, but neither that, the application’s logs nor render traces gave clear results. The database wasn’t the bottleneck, but there were well over 100 partials in the render trace. These partials seemed to perform well, except sometimes the same partial would take hundreds to thousands of milliseconds.

As it turns out, the cause of these random delays was actually garbage collection triggered by abusive memory consumption within many of the partials – millions of objects and heap growth in excess of 100mb. We discovered this by using the memory and GC statistics features of Ruby Enterprise Edition. You can get an idea of how much memory is being used and garbage collected during rendering by wrapping parts of your page in a block passed to this helper:

def gc_profile
  raise "Dude, you left GC profiling on!" unless Rails.env.development?
  allocated_objects_before = ObjectSpace.allocated_objects
  GC.enable_stats
  GC.clear_stats

  yield if block_given?

  growth = GC.growth
  collections = GC.collections
  time = GC.time
  mallocs = GC.num_allocations
  allocated_objects = ObjectSpace.allocated_objects - allocated_objects_before
  GC.disable_stats

  concat content_tag :span, "GC growth: #{growth}b, collections: #{collections}, time #{time / 1000000.0}sec, #{mallocs} mallocs, #{allocated_objects} objects created."
end

Because there were so many partials on the page, moving the helper around to identify the most egregious memory abusers got tiring so I wrote a monkeypatch to the venerable Rack::Bug plug-in which shows you memory consumption and garbage collection statistics for each template shown in the Rack::Bug template trace, as well as on the memory panel.

Example template trace

Memory panel example

First, install Rack::Bug and make sure it’s working properly, then add the code below in an initializer. Keep in mind this was written to work with Ruby Enterprise Edition 1.8.7 2010.02. Various 1.8 patches and Ruby 1.9 also provide some GC statistics reporting tools which you could probably customize this patch to use instead.

if Rails.env.development?
  require 'rack/bug'

  Rack::Bug::TemplatesPanel::Trace.class_eval do
    alias_method :old_start, :start
    def start(template_name)
      old_start(template_name)
      @initial_allocated_objects = ObjectSpace.allocated_objects
      @initial_allocated_size = GC.allocated_size
      @initial_num_allocations = GC.num_allocations
      @initial_gc_count = GC.collections
      @initial_gc_time = GC.time
    end

    alias_method :old_finished, :finished
    def finished(template_name)
      @current.allocated_objects = ObjectSpace.allocated_objects - @initial_allocated_objects
      @current.allocated_size = GC.allocated_size - @initial_allocated_size
      @current.num_allocations = GC.num_allocations - @initial_num_allocations
      @current.gc_count = GC.collections - @initial_gc_count
      @current.gc_time = (GC.time - @initial_gc_time)/1000.0
      old_finished(template_name)
    end
  end

  Rack::Bug::TemplatesPanel::Rendering.class_eval do
    attr_accessor :allocated_objects
    attr_accessor :allocated_size
    attr_accessor :num_allocations
    attr_accessor :gc_count
    attr_accessor :gc_time

    def memory_summary
      %{<strong>%.2fms</strong><small>in</small><strong>%d</strong><small>GCs</small>
      <strong>%d</strong><small>new objects</small>
      <strong>%d</strong><small>bytes in</small><strong>%d</strong><small>mallocs</small>} % [gc_time, gc_count, allocated_objects, allocated_size, num_allocations]
    end

    def html
      %{<li>
          <p>#{name} (#{time_summary}) [#{memory_summary}]</p>
          #{children_html}
        </li>}
    end
  end

  Rack::Bug::MemoryPanel.class_eval do
    alias_method :old_before, :before
    def before(env)
      old_before(env)
      GC.enable_stats
      GC.clear_stats
      @initial_allocated_objects = ObjectSpace.allocated_objects
      @initial_allocated_size = GC.allocated_size
      @initial_num_allocations = GC.num_allocations
    end

    alias_method :old_after, :after
    def after(env, status, headers, body)
      old_after(env, status, headers, body)
      @gc_count = GC.collections
      @gc_time = GC.time / 1000.0
      @allocated_objects = ObjectSpace.allocated_objects - @initial_allocated_objects
      @allocated_size = GC.allocated_size - @initial_allocated_size
      @num_allocations = GC.num_allocations - @initial_num_allocations
    end

    def heading
      "#{@memory_increase} KB &#916;, #{@total_memory} KB total, %.2fms in #{@gc_count} GCs" % @gc_time
    end

    def has_content?
      true
    end

    def name
      "memory_panel"
    end

    def content
      %{<style>#memory_panel dd { font-size: large; }</style>
        <h3>Garbage Collection Stats</h3>
        <dl>
          <dt>Garbage collection runs</dt>
          <dd>%d</dd>
          <dt>Time spent in GC</dt>
          <dd>%.2fms</dd>
          <dt>Objects created</dt>
          <dd>%d</dd>
          <dt>Bytes allocated</dt>
          <dd>%d</dd>
          <dt>Allocation calls</dt>
          <dd>%d</dd>
      </dl>} % [@gc_count, @gc_time, @allocated_objects, @allocated_size, @num_allocations]
    end
  end
end
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Glenn Jahnke

Standup 9/3/2010

Glenn Jahnke
Friday, September 3, 2010

Help

Server-Side Image Editing

"What's the latest and greatest server-side image processing library people are using?"

Most people quickly agreed that ImageMagick was the way to go.

Data Analysis

"Are there good libraries for data analysis similar to NumPy in Python but for Ruby?"

While there may not be many Ruby libraries that directly comparable to NumPy, there are a fair number of packages to do related work. For instance, you can utilize RSRuby which is a bridge between the R statistical language and Ruby. GnuPlot is another Ruby library that allows both data processing and plotting of graph data.

RSRuby – R / Ruby binding

GnuPlot – Data processing and Plotting

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Glenn Jahnke

Standup 9/1/2010 – Rspec2 + RubyMine and Testing for Class methods

Glenn Jahnke
Wednesday, September 1, 2010

Help

Testing for class methods in Ruby

How do you test for the existence of a class method? Test it using #respond_to?

class Foo
    def self.bar
        puts "Hello, World!"
    end
end

Foo.respond_to?(:bar)
 => true

And to make sure we are really just talking about class methods and not instance methods:

foo = Foo.new

foo.respond_to?(:bar)
 => false

Interesting

RubyMine and Rspec2 Bug Fixed!

We use the latest and greatest RubyMine version available at Pivotal, but sometimes technology choices such as Rails 3 and Rspec 2 are still ahead of it. The formatter that analyzes test output breaks on Rspec 2′s output before any tests run. The bug is further discussed http://youtrack.jetbrains.net/issue/RUBY-6485. Luckily this bug will be fixed in the next EAP release.

Excuting .rvmrc commands and cruisecontrol

We’ve had a difficult time getting .rvmrc files to work with cruisecontrol.rb builds. Specifically, ccrb seems to launch the rake task in the project working directory. This means that the .rvmrc file is ignored. A workaround is to have your CI script directly use RVM or to add “cd .. && cd work” before your project cruise script or rake task.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mike Gehard

Ruby Enumerable and string

Mike Gehard
Friday, August 27, 2010

Did you know that you can call map() and each() on a Ruby string? Do you know how they behave? I hope I’m not the only one that thought they understood it but was proven mistaken.

What would you expect the following code to do?

"hello".map{|char| "Char#{char}"  }

I thought it would return me an array with a bunch of “Char” where x is each letter in “hello”. Nope…it returns:

["Charhello"]

What would you expect the following code to do?

"hello".each{|char| puts "Char#{char}"}

Yeah I thought it would write out a bunch of puts statements “Char” where x is each letter in “hello”. Nope it prints:

Charhello

Ok so maybe my thoughts on strings being enumerable were a little off…I’ve been wrong before and will probably be wrong again.

What really threw me for a loop was that I can access the characters in a string by index:

"hello"[1]

returns

101

which is the ASCII representation of “e”.

So what is the moral of this story? Sometimes things aren’t as the seem at first glance. And sometimes you need to step back, fire up irb and see what really is happening.

Update: Thanks all for the responses below.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Where, oh where has my gem server gone?

Alex Chaffee
Sunday, August 8, 2010

Uh-oh!

ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    bad response Moved Permanently 301 (http://gems.rubyforge.org/latest_specs.4.8)

Whew!

gem sources -a http://rubygems.org/
gem sources -r http://gems.rubyforge.org/

Looks like they weren’t kidding when they said to switch from rubyforge to rubygems.org (née gemcutter)!

[Edited to change "http://production.s3.rubygems.org/" to "http://rubygems.org/". Note that the trailing slash is significant!]

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

monkey patch of the day – activesupport vs. json_pure vs. Ruby 1.8

Alex Chaffee
Sunday, July 25, 2010

The error:

/Library/Ruby/Gems/1.8/gems/json_pure-1.4.3/lib/json/pure/generator.rb:232:in `__send__': undefined method `except' for #<JSON::Pure::Generator::State:0x102f245b0> (NoMethodError)

The environment: Ruby 1.8.7, DataMapper, dm-types, ActiveSupport, or just

require 'json/pure'
require 'active_support'

(as seen in http://gist.github.com/339528)

My solution:

# workaround for activesupport vs. json_pure vs. Ruby 1.8 glitch
if JSON.const_defined?(:Pure)
  class JSON::Pure::Generator::State
    include ActiveSupport::CoreExtensions::Hash::Except
  end
end
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Windowed String Comparison for RSpec

Alex Chaffee
Friday, July 16, 2010

When two strings fail to match, if the difference is somewhere in the middle of the strings, it can be annoying/impossible to track down the
actual difference. I’ve written a little Comparison object that
overrides the failure message for .should == like this:

Strings differ at position 12:
expected: ..."efghijklmnopqrst"...
  actual: ..."efghijklXXopqrst"...

It shows a “prelude” of a few characters, then the difference, lined up on successive lines so they’re easy to visually scan. It also does the right thing (or tries to) if the difference is near the beginning or end of the string (i.e. does or doesn’t show ellipses).

http://gist.github.com/474363

For people who can’t wait for this to get incorporated into RSpec
proper, you can grab the code from github and require "comparison" in your spec_helper.rb and it’ll override the existing RSpec == matcher. Or wait for Issue 9 to be pulled into version 2.1 (maybe). Or if you want to use it in your favorite testing framework, the object is completely self-contained and should be easy to call from your own assert_equals or whatever.

One open question is whether the exception message should show the
full actual string as well as the comparison… On one hand, it adds
to screen clutter, but on the other hand, it can be important in
tracking down the problem, especially if the prelude is ambiguous.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (783)
  • rails (117)
  • testing (90)
  • ruby (85)
  • ruby on rails (71)
  • jobs (62)
  • javascript (59)
  • techtalk (44)
  • ironblogger (42)
  • rspec (39)
  • bloggerdome (34)
  • productivity (34)
  • activerecord (30)
  • rubymine (30)
  • git (29)
  • gogaruco (29)
  • nyc (27)
  • design (24)
  • mobile (23)
  • pivotal tracker (22)
  • process (21)
  • cucumber (21)
  • jasmine (19)
  • ios (18)
  • tracker ecosystem (17)
  • webos (17)
  • objective-c (17)
  • fun (16)
  • android (16)
  • palm (16)
  • ci (16)
  • "soft" ware (16)
  • bdd (15)
  • tdd (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • css (14)
  • gem (13)
  • mouse-free development (12)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • api (12)
  • keyboard (11)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
Subscribe to ruby Feed
  1. ←
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 7
  9. 8
  10. 9
  11. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >