

<rss version="2.0">
  <channel>
    <title>Dblock.org | Code</title>
    <description>technology website</description>
    <link>http://code.dblock.org/</link>
    <language>en-us</language>
    <image>
      <url>http://code.dblock.org/images/blog/blog.gif</url>
      <title>Dblock.org | Code</title>
      <link>http://code.dblock.org/</link>
      <width>72</width>
      <height>49</height>
    </image>
    
      <item>
       <title>Jenkins AnsiColor 0.2.1 w/ Support for Conceal Codes</title>
       <pubDate>Fri, 03 Feb 2012 13:26:50 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I just released <a href="https://wiki.jenkins-ci.org/display/JENKINS/AnsiColor+Plugin">AnsiColor 0.2.0</a> that now supports the ANSI conceal code. Conceal code 0x8 is a hacky way to hide data inside text using ANSI sequences. Jenkins uses it to annotate output with something that looks like <em>ha:&lt;long base64 string&gt;</em>. You can see this implemented in <a href="https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/console/ConsoleNote.java">ConsoleNote.java</a>. The previous version of AnsiColor produced garbage by stripping the conceal sequence, therefore revealing the content inside the conceal block (<a href="https://github.com/dblock/jenkins-ansicolor-plugin/issues/3">issue #3</a>). Fixed in <a href="https://github.com/dblock/jenkins-ansicolor-plugin/commit/c804caf8f1f785a0bd0eaf47f231a1f22b8b0356">this commit</a>. Also updated <a href="http://jansi.fusesource.org/">Jansi</a> to 1.7 – Jansi makes this plugin possible.</p>  <p>Update your Jenkins.</p></stripped></div><div><a href="http://code.dblock.org/jenkins-ansicolor-021-w-support-for-conceal-codes">Read</a></div></html>
         ]]>
       </description>
       <category>jenkins</category><category>java</category>
       <link>http://code.dblock.org/jenkins-ansicolor-021-w-support-for-conceal-codes</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/314</guid>
      </item>
     
      <item>
       <title>CarrierWave: DelayJob-Processing of Selected Versions, Revisited</title>
       <pubDate>Tue, 31 Jan 2012 14:26:52 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I’ve written about delay-processing certain image versions in <a href="http://code.dblock.org/carrierwave-delayjob-processing-of-selected-versions">this article</a>. We’ve made some progress since with a much more robust implementation. Check out <a href="http://artsy.github.com/blog/2012/01/31/delaying-carrierwave-image-processing/">this new post</a> on the Art.sy Engineering blog.</p></stripped></div><div><a href="http://code.dblock.org/carrierwave-delayjob-processing-of-selected-versions-revisited">Read</a></div></html>
         ]]>
       </description>
       <category>carrierwave</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/carrierwave-delayjob-processing-of-selected-versions-revisited</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/313</guid>
      </item>
     
      <item>
       <title>Testing w/ Analytical Gem and RSpec</title>
       <pubDate>Mon, 30 Jan 2012 21:07:14 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>We use the <a href="https://github.com/jkrall/analytical">Analytical</a> gem to include various thirdparty Javascripts in our Rails application. Our test environment was configured with dummy values in <em>config/analytical.yml</em>.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>production:</li> <li class="even">  google:</li> <li>    key: &lt;%= ENV['GOOGLE_UA'] %&gt;</li> <li class="even">  kiss_metrics:</li> <li>    js_url_key: &lt;%= ENV['KISS_METRICS_URL_KEY'] %&gt;</li> <li class="even"> </li> <li>test:</li> <li class="even">  google:</li> <li>    key: 'UA-12345'</li> <li class="even">  kiss_metrics:</li> <li>    js_url_key: 12345</li> <li class="even"> </li> <li>development:</li> </ol> </div> </div> </div>  <p>We wrote a few simple tests to make sure the analytical code is being included properly. For example, we can check whether Google Analytics is included on the splash page.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>context "google analytics" do</li> <li class="even">  it "should appear on the splash page" do</li> <li>    visit "/"</li> <li class="even">    within :css, "script[type='text/javascript']:contains('.google-analytics.com/')" do</li> <li>      page.should have_content("UA-12345")</li> <li class="even">    end</li> <li>  end</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>Or, more complicated, test whether a user ID is sent to Kissmetrics.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>context "kiss-metrics analytics" do</li> <li class="even">  it "should appear on the splash page" do</li> <li>    visit "/"</li> <li class="even">    within :css, "script[type='text/javascript']:contains('kissmetrics.com/')" do</li> <li>      page.should have_content("12345")</li> <li class="even">    end</li> <li>  end</li> <li class="even">  context "logged-in user" do</li> <li>    before(:each) do</li> <li class="even">      login_as @user</li> <li>      visit "/"</li> <li class="even">    end</li> <li>    it "should appear on the search page" do</li> <li class="even">      within :css, "script[type='text/javascript']:contains('kissmetrics.com/')" do</li> <li>        page.should have_content("12345")</li> <li class="even">      end</li> <li>    end</li> <li class="even">    it "should include user id" do</li> <li>      within :css, "script[type='text/javascript']:contains(\"identify\")" do</li> <li class="even">        page.should have_content("[\"identify\", \"#{@user.id}\"]);")</li> <li>      end</li> <li class="even">    end</li> <li>  end</li> <li class="even">end</li> </ol> </div> </div> </div>   <p>The drawback of this approach is that the Analytical code is included with every other test that doesn’t need it. With every Capybara test that runs in a browser, this hits DNS, then makes an HTTP request to Google and Kissmetrics. We cannot stub that with VCR or another gem because we’re using a real browser. But we can selectively enable Analytics without a configuration file by emptying the <em>:test</em> block in <em>config/analytical.yml </em>by configuring it before any test that needs it.</p>      <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>before :each do</li> <li class="even">    @analytical_options = ApplicationController.analytical_options.dup</li> <li>    ApplicationController.analytical_options = @analytical_options.merge({ </li> <li class="even">        :modules =&gt; [ :google, :kiss_metrics ],</li> <li>        :google =&gt; { :key =&gt; "UA-12345" },</li> <li class="even">        :kiss_metrics =&gt; { :js_url_key =&gt; 12345 }</li> <li>    })</li> <li class="even">end</li> <li>after :each do</li> <li class="even">    ApplicationController.analytical_options = @analytical_options</li> <li>end</li> </ol> </div> </div> </div>  <p>It helps to be open-source. Looking at the internals of Analytical, its options are processed inside each controller on load, then merged with request options on every request before anything is rendered. The code above updates the configuration between those two steps. Note that since we’re modifying a static we have to make sure to cleanup after ourselves.</p></stripped></div><div><a href="http://code.dblock.org/testing-w-analytical-gem-and-rspec">Read</a></div></html>
         ]]>
       </description>
       <category>rails</category><category>ruby</category><category>testing</category>
       <link>http://code.dblock.org/testing-w-analytical-gem-and-rspec</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/312</guid>
      </item>
     
      <item>
       <title>Grape API Mounted on RACK w/ Static Pages</title>
       <pubDate>Mon, 30 Jan 2012 15:54:46 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p><em>tl;dr</em> – the source is <a href="https://github.com/dblock/grape-on-rack">here</a></p>  <p>Here’s how I mount a <a href="http://github.com/intridea/grape">Grape</a> API on Rack and also serve static pages. Most useful for building a service with documentation.</p>  <p>Setup bundler with the required gems. I am using the next version of Grape (<em>frontier</em> branch and the next version of <em>rack-contrib</em> which contains <em>Rack::TryStatic </em>that we’re going to want to use). </p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>source "http://rubygems.org"</li> <li class="even"> </li> <li>gem "rack", "1.3.5"</li> <li class="even">gem "rack-contrib", :git =&gt; "https://github.com/rack/rack-contrib.git", :require =&gt; "rack/contrib"</li> <li>gem "grape", :git =&gt; "http://github.com/intridea/grape.git", :branch =&gt; "frontier"</li> </ol> </div> </div> </div>  <p>Static content goes to a new <em>public</em> folder, for example <em>public/index.html</em>.</p>  <p>Our application will need to boot with all these gems, we’ll do it Rails-style by starting with a <em>config/boot.rb</em> file. It brings in Bundler.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>require 'rubygems'</li> <li class="even">require 'bundler/setup'</li> </ol> </div> </div> </div>  <p>Lets define our Acme Grape API that will have a <em>system</em> resource that answers <em>ping</em> requests with <em>“pong”. </em>This<em> </em>goes into <em>api/api.rb.</em></p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>module Acme</li> <li class="even">  class API &lt; Grape::API</li> <li>    version 'v1', :using =&gt; :header, :vendor =&gt; 'acme', :format =&gt; :json    </li> <li class="even">    resource :system do</li> <li>      desc "Returns pong."</li> <li class="even">      get :ping do</li> <li>        "pong"</li> <li class="even">      end</li> <li>    end</li> <li class="even">  end</li> <li>end</li> </ol> </div> </div> </div>  <p>The application requires Bundler, all the gems in Gemfile and our API. Lets define it in <em>config/application.rb</em>.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>require File.expand_path('../boot', __FILE__)</li> <li class="even"> </li> <li>Bundler.require :default, ENV['RACK_ENV']</li> <li class="even"> </li> <li>require File.expand_path('../../api/api', __FILE__)</li> </ol> </div> </div> </div>  <p>Note the odd <em>File.expand_path</em> construct, borrowed from Rails, - it translates a relative path to the current file into an absolute path, there’re allowing us to run the application from any directory – useful for hosting where you never know who boots the application.</p>  <p>Continuing to borrow from Rails, we will want different environments (development, production, etc.), so it’s a good idea to keep things organized. Setup the environment in <em>config/environment.rb </em>and then load the application. </p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>ENV['RACK_ENV'] ||= :test</li> <li class="even"> </li> <li>require File.expand_path('../application', __FILE__)</li> </ol> </div> </div> </div>    <p>Finally, we need to “rackup” this whole thing in <em>config.ru</em>. We will use <em>Rack::TryStatic</em> to serve static pages when available and pass through to the Acme API otherwise.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>require File.expand_path('../config/environment', __FILE__)</li> <li class="even"> </li> <li>use Rack::TryStatic, </li> <li class="even">  :root =&gt; File.expand_path('../public', __FILE__), </li> <li>  :urls =&gt; %w[/], :try =&gt; ['.html', 'index.html', '/index.html']</li> <li class="even"> </li> <li>run Acme::API</li> </ol> </div> </div> </div>  <p>Run the application with <em>bundle exec rackup</em>.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=424&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=425&ShowThumbnail=false" width="640" height="272" /></a></p>  <p>Full <a href="https://github.com/dblock/grape-on-rack">source on Github</a>.</p></stripped></div><div><a href="http://code.dblock.org/grape-api-mounted-on-rack-w-static-pages">Read</a></div></html>
         ]]>
       </description>
       <category>rack</category><category>grape</category><category>ruby</category>
       <link>http://code.dblock.org/grape-api-mounted-on-rack-w-static-pages</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/311</guid>
      </item>
     
      <item>
       <title>How Art.sy uses Github to Build Art.sy</title>
       <pubDate>Sun, 29 Jan 2012 20:29:08 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I *heart* Github and its magical green merge button. The entire fork/pull/merge workflow has been singlehandedly responsible for a massive amount of open-source contributions by making it so easy! I wrote a quick post on how Art.sy uses Github to build Art.sy on the new Art.sy Engineering Blog, <a href="http://artsy.github.com/blog/2012/01/29/how-art-dot-sy-uses-github-to-build-art-dot-sy/">here</a>.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=422&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=423&ShowThumbnail=false" width="160" height="240" /></a></p></stripped></div><div><a href="http://code.dblock.org/how-artsy-uses-github-to-build-artsy">Read</a></div></html>
         ]]>
       </description>
       <category>github</category><category>art.sy</category>
       <link>http://code.dblock.org/how-artsy-uses-github-to-build-artsy</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/310</guid>
      </item>
     
      <item>
       <title>Octopress: Setting up a Blog and Contributing to an Existing One</title>
       <pubDate>Tue, 17 Jan 2012 15:22:24 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p><a href="http://octopress.org">Octopress</a> documentation can be quite confusing. It took me a while to understand what the heck Octopress is doing to branches and remote origins. It’s actually pretty simple, so I am going to try to un-confuse you. I will also show you a better way to contribute to an existing blog and explain what’s happening in those Rake tasks.</p>  <p>We are going to deploy a blog to Github pages, so we need a project, such as <em>username.github.com</em>. Go to Github to <a href="https://github.com/repositories/new">create one</a>. Use your username instead of “username”.</p>  <p>Next, fetch Octopress and install it locally. This gets the files from its main repository and applies a default theme.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>$ git clone git://github.com/imathis/octopress.git octopress</li> <li class="even"> </li> <li>Cloning into octopress...</li> <li class="even">remote: Counting objects: 6046, done.</li> <li>remote: Compressing objects: 100% (2420/2420), done.</li> <li class="even">remote: Total 6046 (delta 3448), reused 5549 (delta 3097)</li> <li>Receiving objects: 100% (6046/6046), 1.26 MiB | 426 KiB/s, done.</li> <li class="even">Resolving deltas: 100% (3448/3448), done.</li> <li> </li> <li class="even">$ cd octopress</li> <li>Using /home/dblock/.rvm/gems/ruby-1.9.2-p290</li> <li class="even"> </li> <li>octopress$ bundle install</li> <li class="even">Fetching source index for http://rubygems.org/</li> <li>...</li> <li class="even">Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.</li> <li> </li> <li class="even">octopress$ rake install</li> <li>## Copying classic theme into ./source and ./sass</li> </ol> </div> </div> </div>  <p>Octopress comes with some handy Rake tasks to get you started. To deploy to Github pages run <em>rake setup_github_pages</em>. When prompted, enter the GIT URL to your new repository, such as <a href="mailto:git@github.com:username/username.github.com.git">git@github.com:username/username.github.com.git</a>.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>octopress$ rake setup_github_pages</li> <li class="even">Enter the read/write url for your repository: git@github.com:username/username.github.com.git</li> <li> </li> <li class="even">Added remote git@github.com:username/username.github.com.git as origin</li> <li>Set origin as default remote</li> <li class="even">Master branch renamed to 'source' for committing your blog source files</li> <li>Initialized empty Git repository in /home/username/source/octopress/_deploy/.git/</li> <li class="even">[master (root-commit) 2a4e9e7] Octopress init</li> <li> 1 files changed, 1 insertions(+), 0 deletions(-)</li> <li class="even"> create mode 100644 index.html</li> <li> </li> <li class="even">---</li> <li>## Now you can deploy to http://username.github.com with `rake deploy` ##</li> </ol> </div> </div> </div>  <p>So what the heck happened here? It pointed our clone to our new repository. It also created a <em>_deploy</em> directory with another git repository that is going to contain everything that is being deployed. The remote in that directory is the same as the one in our <em>octopress</em> directory, but the checked out branch is <em>master</em>. Btw, we’re now on the <em>source</em> branch.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>octopress$ git remote -v</li> <li class="even">octopress    git://github.com/imathis/octopress.git (fetch)</li> <li>octopress    git://github.com/imathis/octopress.git (push)</li> <li class="even">origin    git@github.com:username/username.github.com.git (fetch)</li> <li>origin    git@github.com:username/username.github.com.git (push)</li> <li class="even"> </li> <li>octopress$ git branch</li> <li class="even">* source</li> <li> </li> <li class="even">octopress$ cd _deploy/</li> <li>octopress/_deploy$ git remote -v</li> <li class="even">origin    git@github.com:username/username.github.com.git (fetch)</li> <li>origin    git@github.com:username/username.github.com.git (push)</li> <li class="even"> </li> <li>octopress/_deploy$ git branch</li> <li class="even">* master</li> <li> </li> <li class="even">octopress/_deploy$ cd ..</li> <li> </li> <li class="even">octopress$</li> </ol> </div> </div> </div>  <p>Now is a good time to read <a href="http://octopress.org/docs/blogging/">Blogging Basics</a>. You should edit <em>_config.yml </em>with your blog name, etc. Lets create an article and deploy it.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>octopress$ rake new_post["New Post"]</li> <li class="even">Creating new post: source/_posts/2012-01-17-new-post.markdown</li> </ol> </div> </div> </div>  <p>Edit the generated file and add some text at the bottom.</p>  <p>Generate the blog. </p>    <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>octopress$ rake generate</li> <li class="even">## Generating Site with Jekyll</li> <li>directory source/stylesheets/ </li> <li class="even">   create source/stylesheets/screen.css </li> <li>Configuration from /home/dblock/source/o/octopress/_config.yml</li> <li class="even">Building site: source -&gt; public</li> <li>Successfully generated site: source -&gt; public</li> </ol> </div> </div> </div>    <p>You can also preview it with <em>rake preview</em>.</p>  <p>Before we deploy the blog, save the source and push it to Github. Note that we’re pushing our source branch. </p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>octopress$ git add .</li> <li class="even"> </li> <li>octopress$ git commit -m "Initial blog post."</li> <li class="even">...</li> <li> </li> <li class="even">octopress$ git push origin source</li> <li>Counting objects: 3927, done.</li> <li class="even">Compressing objects: 100% (1412/1412), done.</li> <li>Writing objects: 100% (3927/3927), 910.08 KiB, done.</li> <li class="even">Total 3927 (delta 2257), reused 3848 (delta 2203)</li> <li>To git@github.com:username/username.github.com.git</li> <li class="even"> * [new branch]      source -&gt; source</li> </ol> </div> </div> </div>  <p>You’ll have to repeat the above every time you make changes, to save them.</p>  <p>Deploy the blog. What this does it rake everything inside <em>_deploy</em> and push it onto the <em>master</em> branch.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>octopress$ rake deploy</li> <li class="even"> </li> <li>## Pushing generated _deploy website</li> <li class="even">Counting objects: 84, done.</li> <li>Compressing objects: 100% (74/74), done.</li> <li class="even">Writing objects: 100% (84/84), 180.40 KiB, done.</li> <li>Total 84 (delta 2), reused 0 (delta 0)</li> <li class="even">To git@github.com:username/username.github.com.git</li> <li> * [new branch]      master -&gt; master</li> </ol> </div> </div> </div>  <p>If you go to <a href="http://username.github.com">http://username.github.com</a> you should see your blog with the blog post once Github has regenerated the pages – usually a minute or two. And on <a href="https://github.com/username/username.github.com">https://github.com/username/username.github.com</a> you should be able to see the generated files on <em>master</em> along with a <em>source</em> branch with the blog source.</p>  <p>You’ll have to do this every time you want to deploy your changes.</p>  <p>So how does one start contributing to an existing Octopress blog (or yourself from a new computer)? What we want is the same setup as above, but not from scratch.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>$ git clone git@github.com:username/username.github.com.git</li> <li class="even">$ cd username.github.com</li> <li>username.github.com$ git checkout source</li> <li class="even">username.github.com$ mkdir _deploy</li> <li>username.github.com$ cd _deploy</li> <li class="even">username.github.com/_deploy$ git init</li> <li>username.github.com/_deploy$ git remote add origin git@github.com:username/username.github.com.git</li> <li class="even">username.github.com/_deploy$ git pull origin master</li> <li>username.github.com/_deploy$ cd ..</li> <li class="even">username.github.com$</li> </ol> </div> </div> </div>  <p>You’re all set. Create posts and stuff. Happy blogging with Octopress.</p></stripped></div><div><a href="http://code.dblock.org/octopress-setting-up-a-blog-and-contributing-to-an-existing-one">Read</a> | Updated 1/17/2012</div></html>
         ]]>
       </description>
       <category>octopress</category><category>technology</category><category>blog</category>
       <link>http://code.dblock.org/octopress-setting-up-a-blog-and-contributing-to-an-existing-one</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/309</guid>
      </item>
     
      <item>
       <title>Octopress: Blogging Evolution</title>
       <pubDate>Tue, 17 Jan 2012 14:47:36 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>In 93’ I wrote a Guestbook CGI in C++. Then in 94’ I made my first blogging system. I honestly don’t remember what technology it used, but I think it was some hairy PHP with a ton of issues. Data must have been stored in text files or something like that. The technology has since evolved and got hours of work poured into it. This blog’s code is <a href="https://github.com/dblock/dblog">here</a>. But don’t use it. It all works, but it’s proprietary and riddled with legacy. I would have done something very different today. So …</p>  <p>I wanted something modern, fresh, nerdy and open-source for the new Art.sy Engineering blog. Last week I played with <a href="http://octopress.org">Octopress</a>. It was confusing at first, but now feels completely natural and clean. Octopress is fully integrated with Git and Github pages, so we love it. <a href="http://artsy.github.com/">Check it out</a>. Bookmark it. Subscribe to its RSS. </p>  <p><a href="http://octopress.org/"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=421&ShowThumbnail=false" width="240" height="75" /></a></p>  <p>There’s also an <a href="http://artsy.github.com/blog/2012/01/17/responsive-layouts-with-css3/">awesome first post</a> by <a href="https://www.github.com/mmcnierney14">@mmcnierney14</a> on responsive layout with CSS3 and a collection of <a href="http://artsy.github.com/open-source/">our open-source projects</a>.</p></stripped></div><div><a href="http://code.dblock.org/octopress-blogging-evolution">Read</a> | Updated 1/17/2012</div></html>
         ]]>
       </description>
       <category>octopress</category><category>art.sy</category>
       <link>http://code.dblock.org/octopress-blogging-evolution</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/308</guid>
      </item>
     
      <item>
       <title>Paginating w/ Mongoid 2.4.0, MongoMapper and Kaminari</title>
       <pubDate>Sun, 15 Jan 2012 13:54:15 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I’ve upgraded our project from Mongoid 2.0.2 to 2.4.0. It took me a few days since our specs raised a couple of real issues. If you’re doing the same, take Mongoid from the tip of <a href="https://github.com/mongoid/mongoid/tree/2.4.0-stable">2.4.0-Stable</a>.</p>  <p>If you remember, 2.0.2 dropped pagination support and a helpful Kaminari gem took over (details <a href="http://code.dblock.org/mongoid-202-dropped-pagination-kaminari">here</a>). Once again the upgrade had a surprise, the number of items on the current page was wrong, displaying the entire count of a collection. I thought this was a bug in Mongoid and created <a href="https://github.com/mongoid/mongoid/issues/1584">#1584</a>. Turns out that the behavior of <em>count</em> on a<em> Mongoid::Criteria</em> is now aligned with the Ruby driver, which takes a curious boolean <em>skip_and_limit</em> parameter that basically says whether to take <em>limit</em> and <em>skip </em>options into account (doc <a href="http://api.mongodb.org/ruby/1.2.0/Mongo/Cursor.html#count-instance_method">here</a>). So calling <em>Foo.limit(1).count</em> may return 10 if there’re 10 Foos. The fix is to call <em>Foo.limit(1).count(true)</em>. I am going to guess this was a bug in the Mongo driver and the additional of a boolean was a clever <strike>fix</strike> hack?</p>  <p>Kaminari needed to pass the boolean, which meant adding a <em>current_page_count</em> to the Kamiari collection wrapper, pulled in <a href="https://github.com/amatsuda/kaminari/pull/194">#194</a>. Next version (probably 0.14.0) will have the fix. In the meantime, I am not super happy with my <a href="https://github.com/amatsuda/kaminari/pull/194/files">implementation</a>:</p>  <ul>   <li>It’s not possible to know whether <em>count</em> takes a parameter, <em>method(:count).arity</em> doesn’t provide enough indication for optional parameters, so the code relies on a <em>ArgumentError</em>.</li>    <li>MongoMapper needed the same fix, but is lacking a way to pass count to the driver. The current implementation calls <em>to_a</em>, which can’t be good when you just want a count.</li> </ul></stripped></div><div><a href="http://code.dblock.org/paginating-w-mongoid-240-mongomapper-and-kaminari">Read</a></div></html>
         ]]>
       </description>
       <category>mongoid</category><category>mongodb</category><category>ruby</category>
       <link>http://code.dblock.org/paginating-w-mongoid-240-mongomapper-and-kaminari</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/307</guid>
      </item>
     
      <item>
       <title>Warning: Toplevel Constant XYZ Referenced Admin:XYZ</title>
       <pubDate>Sun, 08 Jan 2012 00:09:25 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I posted <a href="http://www.ruby-forum.com/topic/1506818">this</a> to a Ruby forum a while ago.</p>  <blockquote>   <p><em>I got controllers in a namespace and controllers outside of the namespace. For example, I have a PagesController and a Admin::PagesController. When I run rspec from the top, tests pass and I get the following warning: </em><em>spec/controllers/admin/pages_controller_spec.rb:4: warning: toplevel constant PagesController referenced by Admin::PagesController. </em><em>This makes no sense. I do have a PagesController and an Admin::PagesController and specs for both that are declared properly.</em></p> </blockquote>  <p>This was only happening under Spork, so I posted <a href="http://groups.google.com/group/sporkgem/browse_thread/thread/54dfd1e885ad5373">a similar question</a> to the sporkgem list.</p>  <p>I also found a workaround, to require the Admin controllers first in <em>spec/spec_helper.rb</em>.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>Dir[File.expand_path("app/controllers/admin/*.rb")].each do |file| </li> <li class="even">  require file </li> <li>end</li> </ol> </div> </div> </div>  <p>Finally, <a href="https://twitter.com/#!/tilsammans">@tilsammans</a> figured it out. It’s the same problem as what I have: an Admin namespace and an Admin class.</p>  <blockquote>   <p><em>It was because I also had a class Admin, as well as a namespace Admin. Since Admin was a class (a model) it inherited from Object which made the top-level ApplicationController available inside the Admin namespace. The reply by Andrew White on </em><a href="http://groups.google.com/group/rubyonrails-core/browse_thread/thread/bab5e87ee10d2ecb"><em>http://groups.google.com/group/rubyonrails-core/browse_thread/thread/bab5e87ee10d2ecb</em></a><em> lead me to find the right answer. In the end I renamed Admin to AdminUser and everything fell into place.</em></p> </blockquote>  <p>This is rather counterintuitive and one would think Ruby should somehow handle this situation, but it at least makes technical sense.</p></stripped></div><div><a href="http://code.dblock.org/warning-toplevel-constant-xyz-referenced-adminxyz">Read</a></div></html>
         ]]>
       </description>
       <category>rspec</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/warning-toplevel-constant-xyz-referenced-adminxyz</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/306</guid>
      </item>
     
      <item>
       <title>Fabricating Spec Failures</title>
       <pubDate>Fri, 06 Jan 2012 21:39:10 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I love fabricators. We use the awesome <a href="https://github.com/paulelliott/fabrication">fabrication gem</a> that lets you do some pretty neat things in Rails specs.</p>  <p>For example, we have a page that lists users in alphabetical order. The retrieval is implemented in a controller.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>def index</li> <li class="even">  @users = User.asc(:name)</li> <li>end</li> </ol> </div> </div> </div>  <p>The fabricator for a User generates a global sequence to give each user a unique name.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>Fabricator(:user) do</li> <li class="even">  name { Fabricate.sequence(:name) { |i| "Joe #{i}" } }</li> <li>end</li> </ol> </div> </div> </div>  <p>To test the above-mentioned controller, we would fabricate a couple users and ensure that they are returned in the correct order. </p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>it "returns users in alphabetical order"</li> <li class="even">    user1 = Fabricate :user</li> <li>    user2 = Fabricate :user</li> <li class="even">    get :index</li> <li>    assigns(:users).should eq [ user1, user2 ]</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>What could possibly go wrong here? </p>  <p>I made a beginner mistake that just looks like someone else’s fault (specs fail depending on which order you run them). To get a failed test we fabricate 8 users before this spec is run. The next two users that are fabricated are <em>Joe 9</em> and <em>Joe 10</em>. When sorted alphabetically <em>Joe 10</em> comes before <em>Joe 9</em>, duh. It’s a good lesson in not relying on external behavior for tests – in this case we should not rely on knowing how names are generated in a fabricator to test that the users are sorted by name. Instead, we should assign names explicitly.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>it "returns users in alphabetical order"</li> <li class="even">    user1 = Fabricate :user, name: "A"</li> <li>    user2 = Fabricate :user, name: "B"</li> <li class="even">    get :index</li> <li>    assigns(:users).should eq [ user1, user2 ]</li> <li class="even">end</li> </ol> </div> </div> </div></stripped></div><div><a href="http://code.dblock.org/fabricating-spec-failures">Read</a></div></html>
         ]]>
       </description>
       <category>rspec</category><category>rails</category><category>ruby</category><category>testing</category>
       <link>http://code.dblock.org/fabricating-spec-failures</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/305</guid>
      </item>
     
      <item>
       <title>Blame it all on MongoDB</title>
       <pubDate>Tue, 20 Dec 2011 17:26:09 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>You may have read my <a href="http://code.dblock.org/mongoid-202-mongo-bson-bsonext-140-and-141">previous post</a> about the MongoDB 1.4.x Ruby driver hell.</p>  <p>We rolled back to 1.3.1 and were running fine in production for a long time. On Friday, we started seeing intermittent <em>deadlock: recursive locking</em> errors from the driver and our site was struggling to stay up. Very quickly the error rate rendered it unusable. A Google search yielded Mongo Ruby driver bug <a href="https://jira.mongodb.org/browse/RUBY-274">RUBY-274</a>, describing the exact error, which pointed a Ruby 1.9.2 threading issue <a href="http://bugs.ruby-lang.org/issues/show/4266">#4266</a>, explained in <a href="http://blog.stochasticbytes.com/2011/01/rubys-threaderror-deadlock-recursive-locking-bug/">this blog post</a>.</p>  <p>We were confused why this suddenly started happening with no apparent reason, created a ticket with our MongoDB provider <a href="http://mongohq.com">MongoHQ</a> and bounced the replica set members one-by-one as well as our app on Heroku. It did nothing.</p>  <p>Kyle, the maintainer of the Ruby driver at 10gen was replying to <a href="https://jira.mongodb.org/browse/RUBY-274">RUBY-274</a> and told us to upgrade the driver to 1.5.2. We did. All tests passed (we have over 2000) and our staging site was operating normally. But after pushing it in production where we have a replica set, we were now seeing a different error: <em>stack level too deep, </em>with <em>/app/.bundle/gems/ruby/1.9.1/gems/mongo-1.5.2/lib/mongo/util/pool.rb:72</em> on top of a cut-off stack trace. By then I haven’t gotten up from my chair for six hours straight and you bet I was thinking the Ruby driver was the worst piece of crap as I was angrily typing <a href="https://jira.mongodb.org/browse/RUBY-393">RUBY-393</a>, a knee-jerk reaction.</p>  <p>With a bit of calm and holding onto a better error someone on my team dug through this and hit the the root cause. We made a mistake in a data model and ended up with a recursion in a query. Instead of reporting an expected <em>stack level too deep</em> error for this one particular request the Ruby 1.3.1 driver blew up with <em>deadlock: recursive locking </em>and no stack trace<em>, </em>caused by a bug in Ruby 1.9.2, while other queries would immediately start failing bringing the entire site down with this error. The newer version of the driver did much better and only failed the specific query, which was much easier to diagnose. Pilot error – lessons learned. Sincere apologies to everyone involved at 10gen and MongoHQ – you guys were there when I needed you.</p>  <p>The 1.5.2 driver has been running rock solid over the week-end. I am hearing good things about it from other teams too. If you’re on 1.3.1 or 1.4.x, you should consider upgrading.</p></stripped></div><div><a href="http://code.dblock.org/blame-it-all-on-mongodb">Read</a> | Updated 12/20/2011</div></html>
         ]]>
       </description>
       <category>art.sy</category><category>mongodb</category><category>ruby</category>
       <link>http://code.dblock.org/blame-it-all-on-mongodb</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/304</guid>
      </item>
     
      <item>
       <title>Grape vs. Webmachine</title>
       <pubDate>Wed, 14 Dec 2011 03:13:28 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>One of my favorite talks at QCon 2011 was <a href="http://qconlondon.com/london-2011/presentation/Webmachine%3A+a+practical+executable+model+of+HTTP">about Webmachine</a>. I was very curious to see what those well-disciplined Erlang people had come up with. At the end of the talk I had learned that Webmachine used a resource-based model that enabled well-behaved HTTP applications, which is RESTful by definition. So I went to <a href="http://www.meetup.com/NYC-rb/events/28968101/?value=Resources%2C+For+Real+This+Time+(with+Webmachine)">NYC.rb</a> today to hear about the Ruby version of Webmachine and to write a post about how these two frameworks compare. </p>  <p>Should you build your next RESTful API with <a href="https://github.com/intridea/grape">Grape</a> or <a href="https://github.com/seancribbs/webmachine-ruby">Webmachine</a>?</p>  <p>Both frameworks as saying that you should not force HTTP onto an MVC-shaped application. Both excel at serving HTTP resources.</p>  <p>Webmachine is an executable model for HTTP, while Grape is a DSL for RESTful APIs. This means that in Webmachine you don’t perform actions – you declare resources. In Grape you declare API methods and fill out the responses. In Grape you have to be disciplined about those API methods - they should represent resources, not RPC service endpoints. More differences appear in branching: halting execution in Webmachine is done by returning appropriate answers in resource-specific functions, while halting execution in Grape is done by throwing a specific exception that carries an HTTP error code. Routing-wise, In Webmachine you map URIs to resources, while in Grape you define namespaces and method paths that translate into invisible routes. In Webmachine you implement resource callbacks, while in Grape you use procedural logic within the API method implementation. Webmachine is trying to be a complete executable model and is therefore more structured, while Grape wants you to use middleware for aspects such as ETag-based caching and doesn’t try to prevent you from jumping in the water when you don’t know how to swim.</p>  <p>We had a long discussion about this outside of Pivotal Labs with <a href="http://twitter.com/#!/seancribbs">@seancribbs</a> and <a href="http://twitter.com/#!/johnjoseph">@johnjoseph</a> (who even mentioned Prolog at some point). It helped me frame my opinion around mostly philosophical differences between the two frameworks. I could very well use Webmachine to build an API and be very happy with it (I would not be happy building an API in Rails). I would grant Webmachine an advantage over purity from the developer’s perspective – it’s harder to step outside of the programming model. I would grant Grape an advantage over favoring the API consumer, since it focuses on the expressiveness of the API. For example, Grape now has self-introspection for automatically generating documentation, a feature that seems harder and maybe even unnatural to build for Webmachine.</p>  <p>Fundamentally, Webmachine declares resources served via HTTP, while Grape declares an API. Your choice?</p></stripped></div><div><a href="http://code.dblock.org/grape-vs-webmachine">Read</a></div></html>
         ]]>
       </description>
       <category>webmachine</category><category>grape</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/grape-vs-webmachine</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/303</guid>
      </item>
     
      <item>
       <title>Measuring Activity in Open-Source Projects using Github Network Graph</title>
       <pubDate>Mon, 12 Dec 2011 02:05:57 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>When choosing to use an open source project you might want to know whether it’s still developed or at least maintained. For Ruby projects I used to check Rubygems release dates. Here’s <a href="https://rubygems.org/gems/grape">Grape’s</a>.</p>  <blockquote>   <p><a href="http://code.dblock.org/ShowPicture.aspx?id=413&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=414&ShowThumbnail=false" width="102" height="79" /></a></p> </blockquote>  <p>Nothing for the last six months? Not very good – there hasn’t been a release for a while, but that’s more a tribute to the stability of the project.</p>  <p>You could check the number of forks and watchers for projects on Github.</p>  <blockquote>   <p><a href="http://code.dblock.org/ShowPicture.aspx?id=415&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=416&ShowThumbnail=false" width="96" height="34" /></a></p> </blockquote>  <p>It measures the project’s popularity quite well, but maybe not its activity.</p>  <p>My favorite way of measuring a project’s activity is to look at the Github network graph. It’s an <a href="https://github.com/blog/39-say-hello-to-the-network-graph-visualizer">amazing and useful feature</a>. Here’s <a href="https://github.com/intridea/grape/network">Grape’s</a>.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=417&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=418&ShowThumbnail=false" width="449" height="179" /></a></p>  <p>The project is clearly happening. But you can see how this is all over the place – that’s a typical picture for open-source efforts: few core and relatively irregular contributors, long branches and abandoned ends for feature attempts that don’t get merged.</p>  <p>When a small group of people truly collaborates, their feature branches make it into master most of the time. They are also constantly picking up commits from the source. What does a really dense collaborative project look like? Here’s a picture from one of our private repositories. If yours looks like this, you got a team!</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=419&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=420&ShowThumbnail=false" width="447" height="125" /></a></p>        <p>Maybe someone can use this idea to build a nice feature to measure a Github <em>project density</em>?</p></stripped></div><div><a href="http://code.dblock.org/measuring-activity-in-open-source-projects-using-github-network-graph">Read</a></div></html>
         ]]>
       </description>
       <category>github</category><category>open source</category>
       <link>http://code.dblock.org/measuring-activity-in-open-source-projects-using-github-network-graph</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/302</guid>
      </item>
     
      <item>
       <title>Grape: Describing and Documenting an API</title>
       <pubDate>Sun, 11 Dec 2011 15:03:39 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>Building a software platform is not just an investment in the future, it’s a software architecture philosophy. A proper API is a manifestation of some of the core principles of domain driven design – spend a lot of time figuring out what your domain is, then build software that represents the immutable concepts behind an API and, finally, implement different businesses that can quickly thrive, die or pivot, on top of that. We’ve spent considerable amounts of time iterating on our own API and are constantly improving the artifacts around it as we learning from good examples of Twilio, Stripe, etc. </p>  <p>There’re several ways to build an API reference: entirely by hand, generated from code comments or by adding metadata at runtime. The first one is inanity and the second one is not leveraging the magic of Ruby. Hence I am a huge fan of the latter, as it offers the best chance of creating something that actually reflects code. </p>  <p>You can now do this in <a href="https://github.com/intridea/grape">Grape</a> with <em>desc</em> blocks.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li># DELETE /api/v1/thing/:id</li> <li class="even">desc "Delete an existing thing.", {</li> <li>  :params =&gt; {</li> <li class="even">    "id" =&gt; { :description =&gt; "Thing id.", :required =&gt; true }</li> <li>  }</li> <li class="even">}</li> <li>delete ":id" do</li> <li class="even">  thing = Thing.find(params[:id])</li> <li>  error!('Thing Not Found', 404) unless thing</li> <li class="even">  thing.destroy</li> <li>  thing.as_json</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>Aside from the description passed to <em>desc</em>, you can specify a hash with anything in it. There’re a few conventions, such as <em>:params</em>, which will merge with any values specified in the URL of the API call.</p>  <p>We can introspect the API at runtime, adding a Rake task, for example, that lists all API calls with their parameters.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>namespace :api do</li> <li class="even">  desc "Displays all API methods."</li> <li>  task 'routes' =&gt; :environment do</li> <li class="even">    Api.routes.each do |route|</li> <li>      route_path = route.route_path.gsub('(.:format)', '').gsub(':version', route.route_version)</li> <li class="even">      puts "#{route.route_method} #{route_path}"</li> <li>      puts " #{route.route_description}" if route.route_description</li> <li class="even">      if route.route_params.is_a?(Hash)</li> <li>        params = route.route_params.map do |name, desc|</li> <li class="even">          required = desc.is_a?(Hash) ? desc[:required] : false</li> <li>          description = desc.is_a?(Hash) ? desc[:description] : desc.to_s</li> <li class="even">          [ name, required, "   * #{name}: #{description} #{required ? '(required)' : ''}" ]</li> <li>        end</li> <li class="even">        puts "  parameters:"</li> <li>        params.each { |p| puts p[2] }</li> <li class="even">      end</li> <li>    end</li> <li class="even">  end</li> <li>end</li> </ol> </div> </div> </div>  <p>Notice how we’ve used the required option for parameters – it’s, once again, a convention. Grape doesn’t care – it’s pure metadata attached to a route. You can create similar conventions in your own API – we have some “partner” and “admin” APIs that we’ve marked in a similar manner.</p>  <p>This is now in the <a href="https://github.com/intridea/grape/tree/frontier">frontier branch of Grape</a>, which is Grape v.next. Live on the edge.</p></stripped></div><div><a href="http://code.dblock.org/grape-describing-and-documenting-an-api">Read</a></div></html>
         ]]>
       </description>
       <category>grape</category><category>art.sy</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/grape-describing-and-documenting-an-api</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/301</guid>
      </item>
     
      <item>
       <title>Pushing Assets to S3 w/ Rake: Versioning and Cache Expiration</title>
       <pubDate>Sat, 10 Dec 2011 20:19:07 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>A while ago I <a href="http://code.dblock.org/rails-s3-cloudfront-jammit-heroku-100">wrote</a> about how we package and push Rails assets to Amazon S3. We version assets with the GIT hash – varying the assets by URL enables setting indefinite cache expiration and works well with a CDN. In that post you could find a Rake task that would delete any old assets and replace them with newer assets. It’s time for a revision with some new features.</p>  <p>The first problem we have solved is how long it takes to sync contents between a local folder and S3. The old task fetched the entire bucket file list, which grew quite a bit over time. The S3 API supports a <em>prefix</em> option.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>s3i.incrementally_list_bucket(to, prefix: "assets/") do |response|</li> <li class="even">  response[:contents].each do |existing_object|</li> <li>    ...</li> <li class="even">  end</li> <li>end</li> </ol> </div> </div> </div>    <p>The second issue is with asset rollback. We deploy assets to S3 and then code to Heroku. The asset deployment deletes the old assets. There’s a small window in which we have old code and new assets, which is obviously not okay. We’re actually saved by CloudFront which keeps a cache for extended periods of time. A solution is to keep two copies of the assets online: current and previous. The code preserves the most recent copy by looking at the <em>:last_modified</em> field of the S3 object.</p>  <p>Here’s the task with some shortcuts and a <a href="https://gist.github.com/1456181">complete task as a gist</a>.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li># uploads assets to s3 under assets/githash, deletes stale assets</li> <li class="even">task :uploadToS3, [ :to ] =&gt; :environment do |t, args|</li> <li>  from = File.join(Rails.root, 'public/assets')</li> <li class="even">  to = args[:to]</li> <li>  hash = (`git rev-parse --short HEAD` || "").chomp</li> <li class="even">  </li> <li>  logger.info("[#{Time.now}] fetching keys from #{to}")</li> <li class="even">  existing_objects_hash = {}</li> <li>  existing_assets_hash = {}</li> <li class="even">  s3i.incrementally_list_bucket(to, prefix: "assets/") do |response|</li> <li>    response[:contents].each do |existing_object|</li> <li class="even">      existing_objects_hash[existing_object[:key]] = existing_object</li> <li>      previous_asset_hash = existing_object[:key].split('/')[1]</li> <li class="even">      existing_assets_hash[previous_asset_hash] ||= DateTime.parse(existing_object[:last_modified]) </li> <li>    end</li> <li class="even">  end</li> <li> </li> <li class="even">  logger.info("[#{Time.now}] #{existing_assets_hash.count} existing asset(s)")</li> <li>  previous_hash = nil</li> <li class="even">  existing_assets_hash.each_pair do |asset_hash, last_modified|</li> <li>    logger.info(" #{asset_hash} =&gt; #{last_modified}")</li> <li class="even">    previous_hash = asset_hash unless (previous_hash and existing_assets_hash[previous_hash] &gt; last_modified)</li> <li>  end</li> <li class="even">  logger.info("[#{Time.now}] keeping #{previous_hash}") if previous_hash</li> <li> </li> <li class="even">  logger.info("[#{Time.now}] copying from #{from} to s3:#{to} @ #{hash}")</li> <li>  Dir.glob(from + "/**/*").each do |entry|</li> <li class="even">    next if File::directory?(entry)</li> <li>    File.open(entry) do |entry_file|</li> <li class="even">      content_options = {}</li> <li>      content_options['x-amz-acl'] = 'public-read'</li> <li class="even">      content_options['content-type'] = MIME::Types.type_for(entry)[0]</li> <li>      key = 'assets/'</li> <li class="even">      key += (hash + '/') if hash</li> <li>      key += entry.slice(from.length + 1, entry.length - from.length - 1)</li> <li class="even">      existing_objects_hash.delete(key)</li> <li>      logger.info("[#{Time.now}]  uploading #{key}")</li> <li class="even">      s3i.put(to, key, entry_file, content_options)</li> <li>    end</li> <li class="even">  end</li> <li>  </li> <li class="even">  existing_objects_hash.keys.each do |key|</li> <li>    next if previous_hash and key.start_with?("assets/#{previous_hash}/")</li> <li class="even">    puts "deleting #{key}"</li> <li>    s3i.delete(to, key)</li> <li class="even">  end</li> <li>end</li> </ol> </div> </div> </div>  <p>Since we’re versioning assets with a GIT hash in the URL, another improvement is to set cache expiration to something longer.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>content_options['cache-control'] = "public, max-age=#{365*24*60*60}"</li> </ol> </div> </div> </div></stripped></div><div><a href="http://code.dblock.org/pushing-assets-to-s3-w-rake-versioning-and-cache-expiration">Read</a></div></html>
         ]]>
       </description>
       <category>javascript</category><category>css</category><category>git</category><category>cloudfront</category><category>s3</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/pushing-assets-to-s3-w-rake-versioning-and-cache-expiration</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/300</guid>
      </item>
     
      <item>
       <title>Serving Compressed Rails Assets from S3 via Cloudfront</title>
       <pubDate>Fri, 09 Dec 2011 04:56:19 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I wrote about how we do asset packaging with Rails, how we Jammit and push them to S3 in <a href="http://code.dblock.org/rails-s3-cloudfront-jammit-heroku-100">this post</a>. We’ve had a few surprises since then, one that had to do with compressed assets. </p>  <p>If a browser sends an <em>Accept-Encoding: gzip </em>header for a resource that has both an uncompressed and a compressed copy (eg. <em>client.js</em> and <em>client.js.gz</em>), the server can respond with the compressed version of the file along with the original Content-Type (eg. <em>text/css</em>) and <em>Content-Encoding: gzip</em> headers. This is called content negotiation. Unfortunately S3 has very poor negotiation skills. CloudFront CDN does better, but only if the server behind it supports it. So putting a CloudFront in front of S3 produces the same effect and Amazon recommends using a custom origin server (a fancy word for another web server), other than S3 if you want to enable content negotiation. We’d rather not serve static assets from Heroku because it requires checking them into source control. And we’d rather not add a web server that we have to maintain – too much infrastructure when multiplied by the number of developers.</p>  <p>The solution is, as usual, to <strike>monkey-patch</strike> extend rails. We’re going to tell our Rails application to serve a compressed file if the browser includes the right headers by rendering an URL to the compressed version.</p>  <p>In Rails 3.0 (your mileage will vary for 3.1) paths to assets are written via <a href="http://api.rubyonrails.org/v3.0.9/classes/ActionView/Helpers/AssetTagHelper.html">ActionView::Helpers::AssetTagHelper</a>’s <em>path_to_javascript</em> and <em>path_to_stylesheet</em>. We can figure out browser capabilities by examining <em>request.env['HTTP_ACCEPT_ENCODING']</em> and rewrite those URLs to our liking. </p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>module ActionView</li> <li class="even">  module Helpers</li> <li>    module AssetTagHelper</li> <li class="even">      def accept_encoding?(encoding)</li> <li>        (request.env['HTTP_ACCEPT_ENCODING'] || '').split(',').include?(encoding)</li> <li class="even">      end</li> <li>      def rewrite_path_to_gzip?(source)</li> <li class="even">        (! config.asset_host.blank?) and (source =~ /assets\//) and accept_encoding?('gzip')</li> <li>      end</li> <li class="even">      def path_to_javascript(source)</li> <li>        source = rewrite_path_to_gzip(source) if rewrite_path_to_gzip?(source)</li> <li class="even">        compute_public_path(source, 'javascripts', 'js')</li> <li>      end</li> <li class="even">      def path_to_stylesheet(source)</li> <li>        source = rewrite_path_to_gzip(source) if rewrite_path_to_gzip?(source)</li> <li class="even">        compute_public_path(source, 'stylesheets', 'css')</li> <li>      end</li> <li class="even">      def rewrite_path_to_gzip(source)</li> <li>        source + ".cgz"</li> <li class="even">      end</li> <li>    end</li> <li class="even">  end</li> <li>end</li> </ol> </div> </div> </div>  <p><em><a href="https://gist.github.com/1451946">config/initializers/asset_tag_helper.rb and spec/initializers/rails/asset_tag_helper_spec.rb</a></em><em></em></p>  <p>The .cgz extension replaces the .gz extension to workaround a <a href="http://stackoverflow.com/questions/1235116/safari-and-gzip">bug in Safari</a>. The <em>rewrite_path_to_gzip?</em> check ensures that we’re rendering something under <em>assets</em> and that we’re using an external server (not in development). Your condition may be different.</p>  <p>Finally, we must set the proper content encoding headers when pushing the assets to S3. Here’s the meat of our Rake task.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>File.open(entry) do |entry_file|</li> <li class="even">  content_options = {}</li> <li>  content_type = MIME::Types.type_for(entry)[0]</li> <li class="even">  content_options['x-amz-acl'] = 'public-read'</li> <li>  if entry.ends_with?('.gz')</li> <li class="even">    uncompressed_entry = entry[0..-4]</li> <li>    entry = "#{uncompressed_entry}.cgz"</li> <li class="even">    content_type = MIME::Types.type_for(uncompressed_entry)[0]</li> <li>    content_options['content-encoding'] = 'gzip'</li> <li class="even">  end</li> <li>  content_options['content-type'] = content_type.to_s</li> <li class="even">  key = 'assets/'</li> <li>  key += entry.slice(from.length + 1, entry.length - from.length - 1)</li> <li class="even">  s3i.put(to, key, entry_file, content_options)</li> <li>end</li> </ol> </div> </div> </div>  <p>Note that the Content-Type for a <em>.css.gz</em> file is the same as for a <em>.css</em> file (<em>text/css</em>) and that Content-Encoding is set to <em>gzip</em>.</p>  <p>To verify that your implementation worked, examine the page source and make sure you got a <em>.css.cgz</em> link for stylesheets. Then, navigate to the <em>.css.cgz</em> URL – it should display an uncompressed CSS<em>.</em></p>  <p>For purists, this implementation is really bad. A browser may request a web page with <em>Accept-Encoding: gzip</em>, but then request the CSS from another server without it. I am going to decide that this never happens in real life.</p></stripped></div><div><a href="http://code.dblock.org/serving-compressed-rails-assets-from-s3-via-cloudfront">Read</a> | Updated 12/9/2011</div></html>
         ]]>
       </description>
       <category>cloudfront</category><category>s3</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/serving-compressed-rails-assets-from-s3-via-cloudfront</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/299</guid>
      </item>
     
      <item>
       <title>Sensations Fortes: Deploying Software from Airplanes</title>
       <pubDate>Wed, 30 Nov 2011 23:44:30 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I remember bringing a 14Kbps modem from the U.S. back to Europe in mid-nineties. I couldn’t wait to stick it into the ISA slot on my 486 and was underestimating how much trouble it was going to be to occupy my parent’s phone line all the time or discussing the phone bill at the end of the month. Things have changed in 15 years – we finally have Internet on airplanes for about ten bucks a flight. </p>  <p>So I just redeployed our production site with a few minor bug fixes from my seat on a Delta flight to Miami – going to Art Basel with the entire Art.sy team!</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=409&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=410&ShowThumbnail=false" width="483" height="235" /></a></p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=411&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=412&ShowThumbnail=false" width="460" height="138" /></a></p></stripped></div><div><a href="http://code.dblock.org/sensations-fortes-deploying-software-from-airplanes">Read</a></div></html>
         ]]>
       </description>
       <category>deployment</category><category>art.sy</category><category>heroku</category>
       <link>http://code.dblock.org/sensations-fortes-deploying-software-from-airplanes</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/298</guid>
      </item>
     
      <item>
       <title>dotNetInstaller 2.0 Released</title>
       <pubDate>Thu, 24 Nov 2011 17:57:16 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I’ve released DNI 2.0 today. It’s a major release with a new HTML bootstrapper, better elevation support, Windows 8, etc. It has been stable for quite a while now and a few people are using this build in production.</p>  <p><img src="http://download.codeplex.com/Download?ProjectName=dotnetinstaller&DownloadId=94426&Build=18301" /></p>  <p><a href="http://dotnetinstaller.codeplex.com/releases/view/50143">http://dotnetinstaller.codeplex.com/releases/view/50143</a></p>  <p>Build 2.0.81.0</p>  <p>#7968: Support elevation as a subsequent command within the bootstrapper. First UI shows un-elevated, but clicking install elevates. (dotNetInstaller only)    <br />#8005: Added a new os_filter type 'greater than' (+) and 'less than' (-).     <br />#6289: Added a new setup bootstrapper, htmlInstaller, driven by an HTML-based UI engine.     <br />#6618: Added #STARTPATH, #STARTEXE and #STARTFILENAME substitution variables.     <br />#6955: Added #OSLANGID substitution variable, operating system language ID.     <br />#6620: Added #OSLOCALE substitution variable, operating system ISO language and region (eg. en-US).     <br />#6956: #LANGID and #LANGUAGE are always set to the value in the currently executing configuration. #LANGUAGE may be empty, while #LANGID will default to the operating system value.     <br />#6604: InstallerEditor no longer needs a configuration file to link a bootstrapper and the configuration does not need to be saved before creating an exe.     <br />#6798: InstallerEditor will display file names when embed files are missing during linking.     <br />#4884: InstallerEditor will notice that a configuration file has changed on disk and offer to reload it.     <br />#6786: Bootstrapper will return a 3010 exit code when a reboot was required.     <br />#6786: Added /noreboot to the bootstrapper to suppress actual reboot when required. Bootstrapper will simply return a 3010 exit code in this case.     <br />#7004: The user-defined browse control will always return paths without the trailing backslash except for drive paths (eg. C:\).     <br />#6730: InstallerEditor displays a * next to field names that are required and displays an error if the user tries to delete the value.     <br />#7148: Added support for Windows 2008 SP2 and Windows 7 SP1.     <br />#7252: Enabled Visual Styles: modified default manifests with a dependency on Microsoft.Windows.Common-Controls 6.0.     <br />#7382: Added disable<i>wow64</i>fs_redirection at setup configuration and component level to run native x64 Windows applications (cmd, regedit, etc) from dotNetInstaller.     <br />#7916: Added MUI support with MuiUser (preferred language set for the user) and MuiSystem (preferred language set for the system) options in configuration lcidtype.     <br />#8277: Language selector dialog in dotNetInstaller will automatically select the operating system language if available.     <br />#8256: Added /noRunOnReboot to the bootstrapper to suppress actually writing the RunOnReboot registry key.     <br />#272583: Added support for Windows 8.</p></stripped></div><div><a href="http://code.dblock.org/dotnetinstaller-20-released">Read</a></div></html>
         ]]>
       </description>
       <category>dotnetinstaller</category><category>msi</category>
       <link>http://code.dblock.org/dotnetinstaller-20-released</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/297</guid>
      </item>
     
      <item>
       <title>Me in Wired: Art.sy’s ‘Genome’ Predicts What Paintings You Will Like</title>
       <pubDate>Thu, 24 Nov 2011 01:07:14 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>Vanity aside, Wired published a very well written article on Art.sy [<a href="http://www.wired.com/magazine/2011/11/mf_artsy/all/1">link</a>] in the December issue. I think it’s objective, describes the company vision well, and the story about a mobile prototype is completely accurate. </p>  <p>Also, got to love the photo taken at Haunch of Venison!</p>  <p><a href="http://www.wired.com/magazine/2011/11/mf_artsy/all/1"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=408&ShowThumbnail=false" width="240" height="237" /></a></p>  <p>We’ll be at Miami Basel Nov 30th-Dec 3rd, don’t forget to say hi!</p></stripped></div><div><a href="http://code.dblock.org/me-in-wired-artsys-genome-predicts-what-paintings-you-will-like">Read</a> | Updated 11/24/2011</div></html>
         ]]>
       </description>
       <category>press</category><category>art.sy</category><category>me me</category>
       <link>http://code.dblock.org/me-in-wired-artsys-genome-predicts-what-paintings-you-will-like</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/296</guid>
      </item>
     
      <item>
       <title>Favorite Talks from QConfSF 2011</title>
       <pubDate>Wed, 23 Nov 2011 04:41:52 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p><a href="http://code.dblock.org/ShowPicture.aspx?id=406&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=407&ShowThumbnail=false" width="162" height="107" /></a></p>  <p>My first QCon, <a href="http://qconsf.com/sf2011/">QConSF ‘11</a> was very good. I’ve been watching <a href="http://infoq.com">InfoQ</a> for a very long time and wanted to go to QCon ever since. </p>  <p>What I loved about this conference is that it was mostly technical in nature and that the best speakers were hands-on industry practitioners. I also greatly enjoyed the fact that most attendees were architect-level engineers, which made for well balanced conversations over the frequently supplied drinks. The rare talks that I didn’t like were given by sponsoring companies’ PMs. Yawn.</p>  <p>The first day was like climbing a mountain of infinite wisdom. It started with a panel of software gurus that <a href="http://qconsf.com/sf2011/presentation/Objects+On+Trial">put objects on trial</a>. I’ve been unlearning OOP for the last year of writing Ruby, hence I found myself completely in sync with the prosecution. Along with a number of Russians in the crowd I was particularly touched by the Souz capsule vs. the U.S.A. Shuttle analogy on class reuse. I lived near the Gagarin Square in Moscow. Tears were shed. The Russian space program was a great example of throw-away technology that turned out to be a lot cheaper to manufacture and enabled faster innovation. </p>  <p>There was an entire track dedicated to the concept of beautiful code. I got my Ruby CR/LF alignment porn at <a href="http://twitter.com/#!/guilhermecaelum">guilhermecaelum's</a> talk and disagreed with about everything else during that track. In general, I think that code is more like a child than a painting. Code might first be cute, but it eventually grows into a complete being with evolved needs that requires additional complexity and structure. You can still teach it new things, but it gets incrementally harder. In contrast, each extra minute you put into a baby’s early days pays off big dividends in the long term.</p>  <p>I frowned during most of <a href="http://qconsf.com/sf2011/presentation/Things+I+Wish+I%27d+Known">Rod Johnson’s keynote</a> on Thursday. I certainly didn’t expect to hear a call to entrepreneurship at QCon. Much like great engineers often make terrible managers, they often make awful CEOs and CTOs. Running a business is a people, not a technology problem. </p>  <p>Then I went to the <a href="http://qconsf.com/sf2011/speaker/Joshua+Kerievsky">Lean Startup</a> talk, where <a href="http://twitter.com/#!/joshuakerievsky">@joshuakerievsky</a> confirmed that lean principles work well for the kind of social location-based coupon technology that thousands are building these days, because most of it will be thrown away anyway as these companies crash and burn. More seriously, I assume some of lean concepts speak poorly to many experienced engineers. Should we validate an idea without writing any code when possible? Yes. Should we write the bare minimum to produce a prototype that learns about the market? No. Prototypes turn into real products much faster in the hands of a business than engineers turn them into solid implementations. Pain, suffering, famine and death ensue. We need to both build high quality code from day one, and build it fast, in order to succeed when we hit product-market fit and the business explodes. That’s also why you should be hiring fewer people from the highest grade of software developer A-list.</p>  <p>I watched <a href="http://twitter.com/#!/emcooke">@emcooke's</a> excellent <a href="http://qconsf.com/sf2011/presentation/Building+a+Great+Web+API">Web API talk</a> next. Evan came to <a href="http://generalassemb.ly">GA</a> a few weeks ago and gave a short version of the talk from a couch to a few techies. This is exactly the kind of talks I wanted to see more of. The guy had his hands in the code. He succeeded at building an API that people loved. He had priceless advice on each and every slide.</p>  <p>I really enjoyed <a href="http://fr.twitter.com/#!/stevevinoski">@stevevinoski’s</a> the <a href="http://qconsf.com/sf2011/presentation/Webmachine%3A+a+practical+executable+model+of+HTTP">talk on Webmachine</a>. I’ve never written anything in Erlang. At first I saw <a href="http://wiki.basho.com/Webmachine.html">Webmachine</a> as a silly framework for declarative RESTful programming. But as the talked got into more complex issues a light bulb lit in my head and I think I totally got it. It’s unlikely that I’ll ever get to use this framework, but I went from being a skeptic to actually learning something.</p>  <p><a href="http://twitter.com/#!/daniel_jacobson">@daniel_jacobson</a> from Netflix described the <a href="http://qconsf.com/sf2011/presentation/Techniques+for+Scaling+the+Netflix+API+in+the+Cloud">recent evolution of the Netflix API</a>. This was mostly about the internal API that thousands of devices use. They chose to create an API variation for every device a longtime ago and are now bringing scripting-like functionality to a middle-tier, server-side. Think of it as a server-side proxy for your API where you execute sequences of operations that are device-specific. Instead of performing chatty operations between a client and a server, you compile and execute them on the proxy.</p>  <p>There was a <a href="http://qconsf.com/sf2011/presentation/Dart%2C+a+new+programming+language+for+structured+web+programming">keynote on Dart</a> on Friday. Why you would want to have type-checking during development and turn it off at runtime is beyond me. Does a thousand smart developers make an awesome language? Does a tree fall in the woods?</p>  <p>Fortunately <a href="http://twitter.com/#!/rauchg">@rauchg</a> killed it in a <a href="http://qconsf.com/sf2011/presentation/Realtime+Web+Apps+with+HTML5+WebSocket+and+Beyond">live coding session for Socket.IO w/ node.js</a>. He built a chatty client-server and OMG, he types way faster than me.</p>  <p>There was a nice NoSQL applications panel where each vendor tried to sell each-other’s products. It was so polite!</p>  <p>Last, but not the least, I met with a bunch of old friends that live in SF and even got to touch a Kindle Fire warm out of Amazon!</p></stripped></div><div><a href="http://code.dblock.org/favorite-talks-from-qconfsf-2011">Read</a></div></html>
         ]]>
       </description>
       <category>conferences</category><category>technology</category><category>architecture</category><category>people</category>
       <link>http://code.dblock.org/favorite-talks-from-qconfsf-2011</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/295</guid>
      </item>
     
      <item>
       <title>Oh BetaBeat: Me in New York’s 20 Most Poachable Techies</title>
       <pubDate>Thu, 17 Nov 2011 20:06:42 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I mean, I am flattered to be <a href="http://www.betabeat.com/2011/11/17/new-york-techs-20-most-poachable-players/#slide20">#20 of the most poachable techies in NYC list</a>, and you got about half of your facts right (eg. <a href="http://github.com/dblock">my Github account</a>) but seriously?</p></stripped></div><div><a href="http://code.dblock.org/oh-betabeat-me-in-new-yorks-20-most-poachable-techies">Read</a></div></html>
         ]]>
       </description>
       <category>art.sy</category><category>jobs</category><category>people</category>
       <link>http://code.dblock.org/oh-betabeat-me-in-new-yorks-20-most-poachable-techies</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/294</guid>
      </item>
     
      <item>
       <title>At QConSF 2011</title>
       <pubDate>Thu, 17 Nov 2011 01:13:46 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I’m at <a href="http://qconsf.com/sf2011/">QConSF 2011</a>.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=404&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=405&ShowThumbnail=false" width="240" height="94" /></a></p>  <p>The keynote was in the form of a trial with a dressed judge and witnesses. A penguin, a ball and a UML object were the accused. Brian Foote, a software ethnologist, talked about <i>reuse</i>. He argued that the American reusable space shuttle wasted a ton of energy vs. the Soviet Союз space program that left everything except a small module with cosmonauts behind. That's enough energy and metal to build out a Stanley Kubrick space wheel a mile in diameter. Joshua Kerievsky made a parallel between object inheritance and real life. Having a vasectomy to avoid having children is the kind of discipline objects could use.</p></stripped></div><div><a href="http://code.dblock.org/at-qconsf-2011">Read</a></div></html>
         ]]>
       </description>
       <category>conferences</category><category>technology</category><category>architecture</category>
       <link>http://code.dblock.org/at-qconsf-2011</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/293</guid>
      </item>
     
      <item>
       <title>Me @ Silicon Alley Talent Fair on NY1</title>
       <pubDate>Mon, 14 Nov 2011 19:42:27 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I got 5 seconds around 1m20.</p>  <p><a href="http://www.ny1.com/content/ny1_living/consumer_watch/150699/startups-provide-non-traditional-spin-to-job-fairs">http://www.ny1.com/content/ny1_living/consumer_watch/150699/startups-provide-non-traditional-spin-to-job-fairs</a></p></stripped></div><div><a href="http://code.dblock.org/me-silicon-alley-talent-fair-on-ny1">Read</a> | Updated 11/14/2011</div></html>
         ]]>
       </description>
       <category>art.sy</category><category>people</category>
       <link>http://code.dblock.org/me-silicon-alley-talent-fair-on-ny1</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/292</guid>
      </item>
     
      <item>
       <title>Alla Klein: A Fake Person In Charge of Customer Support</title>
       <pubDate>Wed, 09 Nov 2011 14:39:16 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>Mea Culpa. Alla Klein was a fake.</p>  <blockquote>   <p><a href="http://code.dblock.org/ShowPicture.aspx?id=402&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="vestris" border="0" alt="vestris" src="http://code.dblock.org/ShowPicture.aspx?id=403&ShowThumbnail=false" width="200" height="182" /></a></p> </blockquote>  <p>I had a software company called Vestris Inc. in late nineties, incorporated in the BVI. I was 20, had no idea what I was doing, and improvised a lot. I started with a bunch of shareware: XReplace-32 was probably the most successful. I also had a classmate collaborating on a search engine called Alkaline, which made quite a bit of money. The cash was collected from a Swiss bank in Geneva in-person. We sold in 40 countries to thousands of satisfied customers. For enterprise clients I wrote invoices and contracts out of my tiny apartment and we had a phone number, a fax and a voicemail for 24h support. The latter was run by a fake person, Alla Klein. Nobody ever saw Alla, but she was very much in charge.</p>  <p>The following things made Alla very successful.</p>  <ol>   <li>Alla would spend a lot of time helping customers outside of crisis, earning credits that could be spent in bad times. She had a relationship with every customer, free, small or large. </li>    <li>Alla had clear ownership of support problems. She would deal with issues, immediately and was the only point of contact and voice. </li>    <li>Alla always got back to customers via e-mail to make sure all their issues were resolved.  She was proactive in reaching out and tracked dissatisfied customers offering her time and expertise.</li>    <li>Alla was honest in her communication. She never made promises or refer to another person in charge. She never offered apologies or excessive sympathy. She always stated hard facts.</li> </ol>  <p>This combination made Alla our number one employee. In fact, she was regularly cited by customers that communicated with sales as one of the most competent support people that they ever had to interact with. She was also asked on a couple of dates. True story.</p></stripped></div><div><a href="http://code.dblock.org/alla-klein-a-fake-person-in-charge-of-customer-support">Read</a></div></html>
         ]]>
       </description>
       <category>vestris</category>
       <link>http://code.dblock.org/alla-klein-a-fake-person-in-charge-of-customer-support</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/291</guid>
      </item>
     
      <item>
       <title>NYC.rb: Building RESTful APIs w/ Grape</title>
       <pubDate>Tue, 08 Nov 2011 12:30:52 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I’m speaking at NYC.rb tonight @ Pivotal Labs, <a href="http://www.meetup.com/NYC-rb/events/28968081/">RSVP</a>.</p>  <p><a href="http://www.meetup.com/NYC-rb/events/28968081/"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=401&ShowThumbnail=false" width="380" height="137" /></a></p>  <p><strong>Update</strong>: Slides from the talk are <a href="http://www.slideshare.net/dblockdotorg/building-restful-apis-w-grape">here</a>.</p></stripped></div><div><a href="http://code.dblock.org/nycrb-building-restful-apis-w-grape">Read</a> | Updated 11/9/2011</div></html>
         ]]>
       </description>
       <category>grape</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/nycrb-building-restful-apis-w-grape</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/290</guid>
      </item>
         
  </channel>
</rss>

