<?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>Tender Lovemaking &#187; Aaron Patterson</title>
	<atom:link href="http://tenderlovemaking.com/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://tenderlovemaking.com</link>
	<description>The act of making love, tenderly.</description>
	<lastBuildDate>Thu, 16 Feb 2012 17:10:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Ten Years of Nerd Club</title>
		<link>http://tenderlovemaking.com/2012/02/16/ten-years-of-nerd-club/</link>
		<comments>http://tenderlovemaking.com/2012/02/16/ten-years-of-nerd-club/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 17:10:43 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=594</guid>
		<description><![CDATA[The Seattle Ruby Brigade, (the first Ruby Bridage), is having a party to celebrating it&#8217;s 10th anniversary, and you should attend! The party will be held February 28th from 7 to 10pm at the offices of &#8230; <a class="more-link" href="http://tenderlovemaking.com/2012/02/16/ten-years-of-nerd-club/">More<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.seattlerb.org/">Seattle Ruby Brigade</a>, (<a href="http://www.oreillynet.com/ruby/blog/2006/02/the_power_of_ruby_brigades.html">the first Ruby Bridage</a>), is having a party to celebrating it&#8217;s 10th anniversary, and you should attend!  The party will be held February 28th from 7 to 10pm at the offices of <a href="http://substantial.com/">Substantial</a> (thanks Substantial!!!)  Tickets are $10 and you can get them <a href="http://rubybrigade10-zvents.eventbrite.com/">here</a>.</p>
<p>If you would like to learn more about the history of nerd club, check out <a href="http://www.youtube.com/watch?v=ICVdf4WidkY">this talk I gave in 2008</a>.  You can find the accompanying slides <a href="http://tenderlovemaking.com/seattlerb_history.pdf">here</a>.</p>
<p>Here&#8217;s to another 10 years of nerd clubbing!</p>
<p><img src="http://i.imgur.com/bqtSz.jpg" /></p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2012/02/16/ten-years-of-nerd-club/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>My Jerky Setup</title>
		<link>http://tenderlovemaking.com/2012/01/14/my-jerky-setup/</link>
		<comments>http://tenderlovemaking.com/2012/01/14/my-jerky-setup/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 04:36:11 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=584</guid>
		<description><![CDATA[I love making beef jerky. I started making jerky by using Alton Brown&#8217;s recipe, but I found his jerky making apparatus to be lacking in a few key areas, so I put together my own jerky &#8230; <a class="more-link" href="http://tenderlovemaking.com/2012/01/14/my-jerky-setup/">More<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I love making beef jerky.  I started making jerky by using <a href="http://www.foodnetwork.com/recipes/alton-brown/beef-jerky-recipe/index.html">Alton Brown&#8217;s recipe</a>, but I found his jerky making apparatus to be lacking in a few key areas, so I put together my own jerky making setup.  I use a modified food dehydrator for making my jerky.  I prefer using a food dehydrator because it&#8217;s easy to clean, efficient at circulating air, and easily adjustable to accommodate larger or smaller batches of meat.  Jerky is supposed to be air dried with no heat.  Drying with no heat required modification of my dehydrator.  I would like to share my modification process with you!</p>
<h2>Getting started</h2>
<p>I use a <a href="http://www.amazon.com/Nesco-American-FD-61-Snackmaster-Dehydrator/dp/B000CEM3WM/">Nesco American Harvest dehydrator</a>.  I found mine on sale for about $50, but it looks like the going rate on Amazon is about $65.</p>
<p class="center"><a href="http://www.flickr.com/photos/aaronp/6698737915/" title="Untitled by tenderlovemaking, on Flickr"><img src="http://farm8.staticflickr.com/7030/6698737915_e59e7cdb28.jpg" width="500" height="333" alt=""></a></p>
<p>I like this dryer because the fan is on top, it&#8217;s easy to clean, and you can buy and use extra trays.  I <em>think</em> it goes up to 10 or 15 trays, but I only have 8.</p>
<h2>Step 1: Remove the top nob</h2>
<p>In order to disconnect the heating element, we must remove the plastic bar that goes across the top of the fan.  The first step is to remove the knob:</p>
<p class="center"><a href="http://www.flickr.com/photos/aaronp/6698738965/" title="Untitled by tenderlovemaking, on Flickr"><img src="http://farm8.staticflickr.com/7018/6698738965_a5706861f0.jpg" width="500" height="333" alt=""></a></p>
<p>Just pull the knob straight up, and it should come off:</p>
<p class="center"><a href="http://www.flickr.com/photos/aaronp/6698739275/" title="Untitled by tenderlovemaking, on Flickr"><img src="http://farm8.staticflickr.com/7020/6698739275_7bf6706481.jpg" width="500" height="333" alt=""></a></p>
<h2>Step 2: Disconnect the bar</h2>
<p>Flip the lid over.  There should be four screws outside the ring.  Remove just those four screws:</p>
<p class="center"><a href="http://www.flickr.com/photos/aaronp/6698857775/" title="6698739611_b6f1428b08_o-1 by tenderlovemaking, on Flickr"><img src="http://farm8.staticflickr.com/7169/6698857775_43f5a278d0.jpg" width="500" height="333" alt="6698739611_b6f1428b08_o-1"></a></p>
<p>Flip the lid back over, and you should be able to remove the center plastic bar with the Nesco logo on it:</p>
<p class="center"><a href="http://www.flickr.com/photos/aaronp/6698740643/" title="Untitled by tenderlovemaking, on Flickr"><img src="http://farm8.staticflickr.com/7025/6698740643_85210904cc.jpg" width="500" height="333" alt=""></a></p>
<h2>Step 3: Disconnect the heater</h2>
<p>These two leads go to the potentiometer that controls the heater:</p>
<p class="center"><a href="http://www.flickr.com/photos/aaronp/6698741363/" title="Untitled by tenderlovemaking, on Flickr"><img src="http://farm8.staticflickr.com/7009/6698741363_5c7e7e3793.jpg" width="500" height="333" alt=""></a></p>
<p>Disconnect one.  The circuit will open, and the heater disabled:</p>
<p class="center"><a href="http://www.flickr.com/photos/aaronp/6698741689/" title="Untitled by tenderlovemaking, on Flickr"><img src="http://farm8.staticflickr.com/7018/6698741689_c09e2ecab2.jpg" width="500" height="333" alt=""></a></p>
<p>I taped mine down with electrical tape:</p>
<p class="center"><a href="http://www.flickr.com/photos/aaronp/6698742407/" title="Untitled by tenderlovemaking, on Flickr"><img src="http://farm8.staticflickr.com/7031/6698742407_094810fe9d.jpg" width="500" height="333" alt=""></a></p>
<h2>That&#8217;s it!</h2>
<p>Just follow the steps backwards to reassemble your dryer.  The electrically inclined may want to enhance their dryer with a switch.  I (on the other hand) am lazy.  I bought a second dryer so that I could make jerky and do normal food dehydrating at the same time.</p>
<p>You can see more pictures of the process <a href="http://www.flickr.com/photos/aaronp/sets/72157628873907505/with/6698857775/">here</a>.  I plan to write a follow up post where I actually make jerky.  Yum!</p>
<p class="center"><a href="http://www.flickr.com/photos/aaronp/6698747215/" title="Untitled by tenderlovemaking, on Flickr"><img src="http://farm8.staticflickr.com/7170/6698747215_7ae9dd0118.jpg" width="500" height="333" alt=""></a></p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2012/01/14/my-jerky-setup/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Profiling Rails startup with DTrace</title>
		<link>http://tenderlovemaking.com/2011/12/05/profiling-rails-startup-with-dtrace/</link>
		<comments>http://tenderlovemaking.com/2011/12/05/profiling-rails-startup-with-dtrace/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 20:07:12 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=578</guid>
		<description><![CDATA[TL;DR: I&#8217;m adding DTrace probes to Ruby, and I used those to make a 6% performance improvement to rake environment. Lately I&#8217;ve been working on adding DTrace probes to Ruby 2.0. I am interested in using &#8230; <a class="more-link" href="http://tenderlovemaking.com/2011/12/05/profiling-rails-startup-with-dtrace/">More<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>TL;DR: I&#8217;m adding DTrace probes to Ruby, and I used those to make a 6% performance improvement to <code>rake environment</code>.</strong></p>
<p>Lately I&#8217;ve been working on adding DTrace probes to Ruby 2.0.  I am interested in using them to profile and improve rails startup time.  Today I want to look at building a profiler with DTrace, finding slow method calls, and making some incremental improvements.</p>
<p>The examples I&#8217;m going to show will only work on systems where DTrace is available, and with either stock Apple MRI 1.8.7, or my special fork of Ruby.  Likely you don&#8217;t have my fork, so if you&#8217;d like to play along, you&#8217;ll have to use Apple&#8217;s Ruby 1.8.7.  I&#8217;ve published my branch <a href="https://github.com/tenderlove/ruby-1/tree/probes">here</a>, but I will be adding and moving probes, so please don&#8217;t depend on it.  Eventually it will be merged to ruby trunk (hopefully).</p>
<p>All of these examples will be executing in the context of a Rails application built from Rails master.</p>
<h2>What to profile?</h2>
<p>It&#8217;s easy to say that application boot time is not important.  When we start our applications in production, they are only booted once, so the cost is only paid once.  But as an application developer, the &#8220;boot once&#8221; argument doesn&#8217;t hold water.  Every time we run a rake task, we boot the app.  Every time we run tests, we boot the app.  Every time we run migrations, we boot the app.  Every time we restart our webserver, we boot the app.  In the context of application development, class reloading helps to some extent, but not when someone runs <code>rake test</code>.</p>
<p>There are <a href="http://confreaks.net/videos/641-gogaruco2011-fast-rails-tests">good efforts</a> surrounding the improvement of Rails test speeds, but I would like to suggest that these are just working around a larger problem: booting Rails is slow.  If we can make Rails boot times fast, I think it would eliminate the need for <a href="https://www.destroyallsoftware.com/screencasts/catalog/fast-tests-with-and-without-rails">testing outside the rails context</a>.</p>
<p>So where do we start?  Typically, we begin at the beginning.  Today we&#8217;ll start profiling the <code>rake environment</code> command.  This task simply requires all of the files for your application, readying everything for execution against a Rails context.  Many things can impact the startup time of our application: file parse time, method call time, GC, etc.  Today we&#8217;re going to focus on slow methods, and using DTrace to find those methods.</p>
<h2>Viewing method calls</h2>
<p>The DTrace probes in Ruby allow us to detect when method calls are made.  We can tell when Ruby enters a method by watching the <code>function-entry</code> probe.  This probe is given:</p>
<ul>
<li>recipient class name</li>
<li>method name</li>
<li>file name and line number of the call site</li>
</ul>
<p>Here is an example DTrace script that prints out all of this information each time a <code>function-entry</code> probe is activated:</p>
<pre><code>ruby*:::function-entry
{
  printf("-> %s::%s (%s:%d)\n", copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3);
}
</code></pre>
<p>Save this to a file, and run the file along with <code>rake environment</code> like so:</p>
<pre><code>$ sudo dtrace -q -s calls.d -c'rake environment'
</code></pre>
<p>You&#8217;ll see all of the method call entries, and what file and line made the call.  Here is a sample of the output:</p>
<pre><code>-> Module::local_constant_names (/Users/aaron/git/rails/activesupport/lib/active_support/core_ext/module/introspection.rb:85)
-> Module::local_constants (/Users/aaron/git/rails/activesupport/lib/active_support/core_ext/module/introspection.rb:78)
-> Module::constants (/Users/aaron/git/rails/activesupport/lib/active_support/core_ext/module/introspection.rb:79)
-> Array::map (/Users/aaron/git/rails/activesupport/lib/active_support/core_ext/module/introspection.rb:86)
-> Symbol::to_s (/Users/aaron/git/rails/activesupport/lib/active_support/core_ext/module/introspection.rb:86)
</code></pre>
<h2>Counting method calls</h2>
<p>We were able to see all of the method calls, but this doesn&#8217;t give us a good understanding of where the program is spending time.  Instead of just viewing method calls, let&#8217;s use the aggregation functionality in DTrace to count the number of times a method is called.  To do this, we use <code>@</code> variables in DTrace.  <code>@</code> variables are known as &#8220;aggregation variables&#8221; and let us, well, aggregate things.</p>
<p>Aggregate variables are associative arrays that allow arbitrary keys.  We can modify our DTrace program to aggregate the count of the recipient class name and method name pairs like so:</p>
<pre><code>ruby*:::function-entry
{
  @[copyinstr(arg0), copyinstr(arg1)] = count();
}
</code></pre>
<p>When the program finishes executing, DTrace will automatically output the aggregate variable.  Running the program yields this output (I&#8217;ve truncated the output to the last 10 lines or so):</p>
<pre><code>$ sudo dtrace -q -s calls.d -c'rake environment'

  Class                 core#define_method           6332
  Symbol                ==                           6612
  Module                method_added                 9329
  Kernel                hash                         9437
  Array                 hash                        11966
  Array                 each                        13101
  Fixnum                ^                           15540
  Module                ===                         20267
  String                hash                        37878
  Symbol                to_s                       214691
$
</code></pre>
<p>Great!  We can see that when <code>rake environment</code> is run, we&#8217;re calling <code>Symbol#to_s</code> over 200,000 times.  Certainly this will put a burden on the Garbage Collector.  If we change our program to aggregate by class, method, and call site, we can find out <em>who</em> is making so many calls.  Let&#8217;s modify the program to add file and line number information:</p>
<pre><code>ruby*:::function-entry
{
  @[copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3] = count();
}
</code></pre>
<p>Rerun the program, and we&#8217;ll see output like this (again I&#8217;ve truncated the output):</p>
<pre><code>$ sudo dtrace -q -s calls.d -c'rake environment'

  Gem::Dependency        requirement           /Users/aaron/.local/lib/ruby/1.9.1/rubygems/dependency.rb               98             4641
  Array                  hash                  /Users/aaron/.local/lib/ruby/1.9.1/rubygems/specification.rb             1308             4697
  Bundler::DepProxy      method_missing        /Users/aaron/.local/lib/ruby/gems/1.9.1/gems/bundler-1.0.21/lib/bundler/rubygems_ext.rb              194             4809
  BasicObject            ==                    /Users/aaron/.local/lib/ruby/1.9.1/rubygems/specification.rb             1334             5610
  Kernel                 ===                   /Users/aaron/.local/lib/ruby/1.9.1/rubygems/specification.rb             1334             5610
  Module                 ===                   /Users/aaron/.local/lib/ruby/1.9.1/rubygems/specification.rb             1334             5940
  Array                  hash                  /Users/aaron/.local/lib/ruby/1.9.1/rubygems/requirement.rb              135             6001
  Fixnum                 ^                     /Users/aaron/.local/lib/ruby/1.9.1/rubygems/specification.rb             1308            11078
  String                 hash                  /Users/aaron/.local/lib/ruby/1.9.1/rubygems/specification.rb             1308            31209
  Symbol                 to_s                  /Users/aaron/git/rails/activesupport/lib/active_support/core_ext/module/introspection.rb               86           208900
$
</code></pre>
<p>This shows us that <a href="https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/module/introspection.rb#L86"><code>introspection.rb</code> line 86</a> is calling <code>Symbol#to_s</code> over 208k times.  If we take a look at that method, we&#8217;ll see that on 1.9 it will call <code>Symbol#to_s</code> many times:</p>
<pre class="brush: ruby; title: ; notranslate">
def local_constants #:nodoc:
  constants(false)
end

# Returns the names of the constants defined locally rather than the
# constants themselves. See &lt;tt&gt;local_constants&lt;/tt&gt;;.
def local_constant_names
  local_constants.map { |c| c.to_s }
end
</pre>
<p>Knowing the number of times a method was called and who called it is pretty good.  But we can&#8217;t tell if that&#8217;s why our program is slow.  It could be that the method is very fast, so calling it many times doesn&#8217;t matter.  Certainly we need to keep an eye on this method, but let&#8217;s try to find out where this program is spending the most time.</p>
<h2>Sampling method calls</h2>
<p>It would be best if we could time how long ruby spends in any particular method.  But in order to do that, we would have to keep track of the Ruby stack.  DTrace doesn&#8217;t provide us with a good way to access the Ruby stack.  We could write our own program to manually keep track, but there are problems.  For example, if something raises an exception, how far up the stack did it go?  Which method caught the exception?  What about catch / throw?  It&#8217;s Friday and I don&#8217;t feel like figuring out all the edge cases for dealing with that.</p>
<p>Rather than keeping track of the stack, we can use a timer probe in DTrace.  We will set up two probes.  One probe will record function entries in a global variable, the other probe will run at fixed intervals and record the last function that was called.  This approach assumes that the more time we spend in any particular function, the more likely we&#8217;ll see that function recorded.  Every time a method is entered, this DTrace script will record the method call.  Then we have a timer that runs at 5000hz taking a sample of the last method entered.</p>
<pre><code>ruby*:::function-entry
{
  k = copyinstr(arg0);
  m = copyinstr(arg1);
}

tick-5000hz
/k != 0/
{
  @[k, m] = count();
}
</code></pre>
<p>Running this script against <code>rake environment</code> yields these results:</p>
<pre><code>$ sudo dtrace -q -s calls.d -c'rake environment'

  Module            method_added               329
  Fixnum            ^                          330
  Mutex             unlock                     355
  String            hash                       477
  Array             -                          671
  Module            constants                  779
  Kernel            require                   2262
  IO                set_encoding              3713
  Symbol            to_s                      4095
  Kernel            `                         4122
$
</code></pre>
<p>The number on the right is the number of times the timer executed while ruby was executing the method on the left.  <code>Symbol#to_s</code> is definitely in our top 10, but it seems we&#8217;re actually spending more time in <code>Kernel#`</code>.  Let&#8217;s find all places where <code>Kernel#`</code> is called but using DTrace.  We&#8217;ll use predicates to ensure our probe only fires when that method is called.  Predicates are declared below the probe name and above the curly brace within slashes.  Our probe body will simply aggregate based on the file where the call happened:</p>
<pre><code>ruby*:::function-entry
/copyinstr(arg0) == "Kernel" &amp;&amp; copyinstr(arg1) == "`"/
{
  @[copyinstr(arg2)] = count();
}
</code></pre>
<p>Execute this script:</p>
<pre><code>$ sudo dtrace -q -s calls.d -c'rake environment'

  /Users/aaron/.local/lib/ruby/gems/1.9.1/gems/bundler-1.0.21/lib/bundler.rb                1
  /Users/aaron/.local/lib/ruby/gems/1.9.1/bundler/gems/coffee-rails-2120408a4063/coffee-rails.gemspec                3
  /Users/aaron/.local/lib/ruby/gems/1.9.1/bundler/gems/sass-rails-3c24e4fd8dd3/sass-rails.gemspec                3
  /Users/aaron/.local/lib/ruby/gems/1.9.1/gems/execjs-1.2.9/lib/execjs/external_runtime.rb                5
$
</code></pre>
<p>On the right side, we have the number of calls made to <code>Kernel#`</code>, and on the left we have the file where that call was made.  We can see that running <code>rake environment</code> will create 12 subshells.  Let&#8217;s see how much time we&#8217;re spending by creating new subshells:</p>
<pre><code>ruby*:::function-entry
/copyinstr(arg0) == "Kernel" &#038;&#038; copyinstr(arg1) == "`"/
{
  self->time = timestamp;
}

ruby*:::function-return
/copyinstr(arg0) == "Kernel" &#038;&#038; copyinstr(arg1) == "`"/
{
  this->took = (timestamp - self->time) / 1000000;

  @[copyinstr(arg2)] = sum(this->took);
  @total = sum(this->took);
}

END
{
  printf("Time per file:\n");
  printa(@);
  printf("\nTOTAL: ");
  printa(@total);
}
</code></pre>
<p>Here we keep track of the total time spent in <code>Kernel#`</code> in the <code>@total</code> variable, and the aggregate per file in the <code>@</code> variable.  The report lists the amount of time in milliseconds that we&#8217;re spending.  If we run this along with the <code>time</code> command, we can get a rough idea of what percentage we&#8217;re spending in <code>Kernel#`</code>:</p>
<pre><code>$ time sudo dtrace -q -s calls.d -c'rake environment'
Time per file:

  /Users/aaron/.local/lib/ruby/gems/1.9.1/gems/bundler-1.0.21/lib/bundler.rb  15
  /Users/aaron/.local/lib/ruby/gems/1.9.1/bundler/gems/coffee-rails-2120408a4063/coffee-rails.gemspec  246
  /Users/aaron/.local/lib/ruby/gems/1.9.1/bundler/gems/sass-rails-3c24e4fd8dd3/sass-rails.gemspec  267
  /Users/aaron/.local/lib/ruby/gems/1.9.1/gems/execjs-1.2.9/lib/execjs/external_runtime.rb  398

TOTAL:
              926

real  0m7.942s
user  0m4.052s
sys   0m2.909s
$
</code></pre>
<p>With DTrace enabled, the total run time took about 8000ms and of that time 926ms was spent inside <code>Kernel#`</code>.  So let&#8217;s say about 11% of our time running <code>rake environment</code> is spent in subshells.</p>
<h2>Removing the Subshells</h2>
<p>First we need to figure out where these subshells are being created.  Since we&#8217;re studying DTrace, let&#8217;s write a script to aggregate call sites of <code>Kernel#`</code>:</p>
<pre><code>ruby*:::function-entry
/copyinstr(arg0) == "Kernel" &amp;&amp; copyinstr(arg1) == "`"/
{
  @[copyinstr(arg2), arg3] = count();
}
</code></pre>
<p>Running this, we can find the locations of our subshells:</p>
<pre><code>/Users/aaron/.local/lib/ruby/gems/1.9.1/bundler/gems/coffee-rails-2120408a4063/coffee-rails.gemspec       19        1
/Users/aaron/.local/lib/ruby/gems/1.9.1/bundler/gems/coffee-rails-2120408a4063/coffee-rails.gemspec       20        1
/Users/aaron/.local/lib/ruby/gems/1.9.1/bundler/gems/coffee-rails-2120408a4063/coffee-rails.gemspec       21        1
/Users/aaron/.local/lib/ruby/gems/1.9.1/bundler/gems/sass-rails-3c24e4fd8dd3/sass-rails.gemspec       22        1
/Users/aaron/.local/lib/ruby/gems/1.9.1/bundler/gems/sass-rails-3c24e4fd8dd3/sass-rails.gemspec       23        1
/Users/aaron/.local/lib/ruby/gems/1.9.1/bundler/gems/sass-rails-3c24e4fd8dd3/sass-rails.gemspec       24        1
/Users/aaron/.local/lib/ruby/gems/1.9.1/gems/bundler-1.0.21/lib/bundler.rb      209        1
/Users/aaron/.local/lib/ruby/gems/1.9.1/gems/execjs-1.2.9/lib/execjs/external_runtime.rb      150        5
</code></pre>
<p>We&#8217;ll tackle fixing the gemspecs first because they are most boring to fix.</p>
<h3>Fixing the gemspecs</h3>
<p>Each gemspec shells out and runs git in order to populate various parts of the gemspec.  Here are the relevant lines from one of the gemspecs:</p>
<pre class="brush: ruby; title: ; notranslate">
s.files         = `git ls-files`.split(&quot;\n&quot;)
s.test_files    = `git ls-files -- {test,spec,features}/*`.split(&quot;\n&quot;)
s.executables   = `git ls-files -- bin/*`.split(&quot;\n&quot;).map{ |f| File.basename(f) }
</pre>
<p>To fix this, we&#8217;re going to generate the gemspec in advance, then check in the generated gemspec.  The downside of this solution is that whenever anybody adds or removes a file, the gemspec must be regenerated.  The upside to this solution is that you see exactly what files are packaged in your gemspec.  A more optimal solution would be to change bundler such that when a git repository is checked out, a gemspec for that repo is automatically built.  If you&#8217;re looking for an opportunity to contribute to open source, this is it! <img src='http://tenderlovemaking.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
<p>The gemspecs are now generated in advance.  Next we should look at fixing subshells Bundler.</p>
<h3>Fixing Bundler</h3>
<p>In <a href="https://github.com/carlhuda/bundler/blob/b6bf2af3beed4d9089d429fcdcbc5f342dbdf855/lib/bundler.rb#L227-239"><code>bundler.rb</code> around line 209</a>, we find that Bundler is trying to locate the <code>sudo</code> executable:</p>
<pre class="brush: ruby; title: ; notranslate">
def requires_sudo?
  return @requires_sudo if defined?(@checked_for_sudo) &amp;&amp; @checked_for_sudo

  path = bundle_path
  path = path.parent until path.exist?
  sudo_present = !(`which sudo` rescue '').empty?

  @checked_for_sudo = true
  @requires_sudo = settings.allow_sudo? &amp;&amp; !File.writable?(path) &amp;&amp; sudo_present
end
</pre>
<p>Let&#8217;s refactor this to use a <code>which</code> method that searches the <code>PATH</code> environment variable:</p>
<pre class="brush: ruby; title: ; notranslate">
def which(cmd)
  if File.executable? cmd
    cmd
  else
    path = ENV['PATH'].split(File::PATH_SEPARATOR).find { |path|
      File.executable? File.join(path, cmd)
    }
    path &amp;&amp; File.expand_path(cmd, path)
  end
end

def requires_sudo?
  # ...
  sudo_present = which &quot;sudo&quot;
  # ...
end
</pre>
<p>Our <code>which</code> implementation isn&#8217;t 100% perfect, (it can&#8217;t handle input like &#8220;./sudo&#8221; correctly) but it is good enough to find the <code>sudo</code> executable on a person&#8217;s system.  Benchmarks reveal that the implementation that doesn&#8217;t shell out is over 10x faster than the version that does:</p>
<pre class="brush: ruby; title: ; notranslate">
require 'rubygems'
require 'benchmark/ips'

def sand_which cmd
  `which #{cmd}`
end

def blair_which cmd
  if File.executable? cmd
    cmd
  else
    path = ENV['PATH'].split(File::PATH_SEPARATOR).find { |path|
      File.executable? File.join(path, cmd)
    }
    path &amp;&amp; File.expand_path(cmd, path)
  end
end

Benchmark.ips do |x|
  x.report(&quot;sand&quot;) { sand_which 'sudo' }
  x.report(&quot;blair&quot;) { blair_which 'sudo' }
end
</pre>
<pre><code>$ ruby lol.rb
                sand      251.0 (±4.8%) i/s -       1265 in   5.051489s (cycle=23)
               blair     3222.0 (±8.2%) i/s -      16218 in   5.076616s (cycle=306)
$
</code></pre>
<p>Now that we have <a href="https://github.com/carlhuda/bundler/pull/1573">bundler fixed</a>, let&#8217;s take a look at ExecJS.</p>
<h3>Fixing ExecJS</h3>
<p>Our last place that shells out is inside ExecJS.  The DTrace probes specifically list <a href="https://github.com/sstephenson/execjs/blob/e88067ac9196bf43365e7d4aa7f0950312492bd1/lib/execjs/external_runtime.rb#L150"><code>execjs/external_runtime.rb</code> line 150</a>.  If we look there, we&#8217;ll find another implementation of <code>which</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
def which(command)
  Array(command).each do |name|
    name, args = name.split(/\s+/, 2)
    result = if ExecJS.windows?
      `#{shell_escape(&quot;#{ExecJS.root}/support/which.bat&quot;, name)}`
    else
      `#{shell_escape('command', '-v', name)} 2&gt;/dev/null`
    end

    if path = result.strip.split(&quot;\n&quot;).first
      return args ? &quot;#{path} #{args}&quot; : path
    end
  end
  nil
end
</pre>
<p>When fixing performance problems, it&#8217;s helpful to understand the task the code is trying to accomplish, as well is how the method is called.  Here is the stack trace for this method inside ExecJS:</p>
<pre><code>lib/execjs/external_runtime.rb:134:in `locate_binary'
lib/execjs/external_runtime.rb:97:in `initialize'
lib/execjs/runtimes.rb:37:in `new'
lib/execjs/runtimes.rb:37:in `<module:Runtimes>'
lib/execjs/runtimes.rb:9:in `<module:ExecJS>'
lib/execjs/runtimes.rb:8:in `<top (required)>'
lib/execjs.rb:2:in `require'
lib/execjs.rb:2:in `<top (required)>'
</code></pre>
<p>There are a couple important things we can learn from this stack trace:  1) this method is called immediately when the file is required, and 2) it&#8217;s called from inside a constructor (on line 97).  Let&#8217;s look at <a href="https://github.com/sstephenson/execjs/blob/e88067ac9196bf43365e7d4aa7f0950312492bd1/lib/execjs/external_runtime.rb#L133-142"><code>locate_binary</code></a>, the <a href="https://github.com/sstephenson/execjs/blob/e88067ac9196bf43365e7d4aa7f0950312492bd1/lib/execjs/external_runtime.rb#L90-98">initializer</a>, and how the objects are constructed in <a href="https://github.com/sstephenson/execjs/blob/e88067ac9196bf43365e7d4aa7f0950312492bd1/lib/execjs/runtimes.rb#L18-42"><code>runtimes.rb</code></a>:</p>
<p><code>external_runtime.rb</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
def initialize(options)
  @name        = options[:name]
  @command     = options[:command]
  @runner_path = options[:runner_path]
  @test_args   = options[:test_args]
  @test_match  = options[:test_match]
  @encoding    = options[:encoding]
  @binary      = locate_binary
end

protected
def locate_binary
  if binary = which(@command)
    if @test_args
      output = `#{shell_escape(binary, @test_args)} 2&gt;&amp;1`
      binary if output.match(@test_match)
    else
      binary
    end
  end
end
</pre>
<p><code>runtimes.rb</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
module ExecJS
  module Runtimes
    # ...

    Node = ExternalRuntime.new(
      :name        =&gt; &quot;Node.js (V8)&quot;,
      :command     =&gt; [&quot;nodejs&quot;, &quot;node&quot;],
      :runner_path =&gt; ExecJS.root + &quot;/support/node_runner.js&quot;,
      :encoding    =&gt; 'UTF-8'
    )

    # ...
  end
end
</pre>
<p>The initializer calls <code>locate_binary</code> which calls <code>which</code> which shells out.  This is a great example of a hidden dependency in a constructor, our hidden dependency being the ability to shell out, and the availability of the <code>command</code> command.  This isn&#8217;t to say that the <code>command</code> command will sometimes not be available, the problem is that people constructing this object will not know that it depends on these things.  It&#8217;s &#8220;hidden&#8221; from the caller.  The first thing we should do is stop the constructor from immediately shelling out.  We&#8217;ll do this by initializing <code>@binary</code> to nil, adding a <code>binary</code> method, and changing all places that access the instance variable to use the method instead.  Our diff looks like this:</p>
<pre class="brush: diff; title: ; notranslate">
diff --git a/lib/execjs/external_runtime.rb b/lib/execjs/external_runtime.rb
index a8180d1..65f46f9 100644
--- a/lib/execjs/external_runtime.rb
+++ b/lib/execjs/external_runtime.rb
@@ -94,7 +94,7 @@ module ExecJS
       @test_args   = options[:test_args]
       @test_match  = options[:test_match]
       @encoding    = options[:encoding]
-      @binary      = locate_binary
+      @binary      = nil
     end

     def exec(source)
@@ -113,16 +113,21 @@ module ExecJS

     def available?
       require &quot;multi_json&quot;
-      @binary ? true : false
+      binary ? true : false
     end

+    private
+      def binary
+        @binary ||= locate_binary
+      end
+
     protected
       def runner_source
         @runner_source ||= IO.read(@runner_path)
       end

       def exec_runtime(filename)
-        output = sh(&quot;#{shell_escape(*(@binary.split(' ') &lt;&lt; filename))} 2&gt;&amp;1&quot;)
+        output = sh(&quot;#{shell_escape(*(binary.split(' ') &lt;&lt; filename))} 2&gt;&amp;1&quot;)
         if $?.success?
           output
         else
</pre>
<p>Now the object will only shell out if the value is absolutely necessary.  This technique is called &#8220;extracting a getter&#8221;, and you can read more about it in <a href="https://twitter.com/mfeathers">Michael Feathers&#8217;s</a> book <a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/ref=sr_1_1?ie=UTF8&amp;qid=1323108276&amp;sr=8-1">Working Effectively with Legacy Code</a> (IMO this book is a mandatory read for any software engineer).  Now we&#8217;re lazily shelling out, but if we look at the impact, we&#8217;ve gone from ExecJS creating 5 subshells down to 3 subshells:</p>
<pre><code>$ sudo dtrace -q -s calls.d -c'rake environment'
/Users/aaron/.local/lib/ruby/gems/1.9.1/gems/execjs-1.2.9/lib/execjs/external_runtime.rb      155      3
$
</code></pre>
<p>The target is 0 subshells, so we should continue.  This code is trying to locate executables on the file system, similar to what bundler was doing.  We can change the <code>which</code> method in ExecJS to be a Ruby implementation similar to the implementation we put in bundler:</p>
<pre class="brush: diff; title: ; notranslate">
diff --git a/lib/execjs/external_runtime.rb b/lib/execjs/external_runtime.rb
index 65f46f9..88a08ce 100644
--- a/lib/execjs/external_runtime.rb
+++ b/lib/execjs/external_runtime.rb
@@ -121,6 +121,22 @@ module ExecJS
         @binary ||= locate_binary
       end

+      def which_windows(name)
+        result = `#{shell_escape(&quot;#{ExecJS.root}/support/which.bat&quot;, name)}`
+        result.strip.split(&quot;\n&quot;).first
+      end
+
+      def which_unix(name)
+        if File.executable? cmd
+          cmd
+        else
+          path = ENV['PATH'].split(File::PATH_SEPARATOR).find { |path|
+            File.executable? File.join(path, cmd)
+          }
+          path &amp;&amp; File.expand_path(cmd, path)
+        end
+      end
+
     protected
       def runner_source
         @runner_source ||= IO.read(@runner_path)
@@ -147,19 +163,14 @@ module ExecJS
       end

       def which(command)
-        Array(command).each do |name|
+        Array(command).find do |name|
           name, args = name.split(/\s+/, 2)
-          result = if ExecJS.windows?
-            `#{shell_escape(&quot;#{ExecJS.root}/support/which.bat&quot;, name)}`
-          else
-            `#{shell_escape('command', '-v', name)} 2&gt;/dev/null`
-          end
+          path = ExecJS.windows? ? which_windows(name) : which_unix(name)

-          if path = result.strip.split(&quot;\n&quot;).first
-            return args ? &quot;#{path} #{args}&quot; : path
-          end
+          next unless path
+
+          args ? &quot;#{path} #{args}&quot; : path
         end
-        nil
       end

       if &quot;&quot;.respond_to?(:force_encoding)
</pre>
<p>It isn&#8217;t clear what the utility of the Windows batch file is, so it&#8217;s been extracted to it&#8217;s own method in order to maintain the current functionality.  After these patches (which I have submitted <a href="https://github.com/sstephenson/execjs/pull/57">here</a>), the number of subshells is now down to zero.</p>
<h2>Total Impact</h2>
<p>Before:</p>
<pre><code>$ time rake environment

real    0m2.377s
user    0m2.028s
sys 0m0.320s
</code></pre>
<p>After:</p>
<pre><code>$ time rake environment 

real    0m2.224s
user    0m1.946s
sys 0m0.260s
</code></pre>
<p>After eliminating subshells, we&#8217;ve saved 153 milliseconds for approximately 6% savings.  Not as much as the 11% we were hoping for, but still greater than 0.  If we re-run our sampling profiler, we&#8217;ll find no more references to <code>Kernel#`</code>:</p>
<pre><code>$ sudo dtrace -q -s calls.d -c'rake environment'

  Module           ===                306
  Mutex            unlock             324
  Fixnum           ^                  353
  Module           method_added       368
  Array            -                  509
  String           hash               603
  Module           constants          859
  Kernel           require           2292
  IO               set_encoding      3371
  Symbol           to_s              4561
</code></pre>
<h2>Conclusion</h2>
<p>Removing subshells from the Rails startup process wasn&#8217;t a silver bullet.  From my experience in doing performance work, there is rarely a silver bullet that will fix performance problems.  That said, even 2.2 seconds is still too slow for Rails startup time.  If we collate the sampling profiler by file and method call, I think we can get a more clear picture about our runtime cost:</p>
<pre><code>$ sudo dtrace -q -s calls.d -c'rake environment'

  Array            hash                  /Users/aaron/.local/lib/ruby/1.9.1/rubygems/requirement.rb              255
  Mutex            unlock                <internal:prelude>                                              365
  Fixnum           ^                     /Users/aaron/.local/lib/ruby/1.9.1/rubygems/specification.rb              493
  Array            -                     /Users/aaron/git/rails/activesupport/lib/active_support/dependencies.rb              507
  IO               set_encoding          /Users/aaron/.local/lib/ruby/1.9.1/rubygems/custom_require.rb              636
  Module           constants             /Users/aaron/git/rails/activesupport/lib/active_support/core_ext/module/introspection.rb              841
  IO               set_encoding          /Users/aaron/git/rails/activesupport/lib/active_support/dependencies.rb             1098
  String           hash                  /Users/aaron/.local/lib/ruby/1.9.1/rubygems/specification.rb             1188
  Kernel           require               /Users/aaron/git/rails/activesupport/lib/active_support/dependencies.rb             1253
  Symbol           to_s                  /Users/aaron/git/rails/activesupport/lib/active_support/core_ext/module/introspection.rb             8981
</code></pre>
<p>Of the top ten slow methods, five of them are inside Rails.  These particular methods are all associated with the way that Rails handles missing constants and code reloading.  The total amount of time spent dealing with code reloading is likely far greater than the subshelling issue we fixed.  I knew this before writing this article, but tackling the reloading code in Rails is much longer than a single blog post.  The goal of this blog post was to show that:</p>
<ul>
<li>Startup performance can be improved</li>
<li>Even small changes can make an impact</li>
<li>DTrace is pretty awesome</li>
</ul>
<p>I&#8217;d like to write an article with a more comprehensive analysis of where Rails spends it&#8217;s time on boot (GC, file parsing, method calls), but I don&#8217;t have all the information I need yet.  My next steps are to:</p>
<ul>
<li>Try and understand Rails code reloading better</li>
<li>Add more GC related probes to Ruby</li>
<li>Add source compile probes to ruby</li>
</ul>
<p>Once I&#8217;ve made more progress, I&#8217;ll write another article.</p>
<p>&lt;3&lt;3&lt;3&lt;3</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2011/12/05/profiling-rails-startup-with-dtrace/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>PSA: The number of gems installed on your system can impact rails boot time</title>
		<link>http://tenderlovemaking.com/2011/11/30/psa-the-number-of-gems-installed-on-your-system-can-impact-rails-boot-time/</link>
		<comments>http://tenderlovemaking.com/2011/11/30/psa-the-number-of-gems-installed-on-your-system-can-impact-rails-boot-time/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 22:57:49 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=574</guid>
		<description><![CDATA[Just a PSA: the number of gems you have installed on your system will impact your rails boot time. Why is this? When you require a file, rubygems must find the file. If the file isn&#8217;t &#8230; <a class="more-link" href="http://tenderlovemaking.com/2011/11/30/psa-the-number-of-gems-installed-on-your-system-can-impact-rails-boot-time/">More<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Just a PSA: the number of gems you have installed on your system will impact your rails boot time.  Why is this?</p>
<p>When you require a file, rubygems must find the file.  If the file isn&#8217;t on the load path, it must find it in your installed gems.  To do this, it loads all gemspecs and searches for the file.  This means all gemspecs on your system are evaluated, so the more gems you have, the longer it takes.  You can read more in the <a href="https://github.com/rubygems/rubygems/blob/master/lib/rubygems/custom_require.rb#L20-32">rubygems comments</a>.</p>
<p>The second problem is when bundler comes in to the picture.  When rubygems loads the gemspec files, it turns them in to <code>Gem::Specification</code> objects and <a href="https://github.com/rubygems/rubygems/blob/master/lib/rubygems/specification.rb#L617-636">caches them</a>.  Sometimes bundler must modify your <code>GEM_HOME</code> and <code>GEM_PATH</code> environment variables.  These environment variables tell rubygems where to locate gems on your file system.  Unfortunately, if these variables are modified after the specification cache is built, that means the cache must be cleared.  Until recently, bundler <a href="https://github.com/carlhuda/bundler/blob/b6bf2af3beed4d9089d429fcdcbc5f342dbdf855/lib/bundler.rb#L300">always cleared the rubygems cache</a>.  Since rubygems can load gemspecs before bundler gets activated (or may even while bundler is being activated!), this means it&#8217;s not unusual for all gemspecs on your system to be evaluated twice.  Earlier today, I <a href="https://github.com/carlhuda/bundler/pull/1567">submitted a patch</a> that will only clear the cache if the environment variables are modified.  Hopefully this will mean fewer gemspec evals in the next version of bundler.</p>
<p>To help reduce boot time, just remember:</p>
<ul>
<li>Use gemsets (if you&#8217;re on RVM)</li>
<li>Clean unused gems often</li>
</ul>
<p>To clean up your gems, just use the command <code>gem cleanup</code>.</p>
<p>Hope that helps!</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2011/11/30/psa-the-number-of-gems-installed-on-your-system-can-impact-rails-boot-time/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Connection Management in ActiveRecord</title>
		<link>http://tenderlovemaking.com/2011/10/20/connection-management-in-activerecord/</link>
		<comments>http://tenderlovemaking.com/2011/10/20/connection-management-in-activerecord/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 19:14:53 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=566</guid>
		<description><![CDATA[OMG! Happy Thursday! I am trying to be totally enthusiastic, but the truth is that I have a cold, so there will be fewer uppercase letters and exclamation points than usual. Anyway, I want to talk &#8230; <a class="more-link" href="http://tenderlovemaking.com/2011/10/20/connection-management-in-activerecord/">More<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>OMG! Happy Thursday!  I am trying to be totally enthusiastic, but the truth is that I have a cold, so there will be fewer uppercase letters and exclamation points than usual.</p>
<p>Anyway, I want to talk about database connection management in ActiveRecord.  I am not too pleased with its current state of affairs.  I would like to describe how ActiveRecord connection management works today, how I think it <em>should</em> work, and steps towards fixing the current system.</p>
<p><strong>TL;DR: database connection API in ActiveRecord should be more similar to File API</strong></p>
<h2>Thinking in terms of files</h2>
<p>It&#8217;s convenient to think of our database connection as a file.  Dealing with files is very common.  When we work with files, the basic sequence goes something like this:</p>
<ul>
<li>Open the file</li>
<li>Do some work on the file handle</li>
<li>Close the file</li>
</ul>
<p>We&#8217;re very used to doing these steps when dealing with files.  Typically our code will look something like this:</p>
<pre class="brush: ruby; title: ; notranslate">
File.open('somefile.txt', 'wb') do |fh| # Open the file
  fh.write &quot;hello world&quot;                # Do some work with the file
end                                     # Close file when block returns
</pre>
<p>We don&#8217;t want to share open files among threads because dealing with synchronization around reading and writing to the file is too difficult (and time consuming).  So maybe we&#8217;ll store the handle in a thread local or something until we&#8217;re ready to close it.</p>
<p>Our basic requirements for dealing with a database connection are essentially the same as when dealing with files.  We need to open our database connection, do some work with the connection (send and receive queries), and close the connection.  We have these similarities, yet the API for dealing with database connections in ActiveRecord is vastly different.  Let&#8217;s look at how each of these steps are performed in ActiveRecord today.</p>
<h2>Opening a connection</h2>
<p>Opening a connection to the database is very easy.  First we configure ActiveRecord with the database specification, then we call <code>connection</code> to actually get back a database handle:</p>
<pre class="brush: ruby; title: ; notranslate">
ActiveRecord::Base.establish_connection(
  :adapter  =&gt; &quot;sqlite&quot;,
  :database =&gt; &quot;path/to/dbfile&quot;)

connection_handle = ActiveRecord::Base.connection
</pre>
<p>The main difference between this API and the File API is that we&#8217;ve separated the connection specification from actually opening the connection.  In the case of opening a file, we call <code>open</code> along with a &#8220;specification&#8221; which includes the file name and how we want to open it.  In this case, we&#8217;ve separated the two; essentially storing the specification in a global place, then opening the connection later.</p>
<p>This leads to two questions:</p>
<ol>
<li>Where is the specification stored?</li>
<li>When I call <code>connection</code>, what specification is used?</li>
</ol>
<p>The answer to the first question can be found by reading the <a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb#L57-91"><code>establish_connection</code> method</a>.  Specifically if we look at <a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb#L63">line 63</a> we&#8217;ll find a clue.  Since this method is a class method, the call to <code>name</code> returns the <em>class name of the recipient</em>.  This name (along with our actual spec) is passed in to the connection handler object.  If we jump through a few more layers of indirection, we&#8217;ll find that what we have is essentially a one to one mapping of <em>class name to connection specification</em>.</p>
<p>Armed with this information, we can tackle the second question.  If we look at the <a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb#L114-116">implementation of <code>connection</code></a>, it calls <code>retrieve_connection</code> on itself, which calls <code>retrieve_connection</code> on the connection handler with itself.  A few more method calls later, and we see that each ActiveRecord subclass <a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#L432-437">walks up the inheritance tree looking for a connection</a>:</p>
<pre class="brush: ruby; title: ; notranslate">
def retrieve_connection_pool(klass)
  pool = @connection_pools[klass.name]
  return pool if pool
  return nil if ActiveRecord::Base == klass
  retrieve_connection_pool klass.superclass
end
</pre>
<p>If we read this code carefully, we&#8217;ll notice that not only are connection specifications mapped to classes so are database connections!</p>
<h3>Why is this bad?</h3>
<p>This behavior smells bad to me.  The reason is because we&#8217;re tightly coupling classes along with database connections when really this relationship doesn&#8217;t need to exist.</p>
<h3>How can it be improved?</h3>
<p>If this tight coupling is removed, the complexity of ActiveRecord can be reduced and at the same time increasing the features available!  The way we can reduce this coupling is by passing the connection specification to the method that actually opens the connection.  Specifications can be stored on each class as a <em>convenience</em>, but nothing more.</p>
<p>What if opening a connection looked more like this?</p>
<pre class="brush: ruby; title: ; notranslate">
spec = ActiveRecord::Base.specificiation
ActiveRecord::ConnectionPool.open(spec) do |conn|
  ...
end
</pre>
<p>We could maintain the current behavior by storing specifications on each class, but eliminate the coupling between connection and class.  We would be able to delete all of the code that looks up connections by class hierarchy, and open the doors to having features like this:</p>
<pre class="brush: ruby; title: ; notranslate">
spec = database_a
ActiveRecord::ConnectionPool.open(spec) do |conn|
  User.find_all
end

spec = database_b
ActiveRecord::ConnectionPool.open(spec) do |conn|
  User.find_all
end
</pre>
<h2>Working with the connection</h2>
<p>Working with our connection should remain the same.  We have one place to retrieve our connection and work with it.  Woo!</p>
<h2>Dealing with thread safety</h2>
<p>Sharing open file handles among threads probably isn&#8217;t a good idea and the same can be said about open database connections.  So how does ActiveRecord keep connections localized to one thread?  If we jump through many, many, method calls, we&#8217;ll find where the connection is actually checked out of the connection pool.  It is <a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#L156-163">here we see how thread safety is handled</a>:</p>
<pre class="brush: ruby; title: ; notranslate">
# Retrieve the connection associated with the current thread, or call
# #checkout to obtain one if necessary.
#
# #connection can be called any number of times; the connection is
# held in a hash keyed by the thread id.
def connection
  @reserved_connections[current_connection_id] ||= checkout
end
</pre>
<p>A hash is kept where the key is the <code>current_connection_id</code>.  The implementation of <code>current_connection_id</code> looks up the current id.  If the id isn&#8217;t set, it sets it to the object id of the current thread:</p>
<pre class="brush: ruby; title: ; notranslate">
def current_connection_id #:nodoc:
  ActiveRecord::Base.connection_id ||= Thread.current.object_id
end
</pre>
<p>Next we look at the implementation of <code>connection_id</code> to find that it just <a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb#L118-124">gets and sets a thread local</a>:</p>
<pre class="brush: ruby; title: ; notranslate">
def connection_id
  Thread.current['ActiveRecord::Base.connection_id']
end

def connection_id=(connection_id)
  Thread.current['ActiveRecord::Base.connection_id'] = connection_id
end
</pre>
<p>These methods ensure that we have a one to one relationship of open connection and thread.</p>
<h2>Closing the connection</h2>
<p>Finally we reach our last step: closing the connection.  How many of you have closed your connection to the database in ActiveRecord?  My guess is that it&#8217;s very few.  I think the reason people don&#8217;t typically close their connections with ActiveRecord is twofold.  One, you don&#8217;t have to because it just does it for you, and two, the API to close a particular connection is pretty convoluted.</p>
<p>So how is the connection closed today?  There are two ways, the easy way and the hard way.</p>
<h3>The easy way</h3>
<p>The easy way is good enough in a non-threaded application.  A rack middleware <a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#L461-467">clears out all of the connections at the end of the request</a>.  The source for <code>clear_active_connections!</code> is pretty simple.  For each connection pool in the system (remember it&#8217;s one pool per AR class and connection spec), release that connection:</p>
<pre class="brush: ruby; title: ; notranslate">
# Returns any connections in use by the current thread back to the pool,
# and also returns connections to the pool cached by threads that are no
# longer alive.
def clear_active_connections!
  @connection_pools.each_value {|pool| pool.release_connection }
end
</pre>
<p>Each pool releases the connection it has using the <code>current_connection_id</code> (which happens to be the current thread id):</p>
<pre class="brush: ruby; title: ; notranslate">
# Signal that the thread is finished with the current connection.
# #release_connection releases the connection-thread association
# and returns the connection to the pool.
def release_connection(with_id = current_connection_id)
  conn = @reserved_connections.delete(with_id)
  checkin conn if conn
end
</pre>
<p>Not bad.  But what if our system has multiple threads?</p>
<h3>The hard way</h3>
<p>Believe it or not, the connection pool in ActiveRecord will check in connections in the checkout method.  Let me say that again: the checkout method checks in connections and checks out connections.  If you&#8217;re not facepalming yet, let&#8217;s look at a small part of the checkout method:</p>
<pre class="brush: ruby; title: ; notranslate">
@queue.wait(@timeout)

if(@checked_out.size &lt; @connections.size)
  next
else
  clear_stale_cached_connections!
  if @size == @checked_out.size
    raise ConnectionTimeoutError, &quot;could not obtain a database connection#{&quot; within #{@timeout} seconds&quot; if @timeout}. The max pool size is currently #{@size}; consider increasing it.&quot;
  end
end
</pre>
<p>This bit of the checkout method is not called unless our connection pool has become full.  First we wait for other threads to check in their connection.  While we&#8217;re waiting, if other threads checked in their connection, the first branch of the if statement executes, and a connection is returned.  If no threads have checked in their connection, we call <code>clear_stale_cached_connections!</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
def clear_stale_cached_connections!
  keys = @reserved_connections.keys - Thread.list.find_all { |t|
    t.alive?
  }.map { |thread| thread.object_id }
  keys.each do |key|
    checkin @reserved_connections[key]
    @reserved_connections.delete(key)
  end
end
</pre>
<p>This method walks through every thread in your system, looking for connections that were allocated to threads that no longer exist.  Then it checks in connections associated with those dead threads.  Since there is really no easy way for users to check in their own connections, this is actually a common code path for systems that use threads.</p>
<h3>Why is this bad?</h3>
<p>It should be pretty clear why this behavior is bad.  Walking through every thread in the system, and asking if it&#8217;s alive isn&#8217;t very cheap.  Even worse is that we&#8217;re coupling ourselves to the threading system.  We cannot change the connection pool to work with other concurrency solutions (like Fibers) because those solutions may not give us the introspection we need to perform this operation!</p>
<p>But really, this is treating a symptom.  The real problem is that checking in connections is too difficult, so people don&#8217;t do it.</p>
<h3>How can we fix this?</h3>
<p>I think the best solution for this is to mimic the File API.  If we do this, it will become natural for people dealing with the database connection to actually close the connection.</p>
<p>We should make <code>ActiveRecord::Base.connection</code> consult a thread local.  That thread local is set in the rack middleware where the connection is opened.  If someone creates a new thread, they must populate that thread local, and close the connection at the end of the thread.</p>
<p>Simplified, our middleware would become something like this:</p>
<pre class="brush: ruby; title: ; notranslate">
class ConnectionManagement
  def call env
    spec       = ActiveRecord::Base.spec
    connection = ActiveRecord::ConnectionPool.open spec
    ActiveRecord::Base.connection = connection

    @app.call env

    connection.close
  end
end
</pre>
<p>When people create a new thread, it would look something like this:</p>
<pre class="brush: ruby; title: ; notranslate">
Thread.new do
  spec = ActiveRecord::Base.spec
  ActiveRecord::ConnectionPool.open(spec) do |connection|
    ActiveRecord::Base.connection = connection

    # do some stuff
  end
end
</pre>
<h3>What does this buy us?</h3>
<p>This buys us two important things: simple connection pool management, and freedom of choice on our concurrency model.</p>
<h2>omg the end.</h2>
<p>I hope I&#8217;ve convinced you that by simply learning to treat our database connection like a file, we can reduce code complexity and at the same time increase the features available.  I think I can add this feature to Rails 3.2 and mostly maintain backwards compatibility.  I think we can keep 100% backwards compatibility if we add some sort of flag like <code>config.i_suck_and_will_not_close_my_database_connections = true</code> or, <code>config.my_app_is_awesome = true</code>.</p>
<p>Anyway, I&#8217;m totally sick and I&#8217;ll stop blllluuurrrrggghhhing now.</p>
<p>&lt;3 &lt;3 &lt;3 &lt;3 &lt;3</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2011/10/20/connection-management-in-activerecord/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>I want DTrace probes in Ruby</title>
		<link>http://tenderlovemaking.com/2011/06/29/i-want-dtrace-probes-in-ruby/</link>
		<comments>http://tenderlovemaking.com/2011/06/29/i-want-dtrace-probes-in-ruby/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 22:59:16 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=559</guid>
		<description><![CDATA[Recently I was debugging a performance regression in Rails 3.1. The ticket reported for the regression just indicated a speed problem. Namely allocating new active record objects was very slow in Rails 3.1 compared to Rails &#8230; <a class="more-link" href="http://tenderlovemaking.com/2011/06/29/i-want-dtrace-probes-in-ruby/">More<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently I was debugging a <a href="https://github.com/rails/rails/issues/1717">performance regression in Rails 3.1</a>.  The ticket reported for the regression just indicated a speed problem.  Namely allocating new active record objects was <em>very</em> slow in Rails 3.1 compared to Rails 3.0.</p>
<h3>The benchmark program</h3>
<p>Here is the program I was using for benchmarking.  It&#8217;s slightly modified from the original program that @paul so kindly submitted:</p>
<pre class="brush: ruby; title: ; notranslate">
require 'active_record'
require 'benchmark'

p ActiveRecord::VERSION::STRING

ActiveRecord::Base.establish_connection(
  :adapter  =&gt; &quot;sqlite3&quot;,
  :database =&gt; &quot;:memory:&quot;
)

ActiveRecord::Base.connection.execute(&quot;CREATE TABLE active_record_models (id INTEGER UNIQUE, title STRING, text STRING)&quot;)

class ActiveRecordModel &lt; ActiveRecord::Base; end
ActiveRecordModel.new

N = 100_000
Benchmark.bm { |x| x.report('new') { N.times { ActiveRecordModel.new } } }
</pre>
<p>I could tell from <a href="https://github.com/tmm1/perftools.rb">perftools.rb</a> output we were calling new methods, and those new methods took plenty of time.</p>
<p>Here is the call graph for this benchmark on Rails 3.0:</p>
<div class="thumbnail"><a href="http://skitch.com/aaron.patterson/fghfi/arnew"><img src="http://img.skitch.com/20110627-c2kr8xwqa4x2kiecpdgwyspecg.preview.jpg" alt="arnew" /></a></div>
<p>Compared to the call graph on Rails 3.1:</p>
<div class="thumbnail"><a href="http://skitch.com/aaron.patterson/fghgk/arnew31"><img src="http://img.skitch.com/20110627-1dcj3fcsdqtk4xp3ihan9canyw.preview.jpg" alt="arnew31" /></a></div>
<p>After some work, I was able to remove the method calls to <code>scope</code> when allocating new AR objects, but the benchmark still showed 3.1 to be slower than 3.0.  I noticed we were spending more time in the Garbage Collector on 3.1 than on 3.0.  This lead me to believe that we were creating more objects in the newer version.</p>
<h3>Counting Object Allocations</h3>
<p>Counting object allocations with Ruby 1.9 is actually pretty easy.  We can call <code>ObjectSpace.count_objects</code> to get a list of the live objects in the system.  That method returns a hash where the keys are the object type and the values are the number of that object in the system (there are other keys, be we don&#8217;t care about them for now).</p>
<p>Knowing this information, we can write a function that will calculate a rough difference in object allocations:</p>
<pre class="brush: ruby; title: ; notranslate">
def allocate_count
  GC.disable
  before = ObjectSpace.count_objects
  yield
  after = ObjectSpace.count_objects
  after.each { |k,v| after[k] = v - before[k] }
  GC.enable
  after
end

p allocate_count { 100.times { {} } }
</pre>
<p>The first thing we do in this function is disable the garbage collector.  It&#8217;s possible that the code we&#8217;re investigating could trigger GC, and that will impact our allocated object count.</p>
<p>Then we grab our current list of objects, yield to the code we want to profile, grab the list again, calculate our delta, enable GC and return!</p>
<p>If you run this code, you should see output similar to this (I&#8217;ve removed keys I don&#8217;t care about):</p>
<pre><code>{ ... :T_HASH=&gt;101, ... }
</code></pre>
<p>You can see from the output that we&#8217;ve allocated 101 hashes.  100 came from our <code>100.times</code> call, and one came from calling the method on ObjectSpace.</p>
<p>Since inspecting our code can impact object allocations, these counts can&#8217;t be 100% accurate.  Another annoying thing is that we can&#8217;t determine <em>where</em> our code is allocating these hashes.  It&#8217;s easy enough to see the hash literals in this code, but imagine a project like rails.  You may be able to find hash literals in your source, but determining which ones are being called is difficult.</p>
<p>After running this against the profile, I found that ActiveRecord in 3.1 was allocating 2x the number of hashes that 3.0 allocated.  Now the problem is figuring out <em>where</em> these hashes were being allocated.</p>
<h3>DTrace</h3>
<p>DTrace gives us hooks in to our processes.  Many of the hooks provided are for system calls, or other various functions.  DTrace requires that we write probes in our code, and unfortunately Ruby does not have DTrace probes built in.</p>
<h3>Adding DTrace to Ruby</h3>
<p>To find these Hash allocations, I decided to add DTrace support.  I usually run Ruby built from Ruby trunk, so running a modified Ruby seemed acceptible.  It turns out adding DTrace support is pretty easy.</p>
<p>First I added a probe definition file.  This file describes the probes that I want to add to Ruby.  It contains the probe names and the signatures of the probes:</p>
<pre><code>provider ruby {
  probe hash__alloc(const char *, int);
};
</code></pre>
<p>This definition says we&#8217;re declaring a probe called <code>hash-alloc</code> and it will take a string (the file name) and an int (the line number).</p>
<p>Next I used this definition file to generate a header file that ruby would use:</p>
<pre><code>$ dtrace -o probes.h -h -s probes.d
</code></pre>
<p>Finally, I modified hash.c to trigger the probe:</p>
<pre class="brush: diff; title: ; notranslate">
diff --git a/hash.c b/hash.c
index b49aff8..c40d94d 100644
--- a/hash.c
+++ b/hash.c
@@ -15,6 +15,7 @@
 #include &quot;ruby/st.h&quot;
 #include &quot;ruby/util.h&quot;
 #include &quot;ruby/encoding.h&quot;
+#include &quot;probes.h&quot;
 #include &lt;errno.h&gt;

 #ifdef __APPLE__
@@ -221,6 +222,9 @@ hash_alloc(VALUE klass)
     OBJSETUP(hash, klass, T_HASH);

     RHASH_IFNONE(hash) = Qnil;
+    if(RUBY_HASH_ALLOC_ENABLED()) {
+       RUBY_HASH_ALLOC(rb_sourcefile(), rb_sourceline());
+    }

     return (VALUE)hash;
 }
</pre>
<p>After this, I built and installed ruby.  Then I wrote a dtrace script to display the filename and line number where hash allocations were happening:</p>
<pre><code>ruby*:::hash-alloc
{
  printf("%s:%d", copyinstr(arg0), arg1);
}
</code></pre>
<p>Then I ran the benchmark with dtrace:</p>
<pre><code>$ sudo dtrace -s x.d -c 'ruby -I lib test.rb'
</code></pre>
<p>Here is an excerpt of the output:</p>
<pre><code>  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1528
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1529
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1534
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1535
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1525
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/persistence.rb:322
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1527
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1528
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1529
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1534
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1535
  1 126930            hash_alloc:hash-alloc /Users/aaron/git/rails/activerecord/lib/active_record/base.rb:1525</code></pre>
<p>I was able to compare the output from this script on Rails 3.0 vs Rails 3.1.  From this output, I was able to determine:</p>
<ul>
<li>The number of hash allocations</li>
<li>Where the hashes were allocated</li>
<li>Which allocations were new in Rails 3.1</li>
</ul>
<p>Armed with this information, I was able to eliminate some allocations and return speed in Rails 3.1 to that of Rails 3.0.</p>
<h3>DTrace vs gdb vs memprof</h3>
<p>I probably could have accomplished this task with <a href="https://github.com/ice799/memprof">memprof</a>, but it requires that I use 1.8.7 from rvm.  Working with RVM on my machine is difficult (don&#8217;t ask, let&#8217;s just say I&#8217;m a &#8220;special needs&#8221; user), and I wanted to use 1.9.  So memprof was out the window.</p>
<p>I was able to get the same information by scripting gdb.  I set a breakpoint at the correct function, called <code>rb_sourcefile()</code> and <code>rb_sourceline()</code> and redirected to a file.  The problem with gdb is that it seemed very slow, and scripting it was a pain (though I am not a gdb expert!).</p>
<p>DTrace was fast, relatively easy to use, and very scriptable.  It made me happy!</p>
<h3>OMG!!!</h3>
<p>I would like to see dtrace probes officially added to ruby trunk.  The ruby that ships with OS X has them built in, but they don&#8217;t give us information like hash literal allocations.  It looks like <a href="http://redmine.ruby-lang.org/issues/2565">they were in ruby trunk at one point, but were then reverted</a>.  I would like to see them added again.</p>
<p>If you want to play with them on ruby trunk, <a href="https://gist.github.com/1055159">here is my full patch</a>.  Make sure to run <code>make probes.h</code> before <code>make &amp;&amp; make install</code>.</p>
<p>HAPPY WEDNESDAY!!!! &lt;3 &lt;3 &lt;3 &lt;3</p>
<p><small>(it feels good to blog on a non &#8220;professional&#8221; blog)</small></p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2011/06/29/i-want-dtrace-probes-in-ruby/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>TIL: It&#8217;s OK to return nil from to_ary</title>
		<link>http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary/</link>
		<comments>http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary/#comments</comments>
		<pubDate>Tue, 28 Jun 2011 23:08:24 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=545</guid>
		<description><![CDATA[tl;dr: You can return nil from to_ary and to_a. Today I discovered that it&#8217;s OK for to_ary to return nil. Ruby spec tests this behavior, and the ruby implementation supports it. But why would you want &#8230; <a class="more-link" href="http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary/">More<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>tl;dr: You can return nil from <code>to_ary</code> and <code>to_a</code>.</p>
<p>Today I discovered that it&#8217;s OK for <code>to_ary</code> to return nil.  <a href="https://github.com/rubyspec/rubyspec/blob/master/core/array/flatten_spec.rb#L105">Ruby spec tests this behavior</a>, and the<br />
ruby implementation <a href="https://github.com/ruby/ruby/blob/trunk/array.c#L3687-3693">supports it</a>.  But why would you want to implement this?</p>
<h3>Array#flatten and <code>to_ary</code></h3>
<p>Consider the following code:</p>
<pre class="brush: ruby; title: ; notranslate">
class Item
  def respond_to?(name, visibility = false)
    p &quot;respond to: #{name}&quot;
    false # we don't respond to anything!!
  end

  def method_missing(name, *args)
    p &quot;method missing: #{name}&quot;
    super # if something?
    # do something else
  end
end

[[Item.new]].flatten
</pre>
<p>In Ruby 1.9, <code>flatten</code> will actually call <code>to_ary</code> on each of the items in the collection.  If the method table for this object contains <code>to_ary</code>, Ruby will call <code>to_ary</code>, and if <code>method_missing</code> is implemented, it will call <code>method_missing</code> regardless of how your <code>respond_to?</code> returns.  The reason ruby will call <code>method_missing</code> is because it <em>could</em> implement <code>to_ary</code>. (As for why it ignores the return value of <code>respond_to?</code>, I don&#8217;t know)</p>
<p>Naturally, if we were to call <code>to_ary</code> directly on this object it would raise a <code>NoMethodError</code> exception.  When calling flatten, ruby will swallow the exception.  If we enable <code>$DEBUG</code> by running ruby with <code>-d</code>, we can see the exception:</p>
<pre><code>[aaron@higgins ~]$ ruby -d test.rb
Exception `LoadError' at /Users/aaron/.local/lib/ruby/site_ruby/1.9.1/rubygems.rb:1215 - cannot load such file -- rubygems/defaults/operating_system
Exception `LoadError' at /Users/aaron/.local/lib/ruby/site_ruby/1.9.1/rubygems.rb:1224 - cannot load such file -- rubygems/defaults/ruby
"method missing: to_ary"
Exception `NoMethodError' at test.rb:9 - undefined method `to_ary' for #&lt;Item:0x00000101079e80&gt;
"respond to: to_ary"
[aaron@higgins ~]$
</code></pre>
<p>Dispatching to <code>method_missing</code> can be expensive, and using exceptions for flow control even more problematic.  The way we can get around this issue is by implementing <code>to_ary</code> and having it return nil:</p>
<pre class="brush: ruby; title: ; notranslate">
class Item
  def respond_to?(name, visibility = false)
    p &quot;respond to: #{name}&quot;
    false # we don't respond to anything!!
  end

  def method_missing(name, *args)
    p &quot;method missing: #{name}&quot;
    super # if something?
    # do something else
  end

  private
  def to_ary
    nil
  end
end

[[Item.new]].flatten
</pre>
<p>Run the code again with <code>-d</code>, and you&#8217;ll see no more calls to <code>respond_to?</code>, no more calls to <code>method_missing</code>, and no more exceptions raised:</p>
<pre><code>[aaron@higgins ~]$ ruby -d test.rb
Exception `LoadError' at /Users/aaron/.local/lib/ruby/site_ruby/1.9.1/rubygems.rb:1215 - cannot load such file -- rubygems/defaults/operating_system
Exception `LoadError' at /Users/aaron/.local/lib/ruby/site_ruby/1.9.1/rubygems.rb:1224 - cannot load such file -- rubygems/defaults/ruby
[aaron@higgins ~]$
</code></pre>
<h3>Array() and <code>to_a</code></h3>
<p>The Array() function exhibits a similar behavior, but with the <code>to_a</code> method.  Try this same code, but rather than using <code>Array#flatten</code>, do this:</p>
<pre class="brush: ruby; title: ; notranslate">
Array(Item.new)
</pre>
<p>We can fix the error produced by this code with a slight change to our class:</p>
<pre class="brush: ruby; title: ; notranslate">
class Item
  def respond_to?(name, visibility = false)
    p &quot;respond to: #{name}&quot;
    false # we don't respond to anything!!
  end

  def method_missing(name, *args)
    p &quot;method missing: #{name}&quot;
    super # if something?
    # do something else
  end

  private
  def to_ary
    nil
  end
  alias :to_a :to_ary
end

[[Item.new]].flatten
Array(Item.new)
</pre>
<h3>Hmmmm</h3>
<p>Are warnings annoying? Yes. Is this strange behavior? I tend to think so. But if I&#8217;m forced to deal with a class the implements <code>method_missing</code>, I&#8217;d like to reduce the number of calls to <code>method_missing</code>.</p>
<p>Anyway.  I hope you found this informative.  Have a Happy Tuesday!!!!</p>
<p>&lt;3 &lt;3 &lt;3 &lt;3</p>
<h3>Small Side Note</h3>
<p>The reason there are exceptions coming from rubygems when <code>-d</code> is enabled is because rubygems attempts to require files that are not shipped with rubygems.  These files are for packagers to provide.  For example someone packaging rubygems for debian, may need to do customizations and those files are where that happens.</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Mechanize 2.0.0 has been released!</title>
		<link>http://tenderlovemaking.com/2011/06/27/mechanize-2-0-0-has-been-releases/</link>
		<comments>http://tenderlovemaking.com/2011/06/27/mechanize-2-0-0-has-been-releases/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 22:14:56 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=533</guid>
		<description><![CDATA[ZOMG! Thanks to @drbrain, mechanize 2.0.0 has been released! See the full announcement here!]]></description>
			<content:encoded><![CDATA[<p>ZOMG!  Thanks to @drbrain, mechanize 2.0.0 has been released!</p>
<p>See the full announcement <a href="http://blog.segment7.net/2011/06/27/mechanize-2-0">here</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2011/06/27/mechanize-2-0-0-has-been-releases/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rack API is awkward</title>
		<link>http://tenderlovemaking.com/2011/03/03/rack-api-is-awkward/</link>
		<comments>http://tenderlovemaking.com/2011/03/03/rack-api-is-awkward/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 19:24:59 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=522</guid>
		<description><![CDATA[TL;DR: Rack API is poor when you consider streaming response bodies. ZOMG!!!! HAPPY THURSDAY!!!! Maybe I shouldn&#8217;t be so excited now. I want to talk about stuff I&#8217;ve been working on in Rails 3.1, and problems &#8230; <a class="more-link" href="http://tenderlovemaking.com/2011/03/03/rack-api-is-awkward/">More<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>TL;DR: Rack API is poor when you consider streaming response bodies.</strong></p>
<p>ZOMG!!!!  HAPPY THURSDAY!!!!  Maybe I shouldn&#8217;t be so excited now.  I want to talk about stuff I&#8217;ve been working on in Rails 3.1, and problems I&#8217;m encountering today.  I want to use this blllurrrggghhh blog post to talk through through the problems I&#8217;ve been having, and to share the pain with others.</p>
<h2>Pie is delicious!</h2>
<p>One feature that would be useful to add to Rails is having a streaming response body.  When Rails processes a response, the entire response is buffered in memory before it can be sent to the user.  Some information like Content Length (among other things) is derived, and the response is sent.</p>
<p>Sometimes buffering a response is less than ideal.  It would be nice if we could send the head tag along with any css or script includes to the browser as quickly as possible.  Then the browser can download external resources while we&#8217;re still processing data on the server.  If this were possible, total response time may remain the same, but the time to first byte would be decreased and the page would load faster as external resource can be downloaded in parallel.</p>
<p>This feature sounds great, but there are many things to think about before it can be implemented.  We need to support infinite streams, chunked encoding, prevent header manipulation, ensure database connections, blah, blah blah.</p>
<h2>Rack interface</h2>
<p>I&#8217;m getting ahead of myself.  Before we get to our ultimate &#8220;pie in the sky&#8221; streaming solution, let&#8217;s take a look at the Rack API.  Rack defines an interface for writing web applications.  A rack handler must respond to <code>call</code> which takes one parameter, the request environment.  <code>call</code> must return a three item list of:</p>
<ul>
<li>Response code</li>
<li>Headers</li>
<li>Body</li>
</ul>
<p>The response code should be a number (like 200), the headers are a hash (like { &#8216;X-Omg&#8217; => &#8216;hello!&#8217; }).  The body must respond to <code>each</code> and take a block.  The body must yield a string to the block, and the string will be output to the client.  Optionally, the body may respond to <code>close</code>, and rack will call <code>close</code> when output is complete.</p>
<h2>An Example Rack application</h2>
<p>Let&#8217;s write an example application.  Our sample application will simulate an ERb page.  We&#8217;ll add some <code>sleep</code> statements to simulate work happening during the ERb rendering process:</p>
<pre class="brush: ruby; title: ; notranslate">
class FooApplication
  class ErbPage
    def to_a
      head = &quot;the head tag&quot;
      sleep(2)
      body = &quot;the body tag&quot;
      sleep(2)
      [head, body]
    end
  end

  def call(env)
    [200, {}, ErbPage.new.to_a]
  end
end
</pre>
<p>For the purposes of demonstration, we&#8217;ll be using a fake implementation of rack:</p>
<pre class="brush: ruby; title: ; notranslate">
class FakeRack
  def serve(application)
    status, headers, body = application.call({})
    p :status  =&gt; status
    p :headers =&gt; headers

    body.each do |string|
      p string
    end

    body.close if body.respond_to?(:close)
  end
end
</pre>
<p>If we feed our application through FakeRack like this:</p>
<pre class="brush: ruby; title: ; notranslate">
app  = FooApplication.new
rack = FakeRack.new

rack.serve app
</pre>
<p>We&#8217;ll see output from the rack application, and the total program run time is about 4 seconds:</p>
<pre class="brush: ruby; title: ; notranslate">
$ time ruby foo.rb
{:status=&gt;200}
{:headers=&gt;{}}
&quot;the head tag&quot;
&quot;the body tag&quot;

real    0m4.008s
user    0m0.003s
sys     0m0.003s
</pre>
<p>Great!  So far, no problem.  Why don&#8217;t we add a middleware to time how long the response takes.</p>
<h2>Rack Middleware</h2>
<p>Rack Middleware is simply another Rack application.  With Rack, we set up a linked list of middleware that eventually point to the real application.  We give the head of the linked list to Rack, Rack calls <code>call</code> on the head of the list, and it is the list&#8217;s responsibility to call <code>call</code> on it&#8217;s link.</p>
<p>Here, we&#8217;ll write a Rack middleware to measure how long the &#8220;ERb render&#8221; takes and add a header indicating the response time.</p>
<pre class="brush: ruby; title: ; notranslate">
class ResponseTimer
  def initialize(app)
    @app = app
  end

  def call(env)
    now                        = Time.now
    status, headers, body      = @app.call(env)
    headers['X-Response-Took'] = Time.now - now

    [status, headers, body]
  end
end
</pre>
<p>When we construct the ResponseTimer, we pass it the real application.  Then we pass the response timer instance to rack:</p>
<pre class="brush: ruby; title: ; notranslate">
app   = FooApplication.new
timer = ResponseTimer.new app
rack  = FakeRack.new

rack.serve timer
</pre>
<p>When rack calls <code>call</code> on the response timer, it records the current time, then calls <code>call</code> on the real application.  When the real application returns, the response timer then adds a header with the time delta.  The output of this program will look like this:</p>
<pre class="brush: ruby; title: ; notranslate">
$ time ruby foo.rb
{:status=&gt;200}
{:headers=&gt;{&quot;X-Response-Took&quot;=&gt;3.999937}}
&quot;the head tag&quot;
&quot;the body tag&quot;

real    0m4.010s
user    0m0.004s
sys     0m0.004s
</pre>
<h2>Speeding up our response time</h2>
<p>We&#8217;ve noticed a problem with our Rack application.  When a client connects, it takes 4 seconds before they receive any data!  It would be nice if we could feed our client the head tag ASAP so they can download external resources.</p>
<p>We know that Rack will call <code>each</code> and (depending on your webserver) immediately send data to the client.  Rather than computing values in ERb ahead of time, we&#8217;ll compute them when Rack asks for them (when <code>each</code> is called).</p>
<p>Let&#8217;s refactor the ERb page to be lazy about calculating values:</p>
<pre class="brush: ruby; title: ; notranslate">
class FooApplication
  class ErbPage
    def each
      head = &quot;the head tag&quot;
      yield head

      sleep(2)

      body = &quot;the body tag&quot;
      yield body

      sleep(2)
    end
  end

  def call(env)
    [200, {}, ErbPage.new]
  end
end
</pre>
<p>Now no values are calculated until rack calls <code>each</code> on our body.  If we run the program, we&#8217;ll see output from the application more quickly than before.</p>
<p>However, the output is somewhat strange:</p>
<pre class="brush: ruby; title: ; notranslate">
$ time ruby foo.rb
{:status=&gt;200}
{:headers=&gt;{&quot;X-Response-Took&quot;=&gt;1.1e-05}}
&quot;the head tag&quot;
&quot;the body tag&quot;

real    0m4.032s
user    0m0.027s
sys     0m0.016s
</pre>
<p>The time command reports that our response was about 4 seconds.  But our response header says that the response took nearly 0 seconds!  Why is this?</p>
<p>If we look closely at our timer middleware, we can see it is only timing <em>how long it took for <code>call</code> to return</em>.</p>
<p>We cannot guarantee that <em>any</em> processing happened during the <code>call</code> method.</p>
<p>Let me say that again:</p>
<p><strong>We cannot guarantee that <em>any</em> processing happened during the <code>call</code> method.</strong></p>
<p>We wanted our response timer to time how long the ERb took to render, but really it is just timing how long the <code>call</code> method took.</p>
<h2>ZOMG HOW FIX?!?</h2>
<h3>Iterating over the body</h3>
<p>One way to fix is to iterate over the body.  If the timer iterates over the body, then we can calculate the real time:</p>
<pre class="brush: ruby; title: ; notranslate">
class ResponseTimer
  def initialize(app)
    @app = app
  end

  def call(env)
    now                        = Time.now
    status, headers, body      = @app.call(env)

    newbody = []
    body.each { |str| newbody &lt;&lt; str }
    headers['X-Response-Took'] = Time.now - now

    [status, headers, newbody]
  end
end
</pre>
<p>But this solution is no good!  Our response timer now buffers the response, and our client ends up waiting for 4 seconds before they get any data.</p>
<p>We know that Rack calls <code>close</code> on the body after it&#8217;s done processing the request.  Why don&#8217;t we try hooking on that method?</p>
<h3>Introducing a Proxy Object</h3>
<p>One way we can hook on to the close method is by wrapping the response body in a proxy object.  Then we can intercept calls made on the body and perform any work we need done:</p>
<pre class="brush: ruby; title: ; notranslate">
class ResponseTimer
  class TimerProxy
    def initialize(body)
      @now     = Time.now
      @body    = body
    end

    def close
      @body.close if @body.respond_to?(:close)

      $stderr.puts({'X-Response-Took' =&gt; (Time.now - @now)})
    end

    def each(&amp;block)
      @body.each(&amp;block)
    end
  end

  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, body = @app.call(env)

    [status, headers, TimerProxy.new(body)]
  end
end
</pre>
<p>Wow!  Suddenly our middleware is not so simple.  This proxy solution is sub-optimal for a few reasons.  We&#8217;re required to make a new object for every request, and our proxy object will add another stack frame between calls from rack to the response body.  Even worse, every middleware that needs to do work after the response is finished must define this proxy object.</p>
<p>This solution does get the job done.  If we look at the output from the program, we&#8217;ll see that the TimerProxy in fact measures ERb processing time correctly:</p>
<pre class="brush: ruby; title: ; notranslate">
$ time ruby foo.rb
{:status=&gt;200}
{:headers=&gt;{}}
&quot;the head tag&quot;
&quot;the body tag&quot;
{&quot;X-Response-Took&quot;=&gt;4.000268}

real    0m4.044s
user    0m0.029s
sys     0m0.015s
</pre>
<p>Diligent readers will note that the response time is no longer part of the response headers.  This is because when the body is flushed, the headers must be flushed too.  We no longer have the opportunity to add extra headers when <code>each</code> is called on the body.</p>
<p>Our solution isn&#8217;t <em>too bad</em>, but it actually isn&#8217;t complete.  The full awkwardness of this API along with a complete solution can actually be felt (and read) <a href="https://github.com/rack/rack/blob/master/lib/rack/lock.rb">in the Rack source itself</a>.</p>
<h3>Lady Gaga Solution</h3>
<p>Another possible solution is to decorate the body using a module.  We can define a module, then simply call <code>extend</code> on the body with the module:</p>
<pre class="brush: ruby; title: ; notranslate">
class ResponseTimer
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, body      = @app.call(env)
    body.extend(Module.new {
      now = Time.now

      define_method(:close) do
        super if defined?(super)

        $stderr.puts({'X-Response-Took' =&gt; (Time.now - now)})
      end
    })

    [status, headers, body]
  end
end
</pre>
<p>The body is extended with an anonymous module.  During module definition, the time is recorded.  We use <code>define_method</code> because it uses a lambda which will keep a reference to the previously calculated time.  In the <code>close</code> method, we call super if it&#8217;s defined, then output our time.</p>
<p>This example also works, but has a few downsides.  It is different than previous examples because we are timing <em>only</em> the ERb rendering and not <code>call</code> plus ERb rendering.  Using this solution, we&#8217;re required to create a new module on every request, and also break method caching on every request.  Similar to the proxy object solution, we must create a new module and extend for every middleware that must to processing after the response is finished.</p>
<h2>ZOMG YOUR EXAMPLE IS CONTRIVED</h2>
<p>Yup.  But I merely simplified a real world problem.  As I mentioned earlier, you can see the awkwardness of this API <a href="https://github.com/rack/rack/blob/master/lib/rack/lock.rb">in rack</a>.</p>
<p>But now that we know about this problem, we can identify middleware that will break streaming responses.  For example, Rails defines a middleware <a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#L407-421">that checks connections back in to the connection pool</a>.  If our ERb in Rails was streaming, we would lose the database connection during ERb render.  The same is true with the <a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/query_cache.rb#L30-34">query cache in active record</a>.  Surely, these cannot be the only middleware that will break when a streaming body is used!</p>
<h2>Lifecycle hooks</h2>
<p>I think a good solution to this problem would be if Rack provided lifecycle hooks.  A Place where we can say &#8220;run this when the response is done&#8221;.  We can define something like that today using middleware:</p>
<pre class="brush: ruby; title: ; notranslate">
class EndOfLife
  attr_reader :callbacks

  def initialize(app)
    @app       = app
    @callbacks = []
  end

  def call(env)
    status, headers, body = @app.call(env)
    body.extend(Module.new {
      attr_accessor :eol

      def close
        super if defined?(super)
        eol.callbacks.each { |cb| cb.call }
      end
    })
    body.eol = self

    [status, headers, body]
  end
end

app = FooApplication.new
eol = EndOfLife.new app
eol.callbacks &lt;&lt; lambda { puts &quot;it finished!&quot; }

rack  = FakeRack.new

rack.serve eol
</pre>
<p>This keeps us from defining many proxy objects or module extensions during a response.  We only define one module extension, and hook any &#8220;end of life&#8221; hooks on to this instance.  The downside is that we cannot guarantee the position of this middleware in the middleware linked list.  That means that the &#8220;end of life&#8221; middleware may not actually execute at the end of the response!</p>
<h2>A &#8220;real&#8221; solution</h2>
<p>Rack&#8217;s interface is simple, and I like that.  The simplicity is attractive, but the API seems to fall on it&#8217;s face when we start talking about streaming web servers.  If I remember correctly, Apache 1.0 modules suffered the same problems that Rack is presenting us today.  Maybe we should look at Apache 2.0 <a href="http://www.apachetutor.org/dev/brigades">buckets and filters</a> and design our API using patterns from a project that has already solved this problem.</p>
<h2>ZOMG I AM TIRED OF TYPING!!</h2>
<p>I&#8217;m not happy with any of the solutions I&#8217;ve presented.  All of them have downsides that I find unattractive.  We can live with the downsides, but life will suck.  If any of you dear readers have better solutions for me, I am all ears!</p>
<p>Thanks for listening, and HAVE A GREAT DAY!!!!</p>
<p>&lt;3 &lt;3 &lt;3 &lt;3 &lt;3</p>
<p><strong>Edit:</strong> I just noticed that Rack contains a &#8220;timer&#8221; middleware similar to the one I&#8217;ve implemented in this blog post.  You can view the broken middleware <a href="https://github.com/rack/rack/blob/master/lib/rack/runtime.rb">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2011/03/03/rack-api-is-awkward/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>RubyCommitters.org winners</title>
		<link>http://tenderlovemaking.com/2011/01/21/rubycommitters-org-winners/</link>
		<comments>http://tenderlovemaking.com/2011/01/21/rubycommitters-org-winners/#comments</comments>
		<pubDate>Sat, 22 Jan 2011 06:50:02 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[life]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=507</guid>
		<description><![CDATA[Hi everybody! I&#8217;m going to get this over. To me, this is like removing a bandage, I must do it all at once. I&#8217;ve increased the Love Bucks, so I&#8217;ll list the winners along with their &#8230; <a class="more-link" href="http://tenderlovemaking.com/2011/01/21/rubycommitters-org-winners/">More<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hi everybody!</p>
<p>I&#8217;m going to get this over.  To me, this is like removing a bandage, I must do it all at once.  I&#8217;ve increased the Love Bucks, so I&#8217;ll list the winners along with their prizes:</p>
<ul>
<li>First place of 500 Love Bucks: <a href="http://tenderlovemaking.com/entries/mnutt-master/">mnutt</a></li>
<li>Second place of 400 Love Bucks: <a href="http://heroesofruby.heroku.com/">fredwu</a></li>
<li>Third place of 300 Love Bucks: <a href="http://wandering-rc.heroku.com/">WanderingMatt</a></li>
<li>Tied for third place with 300 Love Bucks: <a href="http://matzilla.heroku.com/">ejc&#8217;s matzilla!</a></li>
</ul>
<p>Winners, please send me your paypal address and I&#8217;ll send you the Love Bucks.</p>
<p><span id="more-507"></span></p>
<h2>Okay, you can stop reading now</h2>
<p>No, seriously.  Stop reading.  The rest of this post is actually for myself.  I need to record this so that I can remind my future self.  This contest turned out to be more than I had expected.  Every entry was above and beyond anything I could have hoped or wished for.</p>
<p>However, there is a downside for me.  I do not want to choose.  Each entry was amazing.  If I randomly came across rubycommitters.org with any of the designs that had been submitted, I would think &#8220;wow, that&#8217;s a great website&#8221;.  My training through school was very analytical.  I remember when I realized that judgement of work in English / Art classes was more arbitrary compared to that of my Science and Math classes.  It was a turning point in my life.  I wanted to focus on Sciences because the path seemed more clear.</p>
<p>Now, I&#8217;ve forced myself to judge something that is very arbitrary.  Yes, there are tangible goals to this project.  Things like &#8220;which design communicates the information most effectively?&#8221;, &#8220;which will be easiest to maintain?&#8221;.  But even these questions are difficult for me to answer.  Communicating information is important, but I also want to express <em>my feelings</em>.  Every one of the designs submitted shows my feelings in some way or another.  I don&#8217;t know how to measure my feelings, so I feel like I can&#8217;t accurately measure the submissions.  How can I choose which of my feelings is correct if there is no measurement?</p>
<p>This being said, I will probably not hold a contest again.  I like sticking to code.  Code is something I know how to measure.</p>
<h2>Why are you still reading?</h2>
<p>I started this blog for entertaining my friends and myself.  I&#8217;m glad I can use my hobby and work to teach, help, and entertain others.  I feel like many people I don&#8217;t know read this, so sharing my feelings on it is now difficult because I am actually a shy person.  I wish I could repay the kindness of the people that submitted designs to this contest.  I feel like Love Bucks isn&#8217;t enough.</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2011/01/21/rubycommitters-org-winners/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

