<?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"
	>

<channel>
	<title>Common Media, Inc.</title>
	<atom:link href="http://www.commonmediainc.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.commonmediainc.com</link>
	<description>Online Communities and Web Development</description>
	<pubDate>Sun, 07 Sep 2008 18:12:50 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.1</generator>
	<language>en</language>
			<item>
		<title>Perl substitutions in Skype</title>
		<link>http://www.commonmediainc.com/2008/07/16/perl-substitutions-in-skype/</link>
		<comments>http://www.commonmediainc.com/2008/07/16/perl-substitutions-in-skype/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 16:58:27 +0000</pubDate>
		<dc:creator>pjmorse</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.commonmediainc.com/?p=38</guid>
		<description><![CDATA[We upgraded our Skype clients recently, and this afternoon made an accidental discovery of a hidden feature in Skype&#8217;s chat window.
If you make a spelling goof–or, indeed, nearly any other goof–in a message you&#8217;ve sent in Skype&#8217;s IM window, you can fix it using Perl&#8217;s substitution syntax. In other words, if I was to type
I [...]]]></description>
			<content:encoded><![CDATA[<p>We upgraded our Skype clients recently, and this afternoon made an accidental discovery of a hidden feature in Skype&#8217;s chat window.</p>
<p>If you make a spelling goof–or, indeed, nearly any other goof–in a message you&#8217;ve sent in Skype&#8217;s IM window, you can fix it using Perl&#8217;s substitution syntax. In other words, if I was to type</p>
<p><code>I sent it to you're work email</code></p>
<p>and commit that, I could then type</p>
<p><code>s/you're/your/</code></p>
<p>(which means, in Perl, &#8220;substitute the second term wherever you find the first&#8221;) it would correct my earlier gaffe, and change the timestamp to indicate that I&#8217;d edited the message.</p>
<p>This only appears to work in the most-recent message sent, of course.</p>
<p>Here it is in action:</p>
<p><a href="http://www.flickr.com/photos/flashesofpanic/2674186299/" title="skype_perl by pjmorse, on Flickr"><img src="http://farm4.static.flickr.com/3265/2674186299_1d4c6cfa05_o.png" width="462" height="245" alt="skype_perl" style="border: 1px solid black; padding: 3px;"/></a></p>
<p><!-- technorati tags start -->
<p style="text-align:right;font-size:10px;">Technorati Tags: <a href="http://www.technorati.com/tag/perl" rel="tag">perl</a>, <a href="http://www.technorati.com/tag/regular expressions" rel="tag">regular expressions</a>, <a href="http://www.technorati.com/tag/skype" rel="tag">skype</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.commonmediainc.com/2008/07/16/perl-substitutions-in-skype/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rails asset hosts and SSL</title>
		<link>http://www.commonmediainc.com/2008/07/15/rails-asset-hosts-and-ssl/</link>
		<comments>http://www.commonmediainc.com/2008/07/15/rails-asset-hosts-and-ssl/#comments</comments>
		<pubDate>Tue, 15 Jul 2008 16:43:02 +0000</pubDate>
		<dc:creator>pjmorse</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.commonmediainc.com/?p=37</guid>
		<description><![CDATA[We&#8217;ve previously mentioned the asset host setup we created for La Cucina Italiana. For the most recent revision, which includes user registration, we had to add another layer to the mix: SSL.
The standard operating procedure for Rails applications and SSL is to create the SSL host (which functions, in Apache, as another virtual host) and [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve <a href="/2008/04/09/rails-asset-hosts-scm-and-bundling/">previously mentioned</a> the asset host setup we created for <em><a href="http://www.lacucinaitalianamagazine.com">La Cucina Italiana</a></em>. For the most recent revision, which includes user registration, we had to add another layer to the mix: SSL.</p>
<p>The standard operating procedure for Rails applications and SSL is to create the SSL host (which functions, in Apache, as another virtual host) and proxy it directly to the same Ruby <code>httpd</code> you&#8217;re using to run the rest of the site, with the added request header to indicate that yes, this one came in via SSL.</p>
<p>The problem is that Rails then generates a page in which <em>all</em> the sub-requests use SSL. This is a problem when you&#8217;re using asset hosts, unless you&#8217;ve either paid extra for a certificate that covers your asset host subdomains (and why this should cost extra is beyond me, by the way, but nearly nobody does it) or are willing to force Rails to <em>not</em> securely link page assets, which leads to &#8220;mixed content&#8221; warnings from many browsers (a secure page including insecure components.)</p>
<p>The solution to this problem is <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html">in the Rails documentation</a> where the asset hosts are described in the first place: you generate the asset hosts using a proc. There are two gotchas here, though: First, you need to be using Rails 2.1.0 or better. (This, combined with <a href="http://www.commonmediainc.com/2008/06/23/solutions-for-ruby-vulnerabilities/">the Ruby problems</a> that came up last month, pushed <em>La Cucina</em> to Rails 2.1.) The example in the documentation, however, only allows for one asset host, and the <code>%d</code> solution for randomizing across four hosts doesn&#8217;t work within a proc. Here&#8217;s how to manage it, if you weren&#8217;t able to figure that out from the documentation:</p>
<pre>ActionController::Base.asset_host = Proc.new { |source, request|
  if request.ssl?
    "#{request.protocol}#{request.host_with_port}"
  else
    "#{request.protocol}a#{rand(4)}.lacucinaitalianamagazine.com"
  end
}</pre>
<p>Essentially, this turns off asset hosting for requests using SSL, which means those requests will come through the application itself. Fortunately for us, all the SSL-requiring pages don&#8217;t use content which isn&#8217;t under source control!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.commonmediainc.com/2008/07/15/rails-asset-hosts-and-ssl/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Keeping up with the Track Writers</title>
		<link>http://www.commonmediainc.com/2008/06/28/keeping-up-with-the-track-writers/</link>
		<comments>http://www.commonmediainc.com/2008/06/28/keeping-up-with-the-track-writers/#comments</comments>
		<pubDate>Sat, 28 Jun 2008 17:52:23 +0000</pubDate>
		<dc:creator>pjmorse</dc:creator>
		
		<category><![CDATA[Web development]]></category>

		<guid isPermaLink="false">http://www.commonmediainc.com/?p=36</guid>
		<description><![CDATA[Last night, just before the U.S. Olympic Team Trials–Track and Field got underway in Eugene, Oregon, CMI launched a major overhaul of the website for the Track and Field Writers of America (TAFWA).
TAFWA&#8217;s previous website, launched in 2001 or 2002, had languished several years without a visual overhaul. The design broke in several modern browsers, [...]]]></description>
			<content:encoded><![CDATA[<p>Last night, just before the <a href="http://www.eugene08.com/">U.S. Olympic Team Trials–Track and Field</a> got underway in Eugene, Oregon, CMI launched a major overhaul of the website for the <a href="http://www.tafwa.org">Track and Field Writers of America</a> (TAFWA).</p>
<p>TAFWA&#8217;s previous website, launched in 2001 or 2002, had languished several years without a visual overhaul. The design broke in several modern browsers, some of the site&#8217;s content was visibly obsolete, and all of it was difficult to update without the help of the original developers.</p>
<p>We installed <a href="http://drupal.org/">Drupal</a> for TAFWA, and installed and configured several modules to customize the popular free CMS to the organization&#8217;s specifications. It is now simple for authorized members or officers of the organization to update pages on the site and post organization news without needing to know HTML. It&#8217;s also possible for TAFWA to share particular information with its members and not the general public. We imported the membership rolls of the previous website, thus allowing certain parts of the site to require member login.</p>
<p>With its eyes on the marquee sport of the upcoming Olympic Games, TAFWA doesn&#8217;t have time to muck around with HTML tags–but they do need a site which looks as sharp and professional as the words of their journalist members. CMI helped them address both aspects of the problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.commonmediainc.com/2008/06/28/keeping-up-with-the-track-writers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Solutions for Ruby vulnerabilities</title>
		<link>http://www.commonmediainc.com/2008/06/23/solutions-for-ruby-vulnerabilities/</link>
		<comments>http://www.commonmediainc.com/2008/06/23/solutions-for-ruby-vulnerabilities/#comments</comments>
		<pubDate>Mon, 23 Jun 2008 15:57:43 +0000</pubDate>
		<dc:creator>pjmorse</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[System Administration]]></category>

		<category><![CDATA[patching]]></category>

		<category><![CDATA[phusion passenger]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[ruby enterprise edition]]></category>

		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.commonmediainc.com/?p=35</guid>
		<description><![CDATA[The recently-announced vulnerabilities in Ruby have put many of us administering Rails applications in a production space between a rock and a hard place.
To recap, there are three major &#8220;lines&#8221; of Ruby interpreters, the 1.8.6 line, the 1.8.7 line, and the 1.9 line. All of these show the vulnerability, so nearly everyone needs to update [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.ruby-lang.org/en/news/2008/06/20/arbitrary-code-execution-vulnerabilities/">recently-announced vulnerabilities in Ruby</a> have put many of us administering Rails applications in a production space between a rock and a hard place.</p>
<p>To recap, there are three major &#8220;lines&#8221; of Ruby interpreters, the 1.8.6 line, the 1.8.7 line, and the 1.9 line. All of these show the vulnerability, so nearly everyone needs to update their Ruby. (I&#8217;ll get to the exceptions later.) Rails introduces a new line of complication, because the 1.8.7 only works for Rails 2.1 and newer; if the Rails apps in question aren&#8217;t ready for Rails 2.1, or already running it (unlikely), the best route would be to continue to update in the 1.8.6 line. So there&#8217;s the rock: we need to update our Ruby.</p>
<p>The &#8220;hard place&#8221; is that the only patches so far released by the Ruby maintainers tend to produce segmentation faults, according to many who have tried them so far. That&#8217;s a long way of saying, &#8220;They don&#8217;t work.&#8221;</p>
<p>As a Rails-supporting sysadmin with, you&#8217;re left with several options, none of them comfortable. You can, in order of increasing riskiness:</p>
<ul>
<li>Wait out the Ruby maintainers and hope they release a working 1.8.6 patchlevel before your app is compromised.</li>
<li>Do crash-priority Rails upgrades on all your apps and switch to Rails 2.1, then move your Ruby to the 1.8.7 line.</li>
<li>Switch to an entirely different Ruby interpreter, like Rubinius or JRuby. (This hinges on the idea that Ruby is an interpreted language, and as long as the language is interpreted consistently there is room for any number of interpreters. Apparently JRuby and Rubinius are not affected by these vulnerabilities, only MRI, Matz&#8217;s Ruby Interpreter, which is the &#8220;standard&#8221; implementation.)</li>
<li>Switch to a different production stack entirely. For example, we&#8217;re currently using Apache 2.2 as a proxy for a Mongrel cluster in front of Rails 2.0.2 apps, a not-uncommon configuration. This could be the pressure we&#8217;d need to jump to <a href="http://www.modrails.com/">Phusion Passenger</a>, given that their <a href="http://www.rubyenterpriseedition.com">Ruby Enterprise Edition</a> claims to have <a href="http://blog.phusion.nl/2008/06/23/ruby-186-p230187-broke-your-app-ruby-enterprise-edition-to-the-rescue/">applied the security patches</a> to MRE 1.8.6 p111, and thus doesn&#8217;t introduce the segfault-inducing breaking features that the most-recent patchlevel does.</li>
</ul>
<p>I don&#8217;t know which way we&#8217;re going yet, but I&#8217;m not interested in waiting too long, and the upgrade to Rails 2.1 is going to happen sometime anyway, so Option #2 seems most likely for us.</p>
<p><em>Update:</em> Hongli Lai from Phusion assures us (in the comments) that Ruby Enterprise Edition can be used as a drop-in replacement for MRE without replacing the entire stack, moving REE up to the front of the line in the &#8220;different interpreter&#8221; option. Discussion seems to suggest to me that new official patches from the Ruby maintainers will not be coming in a timely fashion, but we are beginning to see &#8220;contributed&#8221; patched distributions emerge for e.g. FreeBSD and Debian.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.commonmediainc.com/2008/06/23/solutions-for-ruby-vulnerabilities/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Dealing with a &#8220;print Slashdotting&#8221;</title>
		<link>http://www.commonmediainc.com/2008/06/17/dealing-with-a-print-slashdotting/</link>
		<comments>http://www.commonmediainc.com/2008/06/17/dealing-with-a-print-slashdotting/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 15:27:15 +0000</pubDate>
		<dc:creator>pjmorse</dc:creator>
		
		<category><![CDATA[Business]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[database]]></category>

		<category><![CDATA[postcards]]></category>

		<category><![CDATA[scaling]]></category>

		<category><![CDATA[slashdot]]></category>

		<category><![CDATA[tripletz]]></category>

		<category><![CDATA[wired]]></category>

		<guid isPermaLink="false">http://www.commonmediainc.com/?p=34</guid>
		<description><![CDATA[If you read Wired, you may have heard of Tripletz.com. The Providence-based company allows site users to compose three-part messages on postcards, which are then mailed on consecutive days, a sort of postal Burma Shave arrangement.
When they appeared in Wired, the resulting spike in site traffic exposed some weaknesses in the site architecture. The Slashdot [...]]]></description>
			<content:encoded><![CDATA[<p>If you read <a href="http://www.wired.com/"><em>Wired</em>,</a> you may have <a href="http://www.wired.com/culture/culturereviews/multimedia/2008/05/pl_playlist?slide=10&amp;slideView=9">heard of</a> <a href="http://tripletz.com">Tripletz.com</a>. The Providence-based company allows site users to compose three-part messages on postcards, which are then mailed on consecutive days, a sort of postal <a href="http://en.wikipedia.org/wiki/Burma_Shave">Burma Shave</a> arrangement.</p>
<p>When they appeared in <em>Wired</em>, the resulting spike in site traffic exposed some weaknesses in the site architecture. <a href="http://en.wikipedia.org/wiki/Slashdot_effect">The Slashdot effect</a> is generally an entirely-online situation, but the Tripletz idea was compelling enough (and the name memorable enough) that thousands of readers followed up on the print article and visited the site. Tripletz contacted us to put out the fires. We pushed the first revision yesterday, shifting a big data-sifting operation out of the Rails code (where it was taking so long the page requests would time out) back into the database engine, where it happened in milliseconds.</p>
<p>There&#8217;s a lot to be said for the rapid production allowed by Rails, but when it comes to high-traffic situations, it&#8217;s worthwhile to be able to look at the application and figure out where bottleneck operations should be taken away from the comfortable, hip tools of Rails and given back to the gritty old database, which almost always performs them faster. Being opinionated about code can be lead to better results in some situations, but making the application work for the client means balancing the code&#8217;s poetry with pragmatism–a balance we&#8217;re happy to take on, even if we can&#8217;t take credit for the site&#8217;s undeniably cool idea.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.commonmediainc.com/2008/06/17/dealing-with-a-print-slashdotting/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A world where running shoes matter</title>
		<link>http://www.commonmediainc.com/2008/06/11/a-world-where-running-shoes-matter/</link>
		<comments>http://www.commonmediainc.com/2008/06/11/a-world-where-running-shoes-matter/#comments</comments>
		<pubDate>Wed, 11 Jun 2008 14:27:38 +0000</pubDate>
		<dc:creator>pjmorse</dc:creator>
		
		<category><![CDATA[Common Running]]></category>

		<category><![CDATA[asics]]></category>

		<category><![CDATA[marathons]]></category>

		<category><![CDATA[olympics]]></category>

		<category><![CDATA[running]]></category>

		<category><![CDATA[running shoes]]></category>

		<guid isPermaLink="false">http://www.commonmediainc.com/?p=33</guid>
		<description><![CDATA[We&#8217;ve been a long time away from our unfinished running-shoe-selection project, Common Running. We were reminded this morning of the importance of good shoe selection when we spotted this New York Times article on Hitoshi Mimura, the Asics craftsman who makes racing flats for many Olympic marathon medalists and medal contenders, including both gold medalists [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been a long time away from our unfinished running-shoe-selection project, <a href="http://commonrunning.com">Common Running</a>. We were reminded this morning of the importance of good shoe selection when we spotted <a title="Can rice lead to gold?" href="http://www.nytimes.com/2008/06/11/sports/olympics/11shoes.html?ex=1370923200&amp;en=ad6acaeba7eabc74&amp;ei=5124&amp;partner=permalink&amp;exprod=permalink">this New York <em>Times</em> article </a>on Hitoshi Mimura, the Asics craftsman who makes racing flats for many Olympic marathon medalists and medal contenders, including both gold medalists in Athens and both American Trials winners.</p>
<p>Mimura, for example, made shoes for the 2000 Sydney Olympics gold medalist, Naoko Takahashi, with soles of slightly different thicknesses to compensate for a leg-length discrepancy of 8mm–less than a centimeter, about a third of an inch, according to reporter Jere Longman.</p>
<p>Longman, a longtime follower of the sport and sometime marathoner himself, concludes the article with a vivid simile from Mimura himself on the importance of running shoes:</p>
<blockquote><p>“Samurai cannot fight without their swords,” Mimura said. “It is the same for runners and their shoes.”</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.commonmediainc.com/2008/06/11/a-world-where-running-shoes-matter/feed/</wfw:commentRss>
		</item>
		<item>
		<title>One year</title>
		<link>http://www.commonmediainc.com/2008/06/05/one-year/</link>
		<comments>http://www.commonmediainc.com/2008/06/05/one-year/#comments</comments>
		<pubDate>Thu, 05 Jun 2008 15:46:17 +0000</pubDate>
		<dc:creator>pjmorse</dc:creator>
		
		<category><![CDATA[Business]]></category>

		<category><![CDATA[anniversaries]]></category>

		<category><![CDATA[founding]]></category>

		<category><![CDATA[solvency]]></category>

		<guid isPermaLink="false">http://www.commonmediainc.com/?p=32</guid>
		<description><![CDATA[Common Media is one year old, and ready for another one.]]></description>
			<content:encoded><![CDATA[<p>There are several dates we could use as milestones in the launch of Common Media: the day we agreed, in<a href="http://www.commonkitchen.com/restaurant/US/MA/Medford/Roses-Chinese-Restaurant"> Rose&#8217;s</a>, that we&#8217;d give this startup thing a shot. The first few days of business-plan writing. The day our incorporation paperwork asserts was our start date. But the beginning of June was when we actually sat down and started coding on <a href="http://www.commonkitchen.com/">Common Kitchen</a>, the time we really became full-time employees of ourselves.</p>
<p>So it&#8217;s been a year now. It doesn&#8217;t seem like that long, and it certainly hasn&#8217;t conformed at all to the grandiose numbers we put in the (now long-obsolete) business plan. We even have direct deposit now, so we can&#8217;t claim to be signing our own paychecks anymore.</p>
<p>There are plenty of startups in the world which don&#8217;t make it to their first birthday, though, and like children, the longer a startup stays in business, the longer it&#8217;s likely to stay in business. Our first year made it more likely that we&#8217;ll finish a second, and we&#8217;re actually pretty confident about that second year right now.</p>
<p>And the business plans in our heads still have some interesting things in them, so stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.commonmediainc.com/2008/06/05/one-year/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Giving back, in a small way</title>
		<link>http://www.commonmediainc.com/2008/04/24/giving-back-in-a-small-way/</link>
		<comments>http://www.commonmediainc.com/2008/04/24/giving-back-in-a-small-way/#comments</comments>
		<pubDate>Thu, 24 Apr 2008 21:39:56 +0000</pubDate>
		<dc:creator>pjmorse</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[acts as amazon product]]></category>

		<category><![CDATA[commonmedia]]></category>

		<category><![CDATA[opensource]]></category>

		<category><![CDATA[plug-in]]></category>

		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.commonmediainc.com/?p=31</guid>
		<description><![CDATA[OK, a very small way.
Like many small companies doing development on the Web, Common Media depends heavily on free and open-source software. Part of the point of open source is that a programmer using the program (or library, or plug-in) may get in to the code and wrangle it around until it works best for [...]]]></description>
			<content:encoded><![CDATA[<p>OK, a very small way.</p>
<p>Like many small companies doing development on the Web, Common Media depends heavily on free and open-source software. Part of the point of open source is that a programmer using the program (or library, or plug-in) may get in to the code and wrangle it around until it works best for them. The obligation that comes with that freedom is to &#8220;give back&#8221; any such changes if they may be useful to the wider community. With big projects, that can mean active participation in a coding community; for smaller packages, it may just mean sending code back to the maintainer for consideration.</p>
<p>We mentioned a few weeks ago how <a title="Where we are and what we're doing" href="http://www.commonmediainc.com/2008/03/26/where-we-are-and-what-were-doing/">we tweaked a plug-in for Common Kitchen</a>. Today, that code became <a title="Commit to acts_as_amazon_product" href="http://github.com/netphase/aaap/commit/48a80e7bedbb0d5f24a31b93278419da681207bd">our first checked-in contribution</a> to an open-source project, <a href="http://www.netphase.com/">Netphase</a>&#8217;s <a title="AAAP at Github" href="http://github.com/netphase/aaap/tree/master"><code>acts_as_amazon_product</code></a>. Hopefully it won&#8217;t be the last.</p>
<p>(I also took the opportunity to  use a topical test case. Check the commit to see which magazine we test magazine searching with.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.commonmediainc.com/2008/04/24/giving-back-in-a-small-way/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rails asset hosts, SCM, and bundling</title>
		<link>http://www.commonmediainc.com/2008/04/09/rails-asset-hosts-scm-and-bundling/</link>
		<comments>http://www.commonmediainc.com/2008/04/09/rails-asset-hosts-scm-and-bundling/#comments</comments>
		<pubDate>Thu, 10 Apr 2008 00:53:02 +0000</pubDate>
		<dc:creator>pjmorse</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[System Administration]]></category>

		<category><![CDATA[asset hosts]]></category>

		<category><![CDATA[capistrano]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://www.commonmediainc.com/?p=30</guid>
		<description><![CDATA[Rails asset hosts not only made our client's site faster, they solved a problem with assets which weren't under revision control.]]></description>
			<content:encoded><![CDATA[<p>This afternoon we pushed another big revision to <a title="La Cucina Italiana USA, the Italian cooking magazine" href="http://www.lacucinaitalianamagazine.com">the <em>La Cucina Italiana</em> website</a>, which is now sharing a very small fraction of the thousands of <a href="http://www.lacucinaitalianamagazine.com/recipes">recipes</a> that magazine has in its archives. There will be more recipes coming online in the months to come, but most of the puzzles we had to solve are finished now.</p>
<p>One in particular was handling the photos which go with some recipes. Artful photography is <a title="An illustrated recipe" href="http://www.lacucinaitaliana.it/default.aspx?idPage=889&amp;idRicetta=6301">a hallmark of the <em>La Cucina Italiana</em> brand</a>, and the editorial team needed to be able to upload their images directly to the site. These photos wouldn&#8217;t be stored in the site database, but because they wouldn&#8217;t be part of our Subversion repository for the site, either, they had to live outside the normal site root in order to avoid being blown away by any site updates we deployed.</p>
<p>Enter <a title="A good explanation of asset hosts from when they entered Edge Rails" href="http://chadfowler.com/2007/2/18/edge-rails-goody-distributed-asset-hosts">Rails&#8217; asset hosts</a>. Rails <a title="The actual (sparse) documentation" href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html">allows for assets</a> (e.g. images, CSS files, or Javascript includes) to be served by a host other than that of the main site. Because the asset host definition happens at the host name level, the asset host can actually be on the same box as the main site, or it can be elsewhere in the world; you manage that at a different level of abstraction.</p>
<p>A &#8220;free&#8221; benefit of asset hosts is that by defining multiple asset hosts (<code>a0</code> through <code>a</code><em>n</em>), you can fool a user&#8217;s browser into downloading your site through a dozen or more different connections, rather than just the two it limits itself two with any single server. Rails will make each asset link use a different asset host, and the browser will open two connections to each server, not caring that they all happen to be on the same box. This gets us <a title="Running YSlow on La Cucina Italiana" href="http://www.commonmediainc.com/2008/03/27/y-be-slow/">extra YSlow points</a> (of course, we lose them again by requiring another DNS lookup for each asset host).</p>
<p>Our hangup, though, was that some assets, specifically CSS and Javascripts, <em>did</em> need to stay inside the Subversion repository and the site&#8217;s file tree.</p>
<p>Here&#8217;s the solution we came up with:</p>
<ul>
<li>Defined an Apache virtual server answering to subdomains <code>a0</code> through <code>a4</code>. (In other words, all four subdomains are the same real server, but the browser doesn&#8217;t know that; we could make them different physical servers someday.)</li>
<li>Set the site root for that server to <code>/var/www/assets/</code>.</li>
<li>Made symbolic links from <code>/var/www/assets/javascripts</code> to <code>/var/www/production/current/public/javascripts</code>, and from <code>/var/www/assets/stylesheets</code> to <code>/var/www/production/current/public/stylesheets</code>. (N.B. if you&#8217;re using Capistrano, &#8220;<code>current</code>&#8221; in your site directory is itself a symbolic link to a directory with your last site deploy.)</li>
<li>Set the upload code for recipe photos to store the uploaded images in subdirectories of <code>/var/www/assets/images</code>.</li>
</ul>
<p>This way, we get all the benefits of asset hosts for assets which are under revision control, and assets which aren&#8217;t. And the asset hosts themselves let us have assets which aren&#8217;t necessarily under revision control.</p>
<p>The free bonus here was that by using a symbolic link to the javascripts directory, <code><a href="http://code.google.com/p/bundle-fu/">bundle_fu</a></code> doesn&#8217;t have to know or understand our asset host setup; it just stores its bundled files in that same subdirectory as always, and it just works.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.commonmediainc.com/2008/04/09/rails-asset-hosts-scm-and-bundling/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Y Be Slow?</title>
		<link>http://www.commonmediainc.com/2008/03/27/y-be-slow/</link>
		<comments>http://www.commonmediainc.com/2008/03/27/y-be-slow/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 00:10:19 +0000</pubDate>
		<dc:creator>pjmorse</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[apache]]></category>

		<category><![CDATA[browser performance]]></category>

		<category><![CDATA[optimization]]></category>

		<category><![CDATA[web production]]></category>

		<category><![CDATA[YSlow]]></category>

		<guid isPermaLink="false">http://www.commonmediainc.com/2008/03/27/y-be-slow/</guid>
		<description><![CDATA[When Yahoo! released it&#8217;s YSlow application last year as a plugin for the Firebug Firefox extension (because really, what web developers don&#8217;t have Firefox installed, even if it isn&#8217;t their primary browser?) nearly everyone installed the tool and started going down the list of rules Yahoo! laid down for improving &#8220;front-end performance&#8221; on websites. Several [...]]]></description>
			<content:encoded><![CDATA[<p>When Yahoo! released it&#8217;s <a href="http://developer.yahoo.com/yslow/">YSlow</a> application last year as a plugin for the <a href="http://www.getfirebug.com/">Firebug</a> Firefox extension (because really, what web developers don&#8217;t have Firefox installed, even if it isn&#8217;t their primary browser?) nearly everyone installed the tool and started going down the <a href="http://developer.yahoo.com/performance/rules.html">list of rules</a> Yahoo! laid down for improving &#8220;front-end performance&#8221; on websites. Several people wrote up suggestions for using the output to improve Rails apps, including <a href="http://www.slashdotdash.net/articles/2007/07/31/rails-performance-tip-using-yslow">a good summary for Nginx</a>, but we&#8217;re using Apache.</p>
<p>&#8220;Front-end performance&#8221; means attacking speed as a problem between the browser and the server, and not as a problem which exists solely behind the server. We can optimize an application as much as we want, but if the browser makes thirty-five round-trips to the server fetching CSS, image files, and JavaScripts, application optimization isn&#8217;t helping much. In addition to grading apps on these fourteen points, YSlow gives a load time (in milliseconds!), and as your grade improves, you can also see the load time improving by perceptible intervals.</p>
<p>This afternoon I ran YSlow on the current development version of <a href="http://www.lacucinaitalianamagazine.com">the <em>La Cucina Italiana</em> site</a>. The initial grade was 52, an F. When I was done, it was 88, a B, and if I circumvent a dubious aspect of YSlow, it becomes a 98 A. I made only four changes: three Apache configuration tweaks and one Rails change. If you&#8217;re a <a href="http://www.rubyonrails.com">Rails</a> developer with Apache 2.2 in your stack, here are the low-hanging fruit for a better YSlow score. You can make these changes in your site configuration or within an <code>.htaccess</code> file.</p>
<p><strong>ETags:</strong> The Yahoo! <a href="http://developer.yahoo.com/performance/rules.html#etags">explanation of how ETags are important</a> is a little confusing. The summary is this: you want to turn ETags off. They&#8217;re ineffective with multiple servers (i.e. an asset-server setup) and even if everything is on one host, there are other, just as useful means of avoiding downloads of cached files. So spare yourself that many bytes per connection and turn them off. It&#8217;s a one-line fix:</p>
<p><code>FileETag none</code></p>
<p><strong>GZip components:</strong> The time saved by sending down compressed files is greater than the time spent compressing them, but only for text-based file types. (Images and PDFs are already compressed, so re-compression won&#8217;t help and might hurt.) If you&#8217;re using <a href="http://blog.codahale.com/2006/06/19/time-for-a-grown-up-server-rails-mongrel-apache-capistrano-and-you/">Coda Hale&#8217;s configuration for Apache and Mongrel</a> (and many of us are) the code for compressing text components before download is already in your Apache configuration. However, Coda&#8217;s config misses one file type which Rails seems to use for Javascript, <code>application/x-javascript</code>, so YSlow keeps dinging us for uncompressed JavaScript files. With that added, the configuration for compression looks like this:</p>
<pre>
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/javascript text/css application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html</pre>
<p>(Note that there should be only four lines there: one <code>AddOutputFilterByType</code> and then three <code>BrowserMatch</code> lines.)</p>
<p><strong>Far-future cache expiration:</strong> Yahoo! is looking for <em>really</em> far future expiration dates for cache expiration. The reasoning here is to maximize the odds that your users are arriving at your site with a &#8220;primed&#8221; cache,  i.e. one where most of your components are already loaded. By putting a way-out expiration on components, users keep those bits in their cache longer. The flip side is that filenames need to change in order to prompt the browser to load a changed file. Rails does this by automatically appending a timestamp to the filenames of many components. (Check your page source and see what is actually getting called when you load a CSS file.) Therefore, we can set our default expires header way out in the future.</p>
<p>This is a two-line addition to the Apache configuration:</p>
<p><code>ExpiresActive On<br />
ExpiresDefault "access plus 10 years"</code></p>
<p><strong>Reducing connection count:</strong> This is the tough one. Default Rails apps load a zillion (OK, seven) Javascript files and at least one but possibly many more CSS files, and that&#8217;s before we start with page images. Most browsers will only open two or three connections at a time to a given server, so all the files are waiting in line to get loaded. You can maximize the number of concurrent connections by using an asset server; this fools the browser into opening more connections by giving it more hosts to connect to. (This is like opening more Starbucks&#8217; in the same town.) That doesn&#8217;t really save you, though, and it boosts the number of DNS lookups the browser needs to run. To really cut the number of JS and CSS files, you need to bundle assets. It&#8217;s possible to bundle images, but that&#8217;s not a problem for LCI, which has only four or five images on the home page. Bundling JS and CSS is where the action is.</p>
<p>There are multiple ways to do this, including a nifty program called <a href="http://synthesis.sbecker.net/pages/asset_packager">AssetPackager</a> and the caching code <a href="http://dev.rubyonrails.org/changeset/6164">built in</a> to Rails 2.0. We went with what we saw as the simplest route, which was <a href="http://code.google.com/p/bundle-fu/"><code>bundle_fu</code></a>, but we have an eye on AssetPackager for future consideration. <code>bundle_fu</code> is a Rails plug-in which takes all the CSS and JS files for a template and concatenates them into one CSS and one JS file, sometimes even minifying the JS. It&#8217;s a quick installation, and not only does it convince YSlow to give your site a good grade on the number of connections, it also gives good grades for &#8220;Put JS at the bottom&#8221; and &#8220;Minify JS&#8221; because, hey, there&#8217;s only one file, right? This one move improved our YSlow score more than any other step.</p>
<p>The score at this point: 88 points, a high B. We&#8217;re still suffering for not having minified our JS (a little, and we&#8217;ve decided not to bother, since it&#8217;s being gzipped anyway) and for not using a <abbr title="Content Delivery Network">CDN</abbr>.</p>
<p><strong>Cheating:</strong> <a href="http://developer.yahoo.com/performance/rules.html#cdn">The CDN point</a> is one of the most hotly-contested on the YSlow report card, because most sites as small as ours see very little return on the investment of putting our site on a Content Delivery Network such as <a href="http://www.akamai.com">Akamai</a>. It&#8217;s possible, though, to get YSlow to turn a blind eye to your CDN-less-ness. Just <a href="http://developer.yahoo.com/yslow/faq.html#faq_cdn">add your own site&#8217;s domain</a> to the list of CDN servers in YSlow&#8217;s preferences. Doing that jumped our score up to 98&#8211;pretty close to perfect.</p>
<p><strong>Unfixable:</strong> One thing which may keep your site from ever having a good YSlow report is using a lot of outside components.  <a href="http://www.commonkitchen.com">Common Kitchen</a> gets dinged because its page loads include calls to two different ad networks, not to mention multiple images from Amazon on some pages and the Google Analytics code. This makes for a lot of un-bundle-able scripts, multiple DNS requests, and a lot of components where we don&#8217;t control their ETags (or lack thereof), expiration header, or compression. Of course, we can&#8217;t control their server uptime, either, so it may be that the YSlow scores are the least of our problems!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.commonmediainc.com/2008/03/27/y-be-slow/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
