<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US" xml:base="http://tx.pignata.com">
  <title>john pignata</title>
  <updated>2013-07-01T00:00:00+00:00</updated>
  <id>http://feeds.feedburner.com/jpignata</id>
  <link href="http://tx.pignata.com" type="text/html" rel="alternate"/>
  <link href="http://tx.pignata.com/index.atom" type="application/atom+xml" rel="self"/>
  <entry>
    <id>http://tx.pignata.com/2013/07/goruco-service-oriented-design.html</id>
    <published>2013-07-01T00:00:00+00:00</published>
    <updated>2013-07-01T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2013/07/goruco-service-oriented-design.html" type="text/html" rel="alternate"/>
    <title>Talk: Asynchronous Service Oriented Design
</title>
    <summary>Video and slides from my talk at GORUCO 2013 on some of our service oriented
infrastructure at GroupMe.
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<h2>Slides</h2>

<script async class="speakerdeck-embed" data-id="fbcf6500b2790130070b6e9d4b85acd4" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>

<h2>Video</h2>

<iframe width="640" height="360" src="http://www.youtube.com/embed/n8QUki5jhAM?feature=player_detailpage" frameborder="0" allowfullscreen></iframe>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2013/04/mwrc-code-smells-talk.html</id>
    <published>2013-04-27T00:00:00+00:00</published>
    <updated>2013-04-27T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2013/04/mwrc-code-smells-talk.html" type="text/html" rel="alternate"/>
    <title>Talk: Code Smells: Your Refactoring Cheat Codes
</title>
    <summary>Video and slides from a talk I gave at the Mountainwest Ruby Conference earlier
this month that talks about some of the canonical code smells by walking through
a refactoring example.
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<p>Sure, the TDD cycle is red-green-refactor but what exactly are we refactoring? We just wrote the code, it&#39;s green, and it seems reasonable to us. Let&#39;s move onto the next test. We have a deadline, remember?</p>

<p>Whether we&#39;re working with code we just wrote or opening up a project for the first time, being able to listen to the hints the code is trying to give you about how it wants to be constructed is the most direct path toward successful refactoring. What the code is telling you nuanced however: no code smell is absolute and none in itself is an indication of a problem. How do we know we need to refactor? What are the code smells telling us to do? How do we balance our short terms needs of shipping our software with the long term maintainability of the code base? In this talk we&#39;ll talk through some of the classical code smells and dive into examples of how to put these smells to work for you.</p>

<h2>Slides</h2>

<script async class="speakerdeck-embed" data-id="de9334907f8101303c5e22000a1d8ce4" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>

<h2>Video</h2>

<iframe width="640" height="360" src="http://www.youtube.com/embed/q_qdWuCAkd8?feature=player_embedded" frameborder="0" allowfullscreen></iframe>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2013/04/hit-the-switches.html</id>
    <published>2013-04-14T00:00:00+00:00</published>
    <updated>2013-04-14T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2013/04/hit-the-switches.html" type="text/html" rel="alternate"/>
    <title>Hit The Switches</title>
    <summary>An experimental gem to manage feature switches in a Ruby application using
pub/sub systems in Redis and Postgres for coordination to reduce the amount
applicatin servers must query a backend.
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<h2><a href="https://github.com/jpignata/switches">jpignata/switches</a></h2>

<p>Ruby developers love continuous deployment. Don&#39;t believe me? Just find one and
ask them, &ldquo;say, how often do you deploy a day?&rdquo; They won&#39;t answer, though,
since they&#39;ll be too busy kicking off another deploy from their phone. The
trend is a great thing &ndash; many teams measure the time between features and
fixes being completed and being live in front of real users in minutes or hours
instead of days or weeks.</p>

<p>Flickr talked extensively about <a href="http://code.flickr.net/2009/12/02/flipping-out/">using feature
flippers</a> to eliminate long
running branches while still ensuring the deploy pipeline isn&#39;t blocked by work
in progress. Using feature flags, Flickr continued to deploy multiple times a
day while all work was continuously integrated in the same main branch that was
being continuously deployed.</p>

<p>In the intervening years we&#39;ve gotten more sophisticated in our approach to
feature flags. We gate not just on the running code&#39;s environment but also down
to request-specific parameters such as the current user. In our Ruby projects,
using tools like <a href="https://github.com/jamesgolick/rollout">rollout</a> or
<a href="https://github.com/jnunemaker/flipper">flipper</a> we can turn a feature on to a
specific set of users or to some arbitrary percentage of users. Using these
tactics we can conditionally expose a feature to a small subset of users. This
can allow us to both get feedback on the feature and see it perform under
real-world conditions before going fully live. We can iterate and tune and
optimize our feature before lifting the curtain to our full population of
users.</p>

<p>Since we often have many application server instances running, these projects
will use a backend to coordinate the sharing of feature switches state and each
feature switch will result in some kind of query.  We read this data far more
often than we write this data so it feels like we should be aggressively
caching on our application servers. This introduces a trade-off: if we cache
aggressively and expire this cache after some time-to-live period, it&#39;s
possible the nodes won&#39;t agree on the state of a feature flag. This could cause
a user to see a feature appear and disappear between requests. Ideally the
application server nodes would be lazy in fetching new configuration data, but
if we decide to make a change it should take effect globally and as close to
immediately as possible.</p>

<p>I&#39;ve published an experimental gem to manage feature switches in a Ruby
application. <a href="https://github.com/jpignata/switches">Switches</a> works much the
same as existing projects but has the explicit design goal of ensuring the
least possible chatter between application server instances and the shared
backend. Instead of querying Redis or Mongo for each feature switch we add to
a given execution path, switches uses in-memory structures for storing this
data. Whenever this data is changed a change notification is delivered via
a pub/sub bus which triggers a refresh of its in-memory cache.</p>
<div class="highlight"><pre><span class="c1"># config/initializers/switches.rb</span>
<span class="vg">$switches</span> <span class="o">=</span> <span class="no">Switches</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
  <span class="n">config</span><span class="o">.</span><span class="n">backend</span> <span class="o">=</span> <span class="s2">&quot;redis://localhost:6379/0&quot;</span>
<span class="k">end</span>

<span class="c1"># app/controllers/posts_controller.rb</span>
<span class="k">def</span> <span class="nf">index</span>
  <span class="k">if</span> <span class="vg">$switches</span><span class="o">.</span><span class="n">feature</span><span class="p">(</span><span class="ss">:websockets_chat</span><span class="p">)</span><span class="o">.</span><span class="n">on?</span><span class="p">(</span><span class="n">current_user</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
    <span class="vi">@chat</span> <span class="o">=</span> <span class="no">ChatConnection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">current_user</span><span class="p">)</span>
 <span class="k">end</span>

  <span class="k">if</span> <span class="vg">$switches</span><span class="o">.</span><span class="n">feature</span><span class="p">(</span><span class="ss">:redesign</span><span class="p">)</span><span class="o">.</span><span class="n">on?</span><span class="p">(</span><span class="n">current_user</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
    <span class="n">render</span> <span class="ss">:index</span><span class="p">,</span> <span class="n">layout</span><span class="p">:</span> <span class="ss">:redesign</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="c1"># In an IRB session; once ran a change notification will be broadcast</span>
<span class="c1"># to all listening nodes. Each node will then refresh its data for the</span>
<span class="c1"># &quot;redesign&quot; feature.</span>

<span class="c1"># On for 10% of users</span>
<span class="vg">$switches</span><span class="o">.</span><span class="n">feature</span><span class="p">(</span><span class="ss">:websockets_chat</span><span class="p">)</span><span class="o">.</span><span class="n">on</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>

<span class="c1"># Add user IDs 5, 454, and 2021 to the power_users cohort</span>
<span class="vg">$switches</span><span class="o">.</span><span class="n">cohort</span><span class="p">(</span><span class="ss">:power_users</span><span class="p">)</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">454</span><span class="p">)</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">2021</span><span class="p">)</span>

<span class="c1"># On for users in the power_users cohort</span>
<span class="vg">$switches</span><span class="o">.</span><span class="n">feature</span><span class="p">(</span><span class="ss">:redesign</span><span class="p">)</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="ss">:power_users</span><span class="p">)</span>
</pre></div>

<p>Switches uses either Redis or Postgres for storage and coordination. I&#39;m hoping
to experiment with other backends soon
(<a href="http://zookeeper.apache.org/">Zookeeper</a> and <a href="http://guide.couchdb.org/draft/notifications.html">CouchDB&#39;s _change
feed</a> both seem promising.)</p>

<p>I&#39;ve not yet gotten this gem production-ready yet, but will continue working on
it over the next few weeks. If you&#39;re using a feature switch library and are
concerned about network chatter get in touch.</p>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2013/03/nycrb-request-queueing-talk.html</id>
    <published>2013-03-12T00:00:00+00:00</published>
    <updated>2013-03-12T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2013/03/nycrb-request-queueing-talk.html" type="text/html" rel="alternate"/>
    <title>Talk: A Brief Aside on Request Queueing
</title>
    <summary>Request queueing is the topic du jour amongst Ruby developers operating web
systems. What's actually going on in that fat green band in New Relic? In this
short talk we'll look at how that number is calculated, what it suggests, and
what we should do about it.
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<h2>Slides</h2>

<script async class="speakerdeck-embed" data-id="1d5b88b06da101306d261231392858a6" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2013/02/dumbodevs-future-developer-talk.html</id>
    <published>2013-02-15T00:00:00+00:00</published>
    <updated>2013-02-15T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2013/02/dumbodevs-future-developer-talk.html" type="text/html" rel="alternate"/>
    <title>Talk: Being for the Benefit of Future Developer
</title>
    <summary>Video and slides from a talk given at the DUMBO Developers meetup that
examines the ways we can prepare our codebases for future generations.
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<h2>Slides</h2>

<script async class="speakerdeck-embed" data-id="5ecf328059d301309a5812313926f5f6" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

<h2>Video</h2>

<iframe src="http://player.vimeo.com/video/59783127" width="500" height="322" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2012/11/applying-the-unix-philosophy-to-object-oriented-design.html</id>
    <published>2012-11-28T00:00:00+00:00</published>
    <updated>2012-11-28T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2012/11/applying-the-unix-philosophy-to-object-oriented-design.html" type="text/html" rel="alternate"/>
    <title>Your Objects, the Unix Way: Applying the Unix Philosophy to Object-Oriented Design
</title>
    <summary>What lessons can we learn from the Unix philosophy that can be applied to
the designs of the components in our applications?
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<p><em>This week I wrote a guest post on the
<a href="http://www.codeclimate.com">Code Climate</a> <a href="http://blog.codeclimate.com">blog</a>
exploring the link between the Unix philosophy and object-oriented design.</em></p>

<p>In 1964, Doug McIlroy, an engineer at Bell Labs, wrote an internal memo
describing some of his ideas for the Multics operating system. The
<a href="http://cm.bell-labs.com/who/dmr/mdmpipe.html">surviving tenth page</a>
summarizes the four items he felt were most important. The first
item on the list reads:</p>

<blockquote>
<p>&ldquo;We should have some ways of coupling programs like [a] garden hose &ndash; screw
in another segment when it becomes necessary to massage data in another way.&rdquo;</p>
</blockquote>

<p>This sentence describes what ultimately became the Unix pipeline: the chaining
together of a set of programs such that the output of one is fed into the next
as input.</p>

<p><a href="http://blog.codeclimate.com/blog/2012/11/28/your-objects-the-unix-way/">Continue reading on Code Climate</a></p>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2012/11/concurrency-patterns-in-ruby-futures.html</id>
    <published>2012-11-19T00:00:00+00:00</published>
    <updated>2012-11-19T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2012/11/concurrency-patterns-in-ruby-futures.html" type="text/html" rel="alternate"/>
    <title>Concurrency Patterns in Ruby: Futures
</title>
    <summary>Concurrency! Threads! Ooh, scary! Sometimes we just need to reach for
patterns that help us reason about what we're asking our computers to do.
Let's take a closer look at one pattern called futures.
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<p>A future is a concurrency construct that allows a programmer to schedule work
in a background thread while continuing execution of the program.  When the
value of the calculation is needed it&#39;s requested from the future proxy which
will either return it or block until it can if the value is not yet available.
Futures abstract some of the complexity inherent in scheduling a task to run in
the background and polling for its completion. We get asynchronous calculations
that happen concurrent to our main program&#39;s execution without callback
spaghetti and we&#39;re guaranteed to be able to get at the result when we require
it.</p>

<p>Sometimes it feels like we&#39;re supposed to fear concurrency as terrifying
complexity, but with the right patterns and practices concurrent programming is
more than manageable. We&#39;ll look at how a future could be implemented in ruby
and then dig into some examples to illustrate where they could be useful.</p>

<h3>A Naive Implementation</h3>

<p>Let&#39;s scratch out a basic implementation of a <code>Future</code> proxy in ruby. In its
most basic form, it could look something like this:</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Future</span> <span class="o">&lt;</span> <span class="no">BasicObject</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">callable</span><span class="p">)</span>
    <span class="vi">@thread</span> <span class="o">||=</span> <span class="o">::</span><span class="no">Thread</span><span class="o">.</span><span class="n">new</span> <span class="p">{</span> <span class="n">callable</span><span class="o">.</span><span class="n">call</span> <span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">value</span>
    <span class="vi">@thread</span><span class="o">.</span><span class="n">value</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">inspect</span>
    <span class="k">if</span> <span class="vi">@thread</span><span class="o">.</span><span class="n">alive?</span>
      <span class="s2">&quot;#&lt;Future running&gt;&quot;</span>
    <span class="k">else</span>
      <span class="n">value</span><span class="o">.</span><span class="n">inspect</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="nb">method</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
    <span class="n">value</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="nb">method</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">respond_to_missing?</span><span class="p">(</span><span class="nb">method</span><span class="p">,</span> <span class="n">include_private</span> <span class="o">=</span> <span class="kp">false</span><span class="p">)</span>
    <span class="n">value</span><span class="o">.</span><span class="n">respond_to?</span><span class="p">(</span><span class="nb">method</span><span class="p">,</span> <span class="n">include_private</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>We start with an object that derives from <code>BasicObject</code> and is instantiated
with a <code>Proc</code> or other object that responds to <code>call</code>. In the initializer a
background thread is created and the callable is called within it. Any methods
received by <code>Future</code> will be proxied to <code>Thread#value</code> which is the last
returned value from the thread. If the <code>Thread</code> is still working on
calculating the value, this call will block until the <code>Thread</code> is finished.
This ensures that a caller can always retrieve the value if it&#39;s needed.
<code>Future</code> also has an <code>inspect</code> method which will return a static string if the
<code>Thread</code> is still running or defer to the value if the <code>Thread</code> is finished.</p>

<p>We&#39;ll also add a convenience method to Kernel so we can use it anywhere we
want.</p>
<div class="highlight"><pre><span class="k">module</span> <span class="nn">Kernel</span>
  <span class="k">def</span> <span class="nf">future</span><span class="p">(</span><span class="o">&amp;</span><span class="n">block</span><span class="p">)</span>
    <span class="no">Future</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>This method instantiates a new <code>Future</code> which runs the given block and returns
the proxy back to the caller. Now we can use the <code>future</code> method to dispatch
arbitrary tasks for background execution and use the returned proxy to access
the computed values later in execution.</p>
<div class="highlight"><pre><span class="o">&gt;&gt;</span> <span class="n">calculation</span> <span class="o">=</span> <span class="n">future</span> <span class="p">{</span> <span class="mi">4</span> <span class="o">*</span> <span class="mi">4</span> <span class="p">}</span>
<span class="o">=&gt;</span> <span class="c1">#&lt;Future running&gt;</span>
<span class="o">&gt;&gt;</span> <span class="n">calculation</span><span class="o">.</span><span class="n">value</span>
<span class="o">=&gt;</span> <span class="mi">16</span>
<span class="o">&gt;&gt;</span> <span class="n">calculation</span>
<span class="o">=&gt;</span> <span class="mi">16</span>
</pre></div>

<p>If we tried to access the result of a long running calculation, it&#39;d block
until that value was available:</p>

<p><img src="/images/futures/demo.gif" alt=""></p>

<p>As <code>Future</code> calls the block in a background thread, execution of multiple
futures will happen concurrently:</p>
<div class="highlight"><pre><span class="n">futures</span> <span class="o">=</span> <span class="o">[</span>
  <span class="n">future</span> <span class="p">{</span> <span class="nb">sleep</span> <span class="mi">2</span> <span class="p">},</span>
  <span class="n">future</span> <span class="p">{</span> <span class="nb">sleep</span> <span class="mi">2</span> <span class="p">},</span>
  <span class="n">future</span> <span class="p">{</span> <span class="nb">sleep</span> <span class="mi">2</span> <span class="p">}</span>
<span class="o">]</span>

<span class="n">futures</span><span class="o">.</span><span class="n">each</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:value</span><span class="p">)</span>
</pre></div>

<p>We&#39;re building three futures here with a block in each that will sleep
for two seconds. If we were executing these serially, we&#39;d expect about six
seconds of execution time as the iterator calls and sleeps for two seconds on
each execution.</p>
<div class="highlight"><pre>jp@oeuf:~/workspace/tmp<span class="nv">$ </span><span class="nb">time </span>ruby futures.rb

real  0m2.032s
user  0m0.024s
sys   0m0.006s
</pre></div>

<p>Each future started executing as soon as it was created in the background.
Since the three blocks were running at the same time, our dummy script executes
in about two seconds.</p>

<h3>Service Oriented Design</h3>

<p>A practical example of why concurrency is important and where a pattern like
this might apply is within service oriented systems. As we continue to break down
our monolithic applications into services and daemons, within a web request we
may need to make some number of remote service calls in order to render a page
of content. A user might be authenticated via a user service, the page&#39;s
content might be stored in a remote CMS service, and recommendations for a user
might be stored within a recommender service. Of those three service calls at
least two can be run independently from the output of any other. When you
don&#39;t use concurrency to make these calls, it&#39;s like cooking dinner with only
one burner on your stove-top. You&#39;re now cooking one dish at a time so it takes
longer to get the food on the table.</p>

<p>In an oft-referenced <a href="http://queue.acm.org/">ACM Queue</a> article,
<a href="http://queue.acm.org/detail.cfm?id=1142065">Werner Vogels</a> asserted that
Amazon could make up to something like 100 service calls to assemble a page for
a visitor. In the same year, Amazon published their findings about the
relationship between their service&#39;s latency and customers&#39; purchasing habits.
For every 100ms delay they were able to slice off of page load times,
<a href="http://www.strangeloopnetworks.com/resources/infographics/web-performance-and-ecommerce/amazon-100ms-faster-1-revenue-increase/">sales increased by 1%</a>.
So even if each request took 1 millisecond, if they were all done serially that
would cost 100 milliseconds and possibly one percent of sales. Considering the
complexity of what these services likely do, it seems reasonable that many take
longer to execute than that. Running these requests concurrently is one way to
ensure that response time doesn&#39;t bloat in line with the number of services that
are required to assemble a response.</p>

<p>Using concurrent requests when distributing of responsibilities across
network-available services will make the most efficient use of our resources,
will reduce wall clock running time for requests, and allow our systems to
handle more transactions over a given amount of time.</p>

<h3>A Hacker News Crawler</h3>

<p>Let&#39;s look at a contrived example. How would <a href="http://stallman.org/">RMS</a> read
Hacker News? <a href="http://stallman.org/stallman-computing.html">Probably from the command line</a>.
Maybe even while eating breakfast,
<a href="https://secure.mysociety.org/admin/lists/pipermail/developers-public/2011-October/007647.html">but I wouldn&#39;t bring it up.</a>
Let&#39;s build a simple script using Nokogiri to grab some URLs from the first
page of Hacker News, fetch each page, and print each article&#39;s title and
content onto STDOUT.</p>

<p>First, we&#39;ll define a simple <code>Page</code> object to represent an HTML document.</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s2">&quot;open-uri&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;nokogiri&quot;</span>

<span class="k">class</span> <span class="nc">Page</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
    <span class="vi">@url</span> <span class="o">=</span> <span class="n">url</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">links</span>
    <span class="n">document</span><span class="o">.</span><span class="n">css</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">anchor</span><span class="o">|</span> <span class="n">anchor</span><span class="o">[</span><span class="s2">&quot;href&quot;</span><span class="o">]</span> <span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">paragraphs</span>
    <span class="n">document</span><span class="o">.</span><span class="n">css</span><span class="p">(</span><span class="s2">&quot;p&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">paragraph</span><span class="o">|</span> <span class="n">paragraph</span><span class="o">.</span><span class="n">text</span> <span class="p">}</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">title</span>
    <span class="n">node</span> <span class="o">=</span> <span class="n">document</span><span class="o">.</span><span class="n">css</span><span class="p">(</span><span class="s2">&quot;title&quot;</span><span class="p">)</span>
    <span class="n">node</span> <span class="o">&amp;&amp;</span> <span class="n">node</span><span class="o">.</span><span class="n">text</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">get</span>
    <span class="n">document</span>
    <span class="nb">self</span>
  <span class="k">end</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">document</span>
    <span class="vi">@document</span> <span class="o">||=</span> <span class="no">Nokogiri</span><span class="o">::</span><span class="no">HTML</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">content</span>
    <span class="nb">open</span><span class="p">(</span><span class="vi">@url</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>A <code>Page</code> is instantiated with a URL and a call to <code>get</code> will pre-load the
document. There are a couple of accessor methods for what we suspect we&#39;ll
need such as the <code>title</code>, all of the <code>links</code> on a page, and all of the
content stored in <code>paragraphs</code>.</p>

<p>We&#39;ll create an object to represent the Hacker News homepage called <code>Index</code>:</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Index</span>
  <span class="no">URL</span> <span class="o">=</span> <span class="s2">&quot;http://news.ycombinator.com&quot;</span>

  <span class="k">def</span> <span class="nf">initialize</span>
    <span class="vi">@page</span> <span class="o">=</span> <span class="no">Page</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">URL</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">urls</span>
    <span class="n">links</span> <span class="o">=</span> <span class="vi">@page</span><span class="o">.</span><span class="n">links</span><span class="o">.</span><span class="n">select</span> <span class="p">{</span> <span class="o">|</span><span class="n">link</span><span class="o">|</span> <span class="n">link</span><span class="o">.</span><span class="n">start_with?</span><span class="p">(</span><span class="s2">&quot;http&quot;</span><span class="p">)</span> <span class="p">}</span>
    <span class="n">links</span><span class="o">[</span><span class="mi">1</span><span class="o">.</span><span class="n">.</span><span class="mi">25</span><span class="o">]</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>This object is composed of a <code>Page</code> and has a method to return 25 of the
absolute <code>urls</code> scraped from the HTML. This is a small cheat to exclude
internal navigation links from the header.</p>

<p>Next we&#39;ll put together a simple <code>Crawler</code> to use these objects to get the
content from Hacker News. Our first stab at this will be synchronous so each
page will be fetched in serial:</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Crawler</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">index</span><span class="p">)</span>
    <span class="vi">@index</span> <span class="o">=</span> <span class="n">index</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">crawl</span>
    <span class="n">pages</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">page</span><span class="o">|</span>
      <span class="no">Outputter</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">page</span><span class="p">)</span><span class="o">.</span><span class="n">output</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">pages</span>
    <span class="vi">@index</span><span class="o">.</span><span class="n">urls</span><span class="o">.</span><span class="n">map</span> <span class="k">do</span> <span class="o">|</span><span class="n">url</span><span class="o">|</span>
      <span class="no">Page</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><span class="o">.</span><span class="n">get</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>The <code>Crawler</code> expects an <code>Index</code> object which responds to <code>urls</code> to be passed
into its initializer. Once it gets each page it&#39;ll pass that to <code>Outputter</code>: a
pretty printer used to display our contents neatly to the terminal. We&#39;ll use
the <code>HighLine</code> gem to handle most of the real work:</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s2">&quot;highline&quot;</span>

<span class="k">class</span> <span class="nc">Outputter</span>
  <span class="no">OUTPUT_WIDTH</span> <span class="o">=</span> <span class="mi">79</span>

  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">page</span><span class="p">)</span>
    <span class="vi">@page</span> <span class="o">=</span> <span class="n">page</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">output</span>
    <span class="n">highline</span><span class="o">.</span><span class="n">say</span><span class="p">(</span><span class="s2">&quot;-&quot;</span> <span class="o">*</span> <span class="no">OUTPUT_WIDTH</span><span class="p">)</span>
    <span class="n">highline</span><span class="o">.</span><span class="n">say</span><span class="p">(</span><span class="vi">@page</span><span class="o">.</span><span class="n">title</span><span class="p">)</span>
    <span class="n">highline</span><span class="o">.</span><span class="n">say</span><span class="p">(</span><span class="s2">&quot;-&quot;</span> <span class="o">*</span> <span class="no">OUTPUT_WIDTH</span><span class="p">)</span>

    <span class="n">highline</span><span class="o">.</span><span class="n">say</span><span class="p">(</span><span class="vi">@page</span><span class="o">.</span><span class="n">paragraphs</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">&quot;</span><span class="p">))</span>
    <span class="n">highline</span><span class="o">.</span><span class="n">say</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">&quot;</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">highline</span>
    <span class="vi">@highline</span> <span class="o">||=</span> <span class="no">HighLine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="vg">$stdin</span><span class="p">,</span> <span class="vg">$stdout</span><span class="p">,</span> <span class="no">OUTPUT_WIDTH</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>Finally, we&#39;ll glue together a small script to introduce our <code>Crawler</code> and
<code>Index</code> and drive our program:</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s2">&quot;future&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;crawler&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;index&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;page&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;outputter&quot;</span>

<span class="no">Crawler</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">Index</span><span class="o">.</span><span class="n">new</span><span class="p">)</span><span class="o">.</span><span class="n">crawl</span>
</pre></div>

<p>Since we&#39;re doing this synchronously, let&#39;s use <code>time</code> to figure out how long
this takes to run:</p>
<div class="highlight"><pre>jp@oeuf:~/workspace/crawler$ time ruby ./crawl
-------------------------------------------------------------------------------
The Quiet Ones - NYTimes.com
-------------------------------------------------------------------------------

EVER since I quit hanging out in Baltimore dive bars, the only place where I
still regularly find myself in hostile confrontations with my fellow man is
Amtrak’s Quiet Car. The Quiet Car, in case you don’t know, is usually the first
car in Amtrak’s coach section, right behind business class. Loud talking is
...

real  0m32.405s
user  0m2.403s
sys   0m0.161s
</pre></div>

<p>Pretty pokey. Now let&#39;s use our <code>Future</code> object to run the requests. We&#39;ll
modify <code>Crawler</code> to wrap each <code>Page#get</code> call in a future block. </p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Crawler</span>
  <span class="o">.</span><span class="n">.</span><span class="o">.</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">pages</span>
    <span class="vi">@index</span><span class="o">.</span><span class="n">urls</span><span class="o">.</span><span class="n">map</span> <span class="k">do</span> <span class="o">|</span><span class="n">url</span><span class="o">|</span>
      <span class="n">future</span> <span class="p">{</span> <span class="no">Page</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><span class="o">.</span><span class="n">get</span> <span class="p">}</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>Let&#39;s run it again using <code>time</code>:</p>
<div class="highlight"><pre>jp@oeuf:~/workspace/crawler$ time ruby ./crawl
...

real  0m6.942s
user  0m2.296s
sys   0m0.164s
</pre></div>

<p>It&#39;s 4.5x faster because each request starts when we call <code>future</code> and happens
concurrently. It&#39;s like 25 people making a phone call at the same time versus
one person making 25 phone calls one at a time.</p>

<p>This finished command line application is on <a href="http://github.com/jpignata/crawler">GitHub</a>.</p>

<h3>Our Concurrent Futures</h3>

<p>The continued emphasis on service-oriented systems and the reality that we&#39;re
likely to keep getting more cores rather than faster processors in our
computers will make concurrency tools even more important when building our
applications. Patterns like futures allow us to more easily reason about what&#39;s
actually happening in a concurrent program. While our naive implementation
isn&#39;t suitable for real world use due to its lack of any error handling or the
absence of a pool of threads, the <a href="http://github.com/celluloid/celluloid">Celluloid</a>
library has a <a href="https://github.com/celluloid/celluloid/wiki/futures">futures implementation</a>
that is ready to be used in your production applications.</p>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2012/11/being-for-the-benefit-of-future-developer.html</id>
    <published>2012-11-11T00:00:00+00:00</published>
    <updated>2012-11-11T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2012/11/being-for-the-benefit-of-future-developer.html" type="text/html" rel="alternate"/>
    <title>Being for the Benefit of Future Developer</title>
    <summary>A software project passes through the hands of many different developers in
its lifetime.  How can we keep our project prepared for the future teams of
developers that will inherit it?
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<p>A successful software project is likely to pass between many developers in its
lifetime. You are one link in your project&#39;s chain of custody and every line
of code you commit to your project is an artifact you&#39;re leaving to be
discovered by Future Developer. Just as you&#39;ve inherited the decisions of the
developers that came before you, other developers will inherit the decisions
you&#39;re making today. Onto them we bequeath our misunderstandings, our
shortcuts, our applications of half-understood patterns and technologies, our
inconsistencies, our inattention to detail, our procrastinations, our
quick-and-dirty changes, our hidden skeletons, our dirty laundry. More rarely,
they will be the beneficiaries of our discipline, deliberation, and preparation.</p>

<p>As a developer on your project you are in the best possible position to
empathize with and anticipate the needs of Future Developer. Every good
decision we make for our project will have ripple effects on his or her
productivity. Why is this important? As Bob Martin asks in <a href="http://www.amazon.com/Clean-%20Code-Handbook-Software-%0ACraftsmanship/dp/0132350882">Clean
Code</a>, &ldquo;Have you ever been significantly impeded by bad
code? So then &ndash; why did you write it?&rdquo; The same strategies to improve the
conditions for future generations of teams working on your project will serve
your team well in the present. When you come back to some obscure corner of
the codebase that you cobbled together six months ago, you&#39;re likely to have
only a little more context than Future Developer will when he or she sees it
or the first time. The clues and polish you&#39;ve left for other developers will
benefit your future self. Projects that are poorly maintained are draining to
contribute to and lead to team attrition. Investing in the quality and future
maintainability of the software you&#39;re creating is an investment in a happy,
productive workplace for the present and future.</p>

<p>I&#39;m going to pick a few practices in no particular order that we can use to
set Future Developer up for success.</p>

<h3>1. Refactor toward Consistency</h3>

<p>As projects age and requirements become more complex, we tend to introduce new
patterns and designs to manage this complexity. It&#39;s hard to tell if a pattern
or approach is pulling its weight immediately. Most of the time the feedback
that proves or disproves its value comes when another developer has to make a
change to that area of the codebase. Sometimes these patterns grow into
conventions that we begin to reach for to solve problems.</p>

<p>There&#39;s immense benefit to that: conventions communicate intent. If we tend
to solve problems in the same sorts of ways in a codebase, Future Developer
can start to predict how pieces of the codebase work together reducing the
amount of time necessary to diagnose problems and implement changes.</p>

<p>Often what we leave behind is a hodgepodge of patterns which never quite
became conventions or have been ignored in the codebase as old cruft. This
happens for a variety of reasons: the conventions introduced didn&#39;t work well
enough to make it into other areas of the codebase or maybe new developers
didn&#39;t know there was a convention or pattern for handling a given
requirement.</p>

<p>Rails&#39; opinions and conventions are powerful. They allow developers to join a
project and quickly be productive if they&#39;ve had any exposure to projects that
have used the framework. Sometimes we muddy these conventions and dilute their
power. For example,  in Rails systems we sometimes see controllers built in
many different styles. Some are composed using a project like
<code>resource_controller</code>, others follow the standard Rails <code>resources</code> convention
while others are junk drawers of random actions. Another common anti-pattern
is having configuration data sprinkled and initialized all throughout your
system.</p>

<p>Don&#39;t have half a dozen different ways of configuring aspects of your system
and make it clear how a controller should be built in your system. Once you&#39;ve
experimented for a while and have settled on an approach, take the time to go
back to previous work and refactor into the new pattern. This doesn&#39;t mean
that you should add arbitrary constraints. There&#39;s good reason, for example,
to have some configuration stored with the project and some stored in the
environment to aid in deployment, but there should be one common structure and
access pattern for using configuration data.</p>

<p>Add conventions to your README or selected documentation repository. This will
give Future Developer a head start on adding functionality to the system and
to in understanding how its components are constructed.</p>

<h3>2. Prune Dead Code</h3>

<p>Another common characteristic of systems that have existed for some time is
the collection of barnacles in the form of dead code. These components in your
project may have at one time been providing business value but they&#39;ve been
deprecated and hidden from production for months. There&#39;s probably even a slew
of full-stack acceptance tests validating those parts of the system are
functioning and slowing down your test suite.</p>

<p>Sometimes we&#39;re reluctant to delete this code because we&#39;re not sure if the
feature will be resurrected. Your product manager, when asked, might say &ldquo;no,
leave it, we may reuse that one day.&rdquo; This is a false dilemma &ndash; carrying
around a slowly rotting section of code for possible future reuse assumes that
reusing those parts of the codebase involves just flicking a switch. If we&#39;re
ignoring it because it&#39;s not actually live, it&#39;s not likely to be something we
can just &ldquo;turn on&rdquo; without significant work. You&#39;re carrying that old code around
like a <a href="http://en.wikipedia.org/wiki/Boat_anchor_(computer_science)">boat anchor</a>,
wasting cycles maintaining it because there&#39;s a small chance you may possibly
one day need part of it. Maybe. You don&#39;t know, but you spent a lot of time
building it so rather than deleting it you allow the code to slowly rot in your
repository.</p>

<p>What&#39;s even more costly is that the continued existence of this code is a
possible trap for Future Developer. It detracts attention from the components
of your system that are actually live and is a possible red herring when he or
she is trying to understand or troubleshoot some aspect of the system. In a
system down emergency, old, dead code is noise waiting to waste valuable time.
Keeping the amount of code present in your code repository synchronized to the
amount of code actually functioning in your live system will reduce overall
maintenance costs and allow Future Developer to more quickly understand your
entire system.</p>

<p>Delete code that isn&#39;t in use with abandon. It&#39;ll still be under source
control if you need to refer to it later. Don&#39;t fall onto the wrong side of
the fallacy that you might be able to &ldquo;turn it back on again later.&rdquo; If it had
any value then why did you turn it off to begin with?</p>

<h3>3. Leave a Coherent Paper Trail</h3>

<p>Aside from our project itself, some of the tools we use in support of writing
code have their own artifacts. For example, there are <a href="http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html">commonly accepted
practices</a>
about what constitutes good <code>git</code> commit message hygiene and
yet projects continue to accumulate commit histories like this contrived
example:</p>
<div class="highlight"><pre>jp@oeuf:~/workspace/blog(master*)$ git log --oneline app/controllers/application_controller.rb
8ec7f99 fuck i dunno lol
ffa919a shut up, atom parser
a33e9fa fixing again
cecc9dc one more time
968a28f fixing
3e3aeb2 ws
1fc597e pagination
edea155 adding dumb feature
</pre></div>

<p>When Future Developer ends up inevitably using <code>git blame</code> to get context
about a given feature, leave him or her the details they need to understand
the churn in the files in question. Use <code>merge --squash</code>, <code>commit --amend</code>,
<code>rebase</code>, and friends to massage your commits into a coherent set before
integrating your topic branch. Reword your commits after you&#39;re done &ndash; take a
moment to include anything that seems relevant and summarize. Proofread for
grammar and spelling; you&#39;re publishing something that somebody else will need
to read and understand. Do Future Developer a favor and ensure you&#39;re leaving behind
an intelligible paper trail that contains the right amount of detail.</p>
<div class="highlight"><pre>jp@oeuf:~/workspace/blog(master*)$ git log app/controllers/application_controller.rb
commit 8ec7f998fb74a80886ece47f0a51bd03b0460c7a
Author: John Pignata &lt;john@pignata.com&gt;
Date:   Sat Nov 3 14:11:12 2012 -0400

    Add Google Analytics helper

commit 968a28f366e959081307e65253118a65301466f2
Author: John Pignata &lt;john@pignata.com&gt;
Date:   Sat Nov 3 13:49:50 2012 -0400

    Correct ATOM feed validation issues

    Using the W3C Validator (http://validator.w3.org/appc/), a few trivial
    errors were reported:

    * &lt;author&gt; should have a &lt;name&gt; node within it and not text
    * Timestamps should be in ISO8601 format

    This change fixes these issues and improves the spec coverage for the XML
    document.

commit 3e3aeb27ea99ecd612c436814c5a2b0dab69c2c3
Author: John Pignata &lt;john@pignata.com&gt;
Date:   Sat Nov 3 13:46:24 2012 -0400

    Fixing whitespace

    We&#39;re no longer indenting methods after `private` or `protected` directives
    as a matter of style. This commit fixes whitespace in all remaining
    classes.

commit 1fc597e788442e8cc774c6d11e7ac5e77b6c6e14
Author: John Pignata &lt;john@pignata.com&gt;
Date:   Sat Nov 3 12:34:50 2012 -0400

    Implement Kaminari pagination

    Move from will_paginate to kaminari in all controllers. The
    motivation is to be able to paginate simple Array collections
    without the monkey patching that will_paginate uses.

    * Consolidate helpers
    * Clean up whitespace

commit edea15560595bab044143149a7d6e528e8ae65d2
Author: John Pignata &lt;john@pignata.com&gt;
Date:   Sat Nov 3 12:27:16 2012 -0400

    Add ATOM feed for RSS readers

    * Include Nokogiri in Gemfile for its builder
    * Add AtomFieldBuilder model
    * Add link to feed from index page
</pre></div>

<h3>4. Polish Your Interfaces</h3>

<p>Some Ruby developers eschew method visibility for the methods in their
objects. What&#39;s the point? Any method is really callable using <code>send</code> anyway.
Why bother putting shackles around some methods? Just add that internal method
to the pile and if Future Developer wants to use it he or she can! We&#39;re all
adults, amirite?</p>

<p>If every object in your system is just a junk drawer of methods, it becomes
very difficult for anyone (including you) to understand how each object was
intended to be used and what messages it&#39;s intended to receive. The design of
the public interface of an object should make it absolutely obvious how other
objects in the system can interact with it. When each object&#39;s role and the
interactions between the objects in your system are not obvious, it increases
the amount of time it takes to understand not only each object but the system
in toto.</p>

<p>Hide as much of a component&#39;s internals as possible to keep interface small
and focused. Put extra energy into making sure your objects&#39; public interfaces
are obvious, well named, and consistent. This gives Future Developer clear
signals about how you intend each object to be used and will highlight how
each can be reused. Use explicit method visibility to communicate this intent
and to enforce the surface area of the object&#39;s public interface.</p>

<h3>5. Leave Comments, Not Too Many, Mostly RDoc</h3>

<p>As developers our feelings about code comments can be best described as
<a href="https://www.google.com/search?q=site%3Ac2.com+comments">ambivalent</a>. On one
hand comments are extremely helpful in assisting a reader in understanding how
a given piece of code works. On the other hand as nothing enforces their
correctness, code comments are lies waiting to be told to the future. When
asked developers will say they value documentation but often projects have
very little beyond a mostly-out-of-date README and maybe a graveyard wiki
somewhere. What&#39;s more, when working with open source libraries we&#39;ll often
expect thorough RDoc documentation, an up-to-date README, and good example
code and when not present we&#39;ll complain bitterly. Scumbag developer: doesn&#39;t
maintain documentation, expects it from others.</p>

<p>As we pay more attention to things like the
<a href="http://www.objectmentor.com/resources/articles/srp.pdf">Single Responsibility Principle</a>
and use patterns to loosen the coupling between objects we start to see
systems composed of many small objects wired together at runtime. While this
makes systems more pliable and objects more reusable there&#39;s a trade-off:
understanding an object&#39;s place within the larger system may be less
obvious and as such take more effort.  You can use all of the usual
refactorings to eliminate pesky inline comments and make your object as
readable as possible but it still might baffle Future Developer as to how the
object fits into the system.</p>

<p>RDoc-style documentation can be found in many open source projects. When
you&#39;re using Google to figure out if <code>update_attribute</code> fires callbacks or not
or what the signature for <code>select_tag</code> is, you&#39;ll likely land on the extracted
RDoc for <a href="http://api.rubyonrails.org/">Ruby on Rails</a>. Writing similar
documentation as part of your project will give Future Developer more context
when he or she is trying to understand the role of an object in the larger
context of your system. Adding a short, declarative sentence to the top of a
class and/or method indicating what it does could have substantial value for
future readers of the code. That said, without a strong shared culture of
keeping these comments up to date they could have negative value and
mislead a future reader of the code. The only thing worse than no documentation
is incorrect documentation.</p>

<h3>6. Write Intention Revealing Tests</h3>

<p>One way we provide documentation to a project is through the tests we leave
behind. These tests not only describe what the behavior of a given component
is but it enforces this documentation is correct as it&#39;s executable. Unlike a comment
we can&#39;t leave future lies in the test suite; it&#39;s either green or it isn&#39;t.
Tools like RSpec and <code>minitest/spec</code> assist us in generating this
by-product documentation by encouraging prose within the defining block of the
example. Unfortunately we sometimes look past the English words we&#39;re typing in
our rush to get to the actual code in the red-green-refactor cycle. The
result of neglecting the English descriptions is that it&#39;s possible our tests
are not properly reflecting our objects&#39; behavior as well as we think they might be.</p>

<p>Almost as painful as finding a project with no test suite is finding a project
whose test suite doesn&#39;t help in understanding how the system works. Tests are
code which also needs to be maintained and as such they need to very clearly
assert why they exist to a future reader.</p>
<div class="highlight"><pre><span class="n">it</span> <span class="s2">&quot;works&quot;</span> <span class="k">do</span>
  <span class="n">data</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s2">&quot;fixtures/projects.txt&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span>
  <span class="n">index</span> <span class="o">=</span> <span class="no">ProjectIndex</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
  <span class="n">index</span><span class="o">.</span><span class="n">should</span> <span class="n">have</span><span class="p">(</span><span class="mi">40</span><span class="p">)</span><span class="o">.</span><span class="n">projects</span>

  <span class="n">last_project</span> <span class="o">=</span> <span class="n">projects</span><span class="o">.</span><span class="n">last</span>
  <span class="n">last_project</span><span class="o">.</span><span class="n">title</span><span class="o">.</span><span class="n">should</span> <span class="n">eq</span><span class="p">(</span><span class="s2">&quot;ORCA&quot;</span><span class="p">)</span>
  <span class="n">last_project</span><span class="o">.</span><span class="n">customer</span><span class="o">.</span><span class="n">should</span> <span class="n">eq</span><span class="p">(</span><span class="s2">&quot;Romney-Ryan 2012&quot;</span><span class="p">)</span>
  <span class="n">last_project</span><span class="o">.</span><span class="n">deploy_date</span><span class="o">.</span><span class="n">should</span> <span class="n">eq</span><span class="p">(</span><span class="no">Date</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&quot;2012-11-06&quot;</span><span class="p">))</span>
<span class="k">end</span>
</pre></div>

<p>Well, what works? That one word description is meaningless and the example has
multiple assertions which don&#39;t provide any context.</p>

<p>In building spec-style tests you should keep the English language descriptions
you&#39;re writing front and center. One way to do this is to run RSpec with the
documentation format:</p>
<div class="highlight"><pre>jp@oeuf:~/workspace/project-manager(master)$ be rspec --format documentation spec
ProjectIndex
  .new
    instantiates an index given the contents of a project CSV file
  #projects
    returns a collection of projects from the index
Project
  #title
    returns the project title
  #customer
    returns the Customer record for the project
  #deploy_date
    calculates the deploy date from the latest project status
</pre></div>

<p>Instead of a field of green dots the documentation format outputs the nested
descriptions, contexts, and example titles you&#39;ve been typing. This allows you
to skim through to see if your tests reveal actually how the object is
intended to behave. Focusing on the output of the documentation formatter can
help improve the communicative value of a test suite. Use the refactor step of
red-green-refactor to actually make your tests a coherent explanation of why
that object exists, how it behaves, and why this behavior exists.</p>

<h3>Future Developer, Delighted</h3>

<p>These are just a few of the ways we can optimize for change with the
reasonable assumption that somebody else will be charged with making those
changes. Think about the next sets of eyes that will be responsible for
building and operating your current project when you&#39;re working on it. We&#39;ve
all felt pangs of guilt about the maintainability or quality of something
we&#39;ve shipped. Instead of feeling sympathy for all of the challenges you&#39;ve
left in the codebase, begin to tally all of the drinks Future Developer will
owe you for all of the tidy work you&#39;ve left behind.</p>

<p><em>Thanks to <a href="http://foodforsamurai.com/">Dave Yeu</a> from whom I&#39;ve co-opted (read: stolen) the term &ldquo;future developer.&rdquo;</em></p>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2012/11/multicast-in-ruby-building-a-peer-to-peer-chat-system.html</id>
    <published>2012-11-01T00:00:00+00:00</published>
    <updated>2012-11-01T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2012/11/multicast-in-ruby-building-a-peer-to-peer-chat-system.html" type="text/html" rel="alternate"/>
    <title>Multicast in Ruby: Building a Peer-to-Peer Chat System
</title>
    <summary>IP multicasting allows you to send a datagram to multiple nodes.  In this
post we'll look at multicasting and implement a simple chat system using the
ruby socket library.
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<p>IP multicasting allows a node to send one datagram to multiple interested
receivers. Hosts indicate their interest in traffic by subscribing to a
multicast address. Datagrams sent to this multicast address will be received
by all member nodes on a local network. A multicast address is any host
address in the 224/8 - 239/8 range of addresses which is reserved for
multicast.</p>

<p>Services that use multicasting are not often found on the public internet due
to the complexities involved in sharing this subscription state between
neighboring external networks and the lack of incentive for ISPs to support
it. You probably don&#39;t use multicast directly day-to-day, but if you&#39;re using
a OS X or Linux system it&#39;s likely to be a member of a couple of multicast
groups by default.</p>
<div class="highlight"><pre>jp@oeuf:~$ netstat -g
...
IPv4 Multicast Group Memberships

Group               Link-layer Address  Netif
224.0.0.1           1:0:5e:0:0:1        en0
224.0.0.251         1:0:5e:0:0:fb       en0
</pre></div>

<p><code>224.0.0.1</code> is the All Hosts multicast group.
<a href="http://www.ietf.org/rfc/rfc1112.txt"><code>RFC1122</code></a> dictates that all hosts that
fully support multicasting must always maintain a membership for it.
224.0.0.251 is the mDNS multicast group which OS X uses for DNS resolution of
the .local domain.</p>

<p>If we send an ICMP echo request to either of these addresses, we&#39;ll get back an
ICMP echo reply for each member host:</p>
<div class="highlight"><pre>jp@oeuf:~$ ping 224.0.0.251
PING 224.0.0.251 (224.0.0.251): 56 data bytes
64 bytes from 192.168.1.5: icmp_seq=0 ttl=64 time=71.531 ms
64 bytes from 192.168.1.6: icmp_seq=0 ttl=64 time=75.006 ms
</pre></div>

<p>Using <code>tcpdump</code> we can see that while we only send one request we get two replies
with the same sequence number:</p>
<div class="highlight"><pre>jp@oeuf:~$ sudo tcpdump -i en0 icmp
20:46:43.659398 IP oeuf.home &gt; 224.0.0.251: ICMP echo request, id 37572, seq 0, length 64
20:46:43.744414 IP ipad.home &gt; oeuf.home: ICMP echo reply, id 37572, seq 0, length 64
20:46:43.744425 IP apple-tv.home &gt; oeuf.home: ICMP echo reply, id 37572, seq 0, length 64
</pre></div>

<h3>Multicasting in Ruby</h3>

<p>Ruby&#39;s <code>socket</code> library exposes a wrapper to the underlying operating system
socket implementation. Normally we&#39;d be working with abstractions well above
<code>socket</code>. It&#39;s pretty low-level and isn&#39;t the friendliest library to work
with, but it allows us to directly manipulate sockets directly to properly
bind to the multicast address group.</p>

<p>Here&#39;s a basic send/receive example. The first script, <code>send.rb</code>, opens up a
UDP socket, sets the multicast TTL of the datagram to 1 to prevent it from
being forwarded beyond our local network, and sends whatever the first
command line argument passed to the script was across the socket.</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s2">&quot;socket&quot;</span>

<span class="no">MULTICAST_ADDR</span> <span class="o">=</span> <span class="s2">&quot;224.0.0.1&quot;</span>
<span class="no">PORT</span> <span class="o">=</span> <span class="mi">3000</span>

<span class="n">socket</span> <span class="o">=</span> <span class="no">UDPSocket</span><span class="o">.</span><span class="n">open</span>
<span class="n">socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="ss">:IPPROTO_IP</span><span class="p">,</span> <span class="ss">:IP_MULTICAST_TTL</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">socket</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="no">ARGV</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="no">MULTICAST_ADDR</span><span class="p">,</span> <span class="no">PORT</span><span class="p">)</span>
<span class="n">socket</span><span class="o">.</span><span class="n">close</span>
</pre></div>

<p><code>receive.rb</code> also opens a UDP socket but does a little more work to set itself
up to receive messages from the multicast address group. It sets two options
on the socket: one to add the membership to the IP multicast group and one to
allow multiple receivers to bind to the same port. The second option allows
two or more programs on the same host to receive messages from the same
multicast group. Lastly, it binds to the address and port and then sets up a
small loop to block, wait for a message, and print its contents to the
terminal.</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s2">&quot;socket&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;ipaddr&quot;</span>

<span class="no">MULTICAST_ADDR</span> <span class="o">=</span> <span class="s2">&quot;224.0.0.1&quot;</span>
<span class="no">BIND_ADDR</span> <span class="o">=</span> <span class="s2">&quot;0.0.0.0&quot;</span>
<span class="no">PORT</span> <span class="o">=</span> <span class="mi">3000</span>

<span class="n">socket</span> <span class="o">=</span> <span class="no">UDPSocket</span><span class="o">.</span><span class="n">new</span>
<span class="n">membership</span> <span class="o">=</span> <span class="no">IPAddr</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">MULTICAST_ADDR</span><span class="p">)</span><span class="o">.</span><span class="n">hton</span> <span class="o">+</span> <span class="no">IPAddr</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">BIND_ADDR</span><span class="p">)</span><span class="o">.</span><span class="n">hton</span>

<span class="n">socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="ss">:IPPROTO_IP</span><span class="p">,</span> <span class="ss">:IP_ADD_MEMBERSHIP</span><span class="p">,</span> <span class="n">membership</span><span class="p">)</span>
<span class="n">socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="ss">:SOL_SOCKET</span><span class="p">,</span> <span class="ss">:SO_REUSEPORT</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>

<span class="n">socket</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="no">BIND_ADDR</span><span class="p">,</span> <span class="no">PORT</span><span class="p">)</span>

<span class="kp">loop</span> <span class="k">do</span>
  <span class="n">message</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">recvfrom</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span>
  <span class="nb">puts</span> <span class="n">message</span>
<span class="k">end</span>
</pre></div>

<p><img src="/images/multicast-in-ruby/demo.gif" alt=""></p>

<p>The <code>socket</code> library is not the easiest to work with and usually involves a
lot of man page reading. Previous editions of the
<a href="http://pragprog.com/book/ruby3/programming-ruby-1-9">pickaxe</a> have a whole
appendix for the <code>socket</code> library but pragprog decided to remove it from the
book in the latest update. Luckily, they have <a href="http://pragprog.com/book/ruby3/programming-ruby-1-9">released its
contents</a> for free in PDF
and e-reader formats.</p>

<h3>Chat, Serverlessly</h3>

<p>Articles about building a chat server in a given toolset are a trope of
programming writing. Let&#39;s embrace the cliche and take that example but
implement it in as a peer to peer service using multicast to allow chat
clients on different hosts on the same network to exchange messages.</p>

<p>We&#39;ll call the project backchannel. Its basic operations are:</p>

<ol>
<li><p>When the client receives a message through the socket from another user,
draw the message into the window</p></li>
<li><p>When the user types in a message and hits return, send that message to
other listening clients over the socket</p></li>
</ol>

<p>Clients will become a member of a multicast group and use the group to
exchange chat messages. I used ruby to pick a random number (<code>rand(10_000)</code>)
and drew 6188 so I&#39;ll use 224.6.1.88 as the multicast address and bind to port
6188.</p>

<p>In our description we&#39;ve mentioned three different nouns: a client, a window
and a message. Let&#39;s start by doing some cocktail napkin design.</p>

<p><img src="/images/multicast-in-ruby/design.png" alt=""></p>

<p><code>Client</code> is responsible for sending and receiving messages. It exposes a
listener interface to allow listeners to be alerted to new messages and a
transmit method for sending arbitrary content across the socket.</p>

<p><code>Window</code> is responsible for managing the UI which entails drawing messages into
the terminal and capturing our input and sending new messages. It&#39;ll require a
handle onto the client to allow us to transmit messages and it&#39;ll need to keep
a backlog of messages to be able to draw chat history.</p>

<p><code>Message</code> will be transmitted as a human readable JSON objects. It will have
three attributes: a client ID, the user&#39;s handle and some message content.
Let&#39;s start with <code>Message</code> since it&#39;s a simple value object:</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s2">&quot;json&quot;</span>

<span class="k">class</span> <span class="nc">Message</span>
  <span class="kp">attr_reader</span> <span class="ss">:client_id</span><span class="p">,</span> <span class="ss">:handle</span><span class="p">,</span> <span class="ss">:content</span>

  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">inflate</span><span class="p">(</span><span class="n">json</span><span class="p">)</span>
    <span class="n">attributes</span> <span class="o">=</span> <span class="no">JSON</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">json</span><span class="p">)</span>
    <span class="kp">new</span><span class="p">(</span><span class="n">attributes</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">attributes</span><span class="o">=</span><span class="p">{})</span>
    <span class="vi">@client_id</span> <span class="o">=</span> <span class="n">attributes</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="s2">&quot;client_id&quot;</span><span class="p">)</span>
    <span class="vi">@handle</span> <span class="o">=</span> <span class="n">attributes</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="s2">&quot;handle&quot;</span><span class="p">)</span>
    <span class="vi">@content</span> <span class="o">=</span> <span class="n">attributes</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="s2">&quot;content&quot;</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">to_json</span>
    <span class="p">{</span> <span class="n">client_id</span><span class="p">:</span> <span class="n">client_id</span><span class="p">,</span> <span class="n">handle</span><span class="p">:</span> <span class="n">handle</span><span class="p">,</span> <span class="n">content</span><span class="p">:</span> <span class="n">content</span> <span class="p">}</span><span class="o">.</span><span class="n">to_json</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>No surprises there. We define an <code>attr_reader</code> for the properties we&#39;re bundling
together and some convenience methods for JSON serialization and deserialization.</p>

<p>Next we&#39;ll look at <code>Client</code>. It&#39;s the object that knows how to send and
receive messages from the multicast address group. It exposes a method for
sending messages and a hook for allowing another object to listen for new
messages. Since it&#39;s the object responsible for chat operations, it will also
generate and hold a random <code>client_id</code> and hold the user&#39;s chosen <code>handle</code>.</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s2">&quot;socket&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;thread&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;ipaddr&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;securerandom&quot;</span>

<span class="k">class</span> <span class="nc">Client</span>
  <span class="no">MULTICAST_ADDR</span> <span class="o">=</span> <span class="s2">&quot;224.6.8.11&quot;</span>
  <span class="no">BIND_ADDR</span> <span class="o">=</span> <span class="s2">&quot;0.0.0.0&quot;</span>
  <span class="no">PORT</span> <span class="o">=</span> <span class="mi">6811</span>

  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>
    <span class="vi">@handle</span>    <span class="o">=</span> <span class="n">handle</span>
    <span class="vi">@client_id</span> <span class="o">=</span> <span class="no">SecureRandom</span><span class="o">.</span><span class="n">hex</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
    <span class="vi">@listeners</span> <span class="o">=</span> <span class="o">[]</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">add_message_listener</span><span class="p">(</span><span class="n">listener</span><span class="p">)</span>
    <span class="n">listen</span> <span class="k">unless</span> <span class="n">listening?</span>
    <span class="vi">@listeners</span> <span class="o">&lt;&lt;</span> <span class="n">listener</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">transmit</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
    <span class="n">message</span> <span class="o">=</span> <span class="no">Message</span><span class="o">.</span><span class="n">new</span><span class="p">(</span>
      <span class="s2">&quot;client_id&quot;</span> <span class="o">=&gt;</span> <span class="vi">@client_id</span><span class="p">,</span>
      <span class="s2">&quot;handle&quot;</span>    <span class="o">=&gt;</span> <span class="vi">@handle</span><span class="p">,</span>
      <span class="s2">&quot;content&quot;</span>   <span class="o">=&gt;</span> <span class="n">content</span>
    <span class="p">)</span>

    <span class="n">socket</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">to_json</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="no">MULTICAST_ADDR</span><span class="p">,</span> <span class="no">PORT</span><span class="p">)</span>
    <span class="n">message</span>
  <span class="k">end</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">listen</span>
    <span class="n">socket</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="no">BIND_ADDR</span><span class="p">,</span> <span class="no">PORT</span><span class="p">)</span>

    <span class="no">Thread</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span>
      <span class="kp">loop</span> <span class="k">do</span>
        <span class="n">attributes</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">recvfrom</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
        <span class="n">message</span> <span class="o">=</span> <span class="no">Message</span><span class="o">.</span><span class="n">inflate</span><span class="p">(</span><span class="n">attributes</span><span class="p">)</span>

        <span class="k">unless</span> <span class="n">message</span><span class="o">.</span><span class="n">client_id</span> <span class="o">==</span> <span class="vi">@client_id</span>
          <span class="vi">@listeners</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">listener</span><span class="o">|</span> <span class="n">listener</span><span class="o">.</span><span class="n">new_message</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="p">}</span>
        <span class="k">end</span>
      <span class="k">end</span>
    <span class="k">end</span>

    <span class="vi">@listening</span> <span class="o">=</span> <span class="kp">true</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">listening?</span>
    <span class="vi">@listening</span> <span class="o">==</span> <span class="kp">true</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">socket</span>
    <span class="vi">@socket</span> <span class="o">||=</span> <span class="no">UDPSocket</span><span class="o">.</span><span class="n">open</span><span class="o">.</span><span class="n">tap</span> <span class="k">do</span> <span class="o">|</span><span class="n">socket</span><span class="o">|</span>
      <span class="n">socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="ss">:IPPROTO_IP</span><span class="p">,</span> <span class="ss">:IP_ADD_MEMBERSHIP</span><span class="p">,</span> <span class="n">bind_address</span><span class="p">)</span>
      <span class="n">socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="ss">:IPPROTO_IP</span><span class="p">,</span> <span class="ss">:IP_MULTICAST_TTL</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
      <span class="n">socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="ss">:SOL_SOCKET</span><span class="p">,</span> <span class="ss">:SO_REUSEPORT</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">bind_address</span>
    <span class="no">IPAddr</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">MULTICAST_ADDR</span><span class="p">)</span><span class="o">.</span><span class="n">hton</span> <span class="o">+</span> <span class="no">IPAddr</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">BIND_ADDR</span><span class="p">)</span><span class="o">.</span><span class="n">hton</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>Much of this code was adapted from the <code>send.rb</code> and <code>receive.rb</code> scripts above
but it has some of its own characteristics worth discussing. <code>listen</code> spins up
a new <code>Thread</code>. This is necessary because in order to listen for new messages
we&#39;re using a blocking call. Spinning up a <code>Thread</code> will allow our program to do
other work while waiting for new messages.</p>

<p>We&#39;ve decoupled any interested receivers of messages from <code>Client</code> by
adding a hook to allow interested parties to subscribe to messages through the
<code>add_message_listener</code> method. Now our <code>Window</code> doesn&#39;t need to have any
concrete wiring to <code>Client</code> but rather just has to register itself on
initialization and implement a <code>new_message</code> method.</p>

<p>Window manages the UI and implements another dusty ruby wrapper &ndash; <code>curses</code>.
I&#39;m going to elide most of these details as those incantations are obscure and
will be the subject of a future article.</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s2">&quot;curses&quot;</span>

<span class="k">class</span> <span class="nc">Window</span>
  <span class="kp">include</span> <span class="no">Curses</span>

  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">client</span><span class="p">)</span>
    <span class="vi">@client</span> <span class="o">=</span> <span class="n">client</span>
    <span class="vi">@messages</span> <span class="o">=</span> <span class="o">[]</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">start</span>
    <span class="vi">@client</span><span class="o">.</span><span class="n">add_message_listener</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span>

    <span class="kp">loop</span> <span class="k">do</span>
      <span class="n">capture_input</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">new_message</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
    <span class="vi">@messages</span> <span class="o">&lt;&lt;</span> <span class="n">message</span>
    <span class="n">redraw</span>
  <span class="k">end</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">capture_input</span>
    <span class="n">content</span> <span class="o">=</span> <span class="n">getstr</span>

    <span class="k">if</span> <span class="n">content</span><span class="o">.</span><span class="n">length</span> <span class="o">&gt;</span> <span class="mi">0</span>
      <span class="n">message</span> <span class="o">=</span> <span class="vi">@client</span><span class="o">.</span><span class="n">transmit</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
      <span class="n">new_message</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">redraw</span>
    <span class="n">draw_text_field</span>
    <span class="n">draw_messages</span>
    <span class="n">cursor_to_input_line</span>
    <span class="n">refresh</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>This class is fairly simple when most of the presentation layer cruft is
set aside. On initialization a <code>Client</code> is passed in and a new array is
initialized to store message history.</p>

<p>Once <code>start</code> is called, <code>Window</code> adds itself as a message listener.
<code>new_message</code> will be called by <code>Client</code> when a new message is available. That
method will add that message to the end of the array and call a <code>redraw</code>
method to do the dirty UI details.</p>

<p>User input is captured via a loop using <code>curses&#39; getstr</code> method. We pass the
content to <code>Client</code> for transmission over the network. <code>Client</code> passes us back a
<code>Message</code> which we add to the collection and redraw the screen.</p>

<p>Finally, we have some glue code to introduce <code>Client</code> and <code>Window</code> and start
the program:</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s2">&quot;backchannel/client&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;backchannel/window&quot;</span>
<span class="nb">require</span> <span class="s2">&quot;backchannel/message&quot;</span>

<span class="k">class</span> <span class="nc">Backchannel</span>
  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">start</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>
    <span class="n">client</span> <span class="o">=</span> <span class="no">Client</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>
    <span class="n">window</span> <span class="o">=</span> <span class="no">Window</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">client</span><span class="p">)</span>

    <span class="n">window</span><span class="o">.</span><span class="n">start</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>The result of these three small classes is an IRC-like program that allows any
users connected over the same physical network to pass messages. Calling
<code>Backchannel.start</code> will draw the screen and wire up the client to the
multicast address group.</p>

<p><img src="/images/multicast-in-ruby/pulp-fiction.png" alt=""></p>

<p>The <a href="http://github.com/jpignata/backchannel">full source</a> of the final
application is on GitHub and you can play with it by running <code>gem install
backchannel</code> and starting backchannel with <code>backchannel &lt;HANDLE&gt;</code>. Since we&#39;re
setting <code>SO_REUSEPORT</code>, multiple programs on the same system can connect to
the same chat for demonstration purposes.</p>

<p>I&#39;ve never used multicasting in a real-world application but will be keeping
my eyes open for an opportunity. Since we&#39;re all carrying around computers in
our pockets now, local, opt-in networks seem applicable to all kinds of things.</p>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2012/10/building-real-time-web-applications-with-server-sent-events.html</id>
    <published>2012-10-29T00:00:00+00:00</published>
    <updated>2012-10-29T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2012/10/building-real-time-web-applications-with-server-sent-events.html" type="text/html" rel="alternate"/>
    <title>Building Real-Time Web Applications with Server-Sent Events</title>
    <summary>We're supposedly living in the bright, shiny future of the real-time web but
often we're still just polling. Let's look at implementing a real-time channel
between clients and servers using Server-Sent Events.
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<p>In the long, long ago, to add real-time content to a web page your only option
was a kludge of a JavaScript timer to poll an HTTP endpoint via XHR and
manipulate the page when new data became available. Still common (and even
<a href="https://twitter.com/dhh/status/251005914344222720">preferred by some</a>), Ajax
polling seems inefficient at best and retrograde at worst. Every few seconds
we have to spin up a TCP connection, send a full HTTP request, wait for the
server to do some kind of work, and snarf back and parse an entire HTTP response.</p>

<p>All of these redundant connections and chatter aren&#39;t free. As more traffic
moves to mobile clients these inefficiencies have real-world impact on users&#39;
device battery life and data transfer costs. Keepalive and <code>If-Modified-Since</code>
or <code>ETag</code> request headers might help but your server is still tied up on each
request doing redundant work for each client to figure out if there&#39;s new
content and your clients are still burning cycles spinning through this
process. Moreover, HTTP requests often become bloated with attributes like
cookies, locale preferences, tweet-sized user-agent strings, etc. that are
unnecessarily shoveled across the connection in each request.</p>

<h3>Server-Sent Events (SSE)</h3>

<p>An alternative to polling is the Server-Sent Events API. SSE provides a
simplex connection between a server and a client that allows the server to
trigger events in the browser. Web applications can bind a callback to these
events via JavaScript.</p>

<p>WebSockets has gotten much more attention than Server-Sent Events. One good
reason for this is that WebSockets is much more fully featured than SSE.
It&#39;s essentially a completely separate protocol from HTTP that provides a
full-duplex connection which makes it more attractive for applications that
require low-latency bi-directional communication. The trade-off is that since
it&#39;s not HTTP there&#39;s added complexity in implementing it. For example,
much of the HTTP infrastructure deployed out in the wild isn&#39;t necessarily
aware of WebSockets and consequently the protocol&#39;s traffic can&#39;t traverse it.
As it stands today getting a WebSockets-speaking server propped up behind a
traditional load balancer can prove to be somewhat painful.</p>

<p>SSE doesn&#39;t have any of this overhead as it uses traditional HTTP for transport.
It&#39;s directed at real-world network environments so it has features like
automatic reconnection baked into it. It&#39;s exposed in the browser via the
<a href="https://developer.mozilla.org/en-US/docs/Server-sent_events/EventSource"><code>EventSource</code></a>
interface so it&#39;s trivial to write a shim for <a href="http://en.wikipedia.org/wiki/Server-sent_events#Web_browsers">browsers that don&#39;t support it</a> to fall back to long-polling.</p>

<p>A SSE event only has a couple of attributes and looks something like YAML:</p>
<div class="highlight"><pre><span class="l-Scalar-Plain">id</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">1</span>
<span class="l-Scalar-Plain">event</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">new-message</span>
<span class="l-Scalar-Plain">data</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">oh, hi!</span>
</pre></div>

<p><code>event</code> is an optional custom name of the event to trigger. JavaScript
applications can bind to specific events or choose to bind to all messages.
<code>data</code> is what&#39;s passed into the event when triggered. <code>id</code> is an optional
unique identifier for the message. If provided, <code>Last-Event-ID</code> will be sent
back to the server on reconnect for applications where messages can&#39;t be
dropped. SSE also allows a server to specify a <code>retry</code> in milliseconds and 
comments can be sent with a line starting with a colon.</p>

<p>Binding to these events using JavaScript is straight-forward:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">stream</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventSource</span><span class="p">(</span><span class="s2">&quot;/stream&quot;</span><span class="p">);</span>

<span class="nx">stream</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">&quot;new-message&quot;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
<span class="p">});</span>
</pre></div>

<p>Any <code>new-message</code> events that are transmitted through the connection will now
trigger this callback and log the message to the console.</p>

<p>The <a href="http://www.w3.org/TR/eventsource/">specification</a> envisions the protocol
to be extensible to serve other purposes outside the browser. For example,
it&#39;s possible to extend it to be used as a transport to deliver push
notifications to mobile devices over TCP/IP or SMS networks.</p>

<h3>Picture Frame</h3>

<p>Let&#39;s build a small application to illustrate how Server-Sent Events works.
In this example we&#39;ll put together a toy application that creates a shared picture
frame. Any user can enter a search term which searches Flickr&#39;s API for that
term, retrieves a random image from the results and broadcasts it via a
Server-Sent Event. Each client subscribed will receive the event and update the
background of the page.</p>

<p><img src="/images/server-sent-events/sushi.png" alt="">
<img src="/images/server-sent-events/pumpkin.png" alt="">
<img src="/images/server-sent-events/ice-cream.png" alt="">
<img src="/images/server-sent-events/clownfish.png" alt=""></p>

<p>We&#39;ll use small components to keep the example focused and forego using any
specific framework. Since we want to be able to service connections
concurrently we&#39;ll use <a href="http://code.macournoyer.com/thin/">Thin</a> as an
application server. Our implementation of the picture frame will be a Rack
application behind <a href="https://github.com/joshbuddy/http_router">HTTP Router</a> for
routing between our actions and serving static content. We expect to have at
least two actions: one to subscribe to the SSE stream, one to publish new
content to the stream, a static HTML page to display the frame and a little
JavaScript to act on events from the stream.</p>

<p>If you return a <code>Deferrable</code> as the body of a response, <a href="https://github.com/macournoyer/thin/blob/master/lib/thin/connection.rb#L115">Thin will keep the
connection open</a> until the deferred object is complete. <a href="http://eventmachine.rubyforge.org/docs/DEFERRABLES.html"><code>Deferrable</code>
objects</a> represent an
operation in flight and accept two callbacks: a <code>callback</code> which is fired on
success and an <code>errback</code> which is fired on failure. We&#39;ll create a deferred
body which can be used to write to the active connection and to signal to Thin
when we want to close the connection.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Body</span>
  <span class="kp">include</span> <span class="no">EM</span><span class="o">::</span><span class="no">Deferrable</span>

  <span class="k">def</span> <span class="nf">each</span><span class="p">(</span><span class="o">&amp;</span><span class="n">block</span><span class="p">)</span>
    <span class="vi">@callback</span> <span class="o">=</span> <span class="n">block</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
    <span class="vi">@callback</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>When Thin calls <code>each</code> it&#39;ll pass a block that can be used to emit data to
the connection. We store that block and expose a <code>write</code> method for
calling it.</p>

<p>We can use this to build an endpoint that can handle concurrent connections
as long as we&#39;re careful not to block the reactor. Here&#39;s an example
rackup file that mounts a small Rack application that returns a ping each second
four times and then closes the connection.</p>
<div class="highlight"><pre><span class="n">app</span> <span class="o">=</span> <span class="o">-&gt;</span><span class="p">(</span><span class="n">env</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
  <span class="n">body</span> <span class="o">=</span> <span class="no">Body</span><span class="o">.</span><span class="n">new</span>

  <span class="n">timer</span> <span class="o">=</span> <span class="no">EM</span><span class="o">.</span><span class="n">add_periodic_timer</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">body</span><span class="o">.</span><span class="n">write</span> <span class="s2">&quot;ping</span><span class="se">\n\n</span><span class="s2">&quot;</span>
    <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>

    <span class="k">if</span> <span class="n">count</span> <span class="o">==</span> <span class="mi">5</span>
      <span class="n">timer</span><span class="o">.</span><span class="n">cancel</span>

      <span class="n">body</span><span class="o">.</span><span class="n">write</span> <span class="s2">&quot;ok, bye!</span><span class="se">\n\n</span><span class="s2">&quot;</span>
      <span class="n">body</span><span class="o">.</span><span class="n">succeed</span>
    <span class="k">end</span>
  <span class="p">}</span>

  <span class="o">[</span><span class="mi">200</span><span class="p">,</span> <span class="p">{</span><span class="s2">&quot;Content-Type&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;text/plain&quot;</span><span class="p">},</span> <span class="n">body</span><span class="o">]</span>
<span class="p">}</span>

<span class="n">run</span> <span class="n">app</span>
</pre></div>

<p>Now when we start the server it&#39;ll accept connections on the specified port
and only close that connection after four pings.</p>
<div class="highlight"><pre>jp@oeuf:~/workspace/tmp$ thin start -R example.ru -p 4000
&gt;&gt; Thin web server (v1.5.0 codename Knife)
&gt;&gt; Maximum connections set to 1024
&gt;&gt; Listening on 0.0.0.0:4000, CTRL+C to stop
</pre></div>

<p><img src="/images/server-sent-events/curl.gif" alt=""></p>

<p>Now to the picture frame. Let&#39;s start with the subscribe action. This endpoint
will subscribe a user to the stream so it should keep the connection alive and
send events when they are triggered by another user. To start we&#39;ll build
a class that expects to be instantiated with a Rack <code>env</code> and a channel object
which will be used to transmit messages to subscribers.</p>
<div class="highlight"><pre><span class="k">module</span> <span class="nn">Actions</span>
  <span class="k">class</span> <span class="nc">Subscribe</span>
    <span class="no">HEADERS</span> <span class="o">=</span> <span class="p">{</span>
      <span class="s2">&quot;Content-Type&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;text/event-stream&quot;</span><span class="p">,</span>
      <span class="s2">&quot;Connection&quot;</span>    <span class="o">=&gt;</span> <span class="s2">&quot;keepalive&quot;</span><span class="p">,</span>
      <span class="s2">&quot;Cache-Control&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;no-cache, no-store&quot;</span>
    <span class="p">}</span>

    <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">channel</span><span class="p">)</span>
      <span class="vi">@env</span> <span class="o">=</span> <span class="n">env</span>
      <span class="vi">@body</span> <span class="o">=</span> <span class="no">Body</span><span class="o">.</span><span class="n">new</span>
      <span class="vi">@channel</span> <span class="o">=</span> <span class="n">channel</span>
    <span class="k">end</span>

    <span class="k">def</span> <span class="nf">run</span>
      <span class="vi">@channel</span><span class="o">.</span><span class="n">subscribe</span> <span class="k">do</span> <span class="o">|</span><span class="n">message</span><span class="o">|</span>
        <span class="n">body</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;event: picture</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
        <span class="n">body</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;data: </span><span class="si">#{</span><span class="n">data</span><span class="o">.</span><span class="n">to_json</span><span class="si">}</span><span class="se">\n\n</span><span class="s2">&quot;</span><span class="p">)</span>
      <span class="k">end</span>

      <span class="o">[</span><span class="mi">200</span><span class="p">,</span> <span class="no">HEADERS</span><span class="p">,</span> <span class="vi">@body</span><span class="o">]</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>This is the entirety of the server-side code necessary to build a Server-Sent
Events stream. We set the <code>Content-Type</code> of the response to <code>text/event-stream</code>
and setup our channel subscription to trigger a <code>picture</code> event when a new
message is received from the channel.</p>

<p>Next we&#39;ll build an endpoint for a user to perform a search. The publish
endpoint expects to receive a POST with a keyword parameter. It takes that
keyword and uses a <code>FlickrSearch</code> class to get the data to publish back to the
channel. For good measure it also sends the result to the original publisher
and suceeds the <code>Deferrable</code> which closes the channel. <code>FlickrSearch</code> is a
<code>Deferrable</code> that uses <code>em-http-request</code> to fetch data from Flickr and return
the result asynchronously. The result is an object that responds to <code>to_json</code>
and returns a hash that includes the original keyword that was used for the
search and the URL to a random result.</p>
<div class="highlight"><pre><span class="k">module</span> <span class="nn">Actions</span>
  <span class="k">class</span> <span class="nc">Publish</span>
    <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">channel</span><span class="p">)</span>
      <span class="vi">@env</span> <span class="o">=</span> <span class="n">env</span>
      <span class="vi">@channel</span> <span class="o">=</span> <span class="n">channel</span>
      <span class="vi">@body</span> <span class="o">=</span> <span class="no">Body</span><span class="o">.</span><span class="n">new</span>
    <span class="k">end</span>

    <span class="k">def</span> <span class="nf">run</span>
      <span class="n">search</span> <span class="o">=</span> <span class="no">FlickrSearch</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="s2">&quot;keyword&quot;</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">get</span>

      <span class="n">search</span><span class="o">.</span><span class="n">callback</span> <span class="k">do</span> <span class="o">|</span><span class="n">result</span><span class="o">|</span>
        <span class="vi">@channel</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>

        <span class="vi">@body</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">to_json</span><span class="p">)</span>
        <span class="vi">@body</span><span class="o">.</span><span class="n">succeed</span>
      <span class="k">end</span>

      <span class="n">search</span><span class="o">.</span><span class="n">errback</span> <span class="p">{</span> <span class="vi">@body</span><span class="o">.</span><span class="n">fail</span> <span class="p">}</span>

      <span class="o">[</span><span class="mi">200</span><span class="p">,</span> <span class="p">{</span><span class="s2">&quot;Content-Type&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;application/json&quot;</span><span class="p">},</span> <span class="n">body</span><span class="o">]</span>
    <span class="k">end</span>

    <span class="kp">private</span>

    <span class="k">def</span> <span class="nf">params</span>
      <span class="vi">@params</span> <span class="o">||=</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Utils</span><span class="o">.</span><span class="n">parse_query</span><span class="p">(</span><span class="vi">@env</span><span class="o">[</span><span class="s2">&quot;rack.input&quot;</span><span class="o">].</span><span class="n">read</span><span class="p">)</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>The only page of the application will be a small, static HTML page to setup
the a form to allow searches.</p>
<div class="highlight"><pre><span class="nt">&lt;html&gt;</span>
  <span class="nt">&lt;head&gt;</span>
    <span class="nt">&lt;style </span><span class="na">type=</span><span class="s">&quot;text/css&quot;</span><span class="nt">&gt;</span>
      <span class="nt">input</span> <span class="p">{</span>
        <span class="k">position</span><span class="o">:</span> <span class="k">absolute</span><span class="p">;</span>
        <span class="k">font-size</span><span class="o">:</span> <span class="m">48px</span><span class="p">;</span>
        <span class="k">bottom</span><span class="o">:</span> <span class="m">10px</span><span class="p">;</span>
      <span class="p">}</span>
    <span class="nt">&lt;/style&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;/js/application.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
  <span class="nt">&lt;/head&gt;</span>
  <span class="nt">&lt;body&gt;</span>
    <span class="nt">&lt;form&gt;</span>
      <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;text&quot;</span><span class="nt">&gt;&lt;/input&gt;</span>
    <span class="nt">&lt;/form&gt;</span>
  <span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</pre></div>

<p>To wire up the page to our stream we have a little bit of CoffeeScript glue
code.</p>
<div class="highlight"><pre><span class="nx">source</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventSource</span><span class="p">(</span><span class="s2">&quot;/subscribe&quot;</span><span class="p">)</span>

<span class="nx">source</span><span class="p">.</span><span class="nx">addEventListener</span> <span class="s2">&quot;picture&quot;</span><span class="p">,</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="o">-&gt;</span>
  <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">)</span>
  <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;body, input&quot;</span><span class="p">).</span><span class="nx">trigger</span> <span class="s2">&quot;changeBackground&quot;</span><span class="p">,</span> <span class="p">[</span><span class="nx">data</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">data</span><span class="p">.</span><span class="nx">keyword</span><span class="p">]</span>

<span class="nx">jQuery</span> <span class="o">-&gt;</span>
  <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;body&quot;</span><span class="p">).</span><span class="nx">bind</span> <span class="s2">&quot;changeBackground&quot;</span><span class="p">,</span> <span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">url</span><span class="p">,</span> <span class="nx">keyword</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">css</span><span class="p">(</span>
      <span class="s2">&quot;background&quot;</span><span class="o">:</span>              <span class="s2">&quot;url(#{url}) no-repeat center center fixed&quot;</span>
      <span class="s2">&quot;-webkit-background-size&quot;</span><span class="o">:</span> <span class="s2">&quot;cover&quot;</span>
      <span class="s2">&quot;-moz-background-size&quot;</span><span class="o">:</span>    <span class="s2">&quot;cover&quot;</span>
      <span class="s2">&quot;background-size&quot;</span><span class="o">:</span>         <span class="s2">&quot;cover&quot;</span>
    <span class="p">)</span>

  <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;input&quot;</span><span class="p">).</span><span class="nx">bind</span> <span class="s2">&quot;changeBackground&quot;</span><span class="p">,</span> <span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">url</span><span class="p">,</span> <span class="nx">keyword</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">val</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s2">&quot;placeholder&quot;</span><span class="p">,</span> <span class="nx">keyword</span><span class="p">)</span>

  <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;form&quot;</span><span class="p">).</span><span class="nx">submit</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nx">event</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">()</span>
    <span class="nx">input</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">find</span><span class="p">(</span><span class="s2">&quot;input&quot;</span><span class="p">)</span>
    <span class="nx">$</span><span class="p">.</span><span class="nx">post</span> <span class="s2">&quot;/publish&quot;</span><span class="p">,</span> <span class="nv">keyword: </span><span class="nx">input</span><span class="p">.</span><span class="nx">val</span><span class="p">()</span>
</pre></div>

<p>The call to <code>EventSource</code> is all that is required to open up the stream.  When
we receive a picture event, we trigger a <code>changeBackground</code> event on our
<code>&lt;body&gt;</code> and <code>&lt;input&gt;</code> elements. The <code>jQuery</code> block sets up the nodes to
respond to <code>changeBackground</code> with their respective presentation logic. The
input clears what has been typed into it and sets a placeholder with the last
search and the body changes its background to the search&#39;s returned URL and
does some CSS incantations to make the background appear full screen.</p>

<p>We also bind a <code>submit</code> callback to our form to wire it up to POST to our
publish endpoint as an XHR request rather than a postback. Since we don&#39;t have
full-duplex communication via SSE, we&#39;re cheating by using Ajax for upstream
communications. This SSE Down/ Ajax Up approach is completely acceptable for
this application, but if it wasn&#39;t for some reason we might consider
WebSockets instead.</p>

<p>The Rack application to make these pieces work together is quite small. We&#39;re
going to inject a memoized <code>EventMachine::Channel</code> into each action to act as
the application&#39;s event bus and rely on <code>HTTP Router</code> to route requests to our
actions and serve our static index page and compiled JavaScript.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">PictureFrame</span>
  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">app</span>
    <span class="vi">@routes</span> <span class="o">||=</span> <span class="no">HttpRouter</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span>
      <span class="n">post</span><span class="p">(</span><span class="s2">&quot;/publish&quot;</span><span class="p">)</span><span class="o">.</span>
        <span class="n">to</span> <span class="p">{</span> <span class="o">|</span><span class="n">env</span><span class="o">|</span> <span class="no">Actions</span><span class="o">::</span><span class="no">Publish</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="no">PictureFrame</span><span class="o">.</span><span class="n">channel</span><span class="p">)</span><span class="o">.</span><span class="n">run</span> <span class="p">}</span>
      <span class="n">get</span><span class="p">(</span><span class="s2">&quot;/subscribe&quot;</span><span class="p">)</span><span class="o">.</span>
        <span class="n">to</span> <span class="p">{</span> <span class="o">|</span><span class="n">env</span><span class="o">|</span> <span class="no">Actions</span><span class="o">::</span><span class="no">Subscribe</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="no">PictureFrame</span><span class="o">.</span><span class="n">channel</span><span class="p">)</span><span class="o">.</span><span class="n">run</span> <span class="p">}</span>
      <span class="n">add</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">static</span><span class="p">(</span><span class="s2">&quot;public/index.html&quot;</span><span class="p">)</span>
      <span class="n">add</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">static</span><span class="p">(</span><span class="s2">&quot;public&quot;</span><span class="p">)</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">channel</span>
    <span class="vi">@channel</span> <span class="o">||=</span> <span class="no">EventMachine</span><span class="o">::</span><span class="no">Channel</span><span class="o">.</span><span class="n">new</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>Now that everything&#39;s stitched together, all users on the page will see its
background changed when another user enters a search term. It looks something
like this:</p>

<p><img src="/images/server-sent-events/demo.gif" alt=""></p>
<div class="highlight"><pre><span class="nx">event</span><span class="o">:</span> <span class="nx">picture</span>
<span class="nx">data</span><span class="o">:</span> <span class="p">{</span><span class="s2">&quot;url&quot;</span><span class="o">:</span><span class="s2">&quot;//farm1.staticflickr.com/48/177506457_6da382ee6d_z.jpg&quot;</span><span class="p">,</span><span class="s2">&quot;keyword&quot;</span><span class="o">:</span><span class="s2">&quot;sushi&quot;</span><span class="p">}</span>

<span class="nx">event</span><span class="o">:</span> <span class="nx">picture</span>
<span class="nx">data</span><span class="o">:</span> <span class="p">{</span><span class="s2">&quot;url&quot;</span><span class="o">:</span><span class="s2">&quot;//farm4.staticflickr.com/3611/3376337890_bdbd465a7b_z.jpg&quot;</span><span class="p">,</span><span class="s2">&quot;keyword&quot;</span><span class="o">:</span><span class="s2">&quot;french fries&quot;</span><span class="p">}</span>

<span class="nx">event</span><span class="o">:</span> <span class="nx">picture</span>
<span class="nx">data</span><span class="o">:</span> <span class="p">{</span><span class="s2">&quot;url&quot;</span><span class="o">:</span><span class="s2">&quot;//farm5.staticflickr.com/4082/4861386139_e6d25a7b35_z.jpg&quot;</span><span class="p">,</span><span class="s2">&quot;keyword&quot;</span><span class="o">:</span><span class="s2">&quot;staten island ferry&quot;</span><span class="p">}</span>

<span class="nx">event</span><span class="o">:</span> <span class="nx">picture</span>
<span class="nx">data</span><span class="o">:</span> <span class="p">{</span><span class="s2">&quot;url&quot;</span><span class="o">:</span><span class="s2">&quot;//farm4.staticflickr.com/3566/3683645594_f8f9ce7091_z.jpg&quot;</span><span class="p">,</span><span class="s2">&quot;keyword&quot;</span><span class="o">:</span><span class="s2">&quot;flatiron building&quot;</span><span class="p">}</span>
</pre></div>

<p><a href="http://picture-frame.herokuapp.com">The final application</a> is deployed to
Heroku and <a href="http://github.com/jpignata/picture-frame">the source</a> is on
GitHub.</p>

<h3>Using SSE in Your Applications</h3>

<p>If you only need a simplex channel to a web client to update some data,
Server-Sent Events is a viable alternative to crufty polling or complex
WebSockets. Even with bi-directional requirements SSE Down/Ajax Up might be
sufficient and save you the trouble of turning up a WebSockets connection.</p>

<p><a href="http://tenderlovemaking.com/2012/07/30/is-it-live.html">Rails 4.0 can be used</a> to
build these endpoints. <a href="http://postrank-labs.github.com/goliath/">Goliath</a> or
<a href="http://cramp.in/">Cramp</a> can also be used <a href="http://www.html5rocks.com/en/tutorials/casestudies/sunlight_streamcongress/">to implement SSE</a> with a
Ruby server. Implementation from scratch with Node.js, Twisted and Python,
or your particular weapon of choice is likely just as straight-forward.</p>

<p>On the client side of the wall it&#39;s already built into most browsers and
easily reusable by your native applications. Since it&#39;s a simple DOM interface
it&#39;s trivial to use SSE to make your dynamic functionality more efficient
for sufficiently modern browsers while maintaining chattier long-polling
for older browsers.</p>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2012/10/when-should-i-use-protected-method-visibility-in-ruby.html</id>
    <published>2012-10-26T00:00:00+00:00</published>
    <updated>2012-10-26T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2012/10/when-should-i-use-protected-method-visibility-in-ruby.html" type="text/html" rel="alternate"/>
    <title>When Should I Use Protected Method Visibility in Ruby?</title>
    <summary>The semantics of protected method visibility hardly ever seem applicable.
Why does this language feature exist and how is it used by open source
projects?
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<p>When I&#39;m reading Ruby code and I come across protected methods, I spend
a moment taking a deeper look at the interface of the object defining them.
Protected method visibility is targeted to a very specific and seemingly rare
use-case in Ruby: methods defined as protected are only callable by other
objects whose class is of the same defining class or its subclasses. The
<a href="http://pragprog.com/book/ruby3/programming-ruby-1-9">pickaxe book</a> calls this
&ldquo;keeping it within the family.&rdquo; <a href="http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177"><em>The Ruby Programming
Language</em></a>
describes protected as &ldquo;the least commonly defined and
also the most difficult to understand&rdquo; of the method visibility types, so when
I do see it I wonder what the author is trying to communicate. Is it a hint
about the stability of the methods? Are the objects actually using protected
access between instances? Did he or she want to encapsulate some behavior but
use explicit <code>self</code> as a matter of style? Was this some unfortunate pattern
promulgated by some random Ruby on Rails tutorial in 2007? Why would you reach
for <code>protected</code> when the semantics of <code>private</code> seem sufficient to encapsulate
an object&#39;s behavior?</p>

<p>Let&#39;s look at some of the common applications of protected method visibility.
Some common patterns I&#39;ve noticed are: attributes for comparison operations,
mutator methods for immutable objects, fulfilling an abstract class&#39; contract,
and framework hooks.</p>

<h3>Attributes for Comparison Operations</h3>

<p>The most common employment of <code>protected</code> is applying it to attributes or
methods that are necessary to compare two instances to each other without
exposing that information in the object&#39;s public interface. Since operators on
an object are actually method calls, we can override these methods and provide
our own comparison logic for operations on an object. <code>protected</code> allows these
objects to expose data needed in a comparison to each other but continue to
hide it from the rest of the system.</p>

<p>For example, let&#39;s look at a simple <code>Collection</code> object. This object is
responsible for management of a collection of items. The <code>Collection</code> doesn&#39;t
expose the items directly but rather defines an interface for interacting with
the internal array.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Collection</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">items</span><span class="o">=[]</span><span class="p">)</span>
    <span class="vi">@items</span> <span class="o">=</span> <span class="n">items</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>Two <code>Collection</code> instances are deemed to be equal if they hold the same number
of elements and the elements are in the same order. To expose this operation
we define a method <code>==</code> on <code>Collection</code>:</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Collection</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">items</span><span class="o">=[]</span><span class="p">)</span>
    <span class="vi">@items</span> <span class="o">=</span> <span class="n">items</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">==</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
    <span class="c1"># TODO: Compare our items to the other collection&#39;s items</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>In order to compare the arrays we&#39;ll need to add an <code>items</code> getter but
continue to hide this data from external callers. If we add a getter without
specifying access control, a caller could access the contents of the array
directly but if we set this method private, nobody &ndash; including sibling
objects &ndash; will be able to access the property. <code>protected</code> does exactly what
we want.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Collection</span>
  <span class="kp">attr_reader</span> <span class="ss">:items</span>
  <span class="kp">protected</span> <span class="ss">:items</span>

  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">items</span><span class="o">=[]</span><span class="p">)</span>
    <span class="vi">@items</span> <span class="o">=</span> <span class="n">items</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">==</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
    <span class="n">items</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">items</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p><code>Collection</code> instances can now compare themselves to each other while still
hiding their data from other callers. <code>Collection</code> objects will only respond to
items for sibling <code>Collection</code> instances; calls from other objects will raise a
<code>NoMethodError</code>.</p>
<div class="highlight"><pre><span class="no">Collection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">]</span><span class="p">)</span> <span class="o">==</span> <span class="no">Collection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">]</span><span class="p">)</span>
<span class="c1"># =&gt; true</span>

<span class="no">Collection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">]</span><span class="p">)</span> <span class="o">==</span> <span class="no">Collection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span><span class="p">)</span>
<span class="c1"># =&gt; false</span>

<span class="o">&gt;&gt;</span> <span class="no">Collection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">items</span>
<span class="c1"># NoMethodError: protected method `items&#39; called for #&lt;Collection:0x007fdaf30450a8 @items=[1, 2, 3]&gt;</span>
</pre></div>

<p>The usual caveat here is that in Ruby access control is &ldquo;just a suggestion&rdquo;
and a user of an object can still reach in and access anything regardless of
its visibility. For example:</p>
<div class="highlight"><pre><span class="no">Collection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">instance_variable_get</span><span class="p">(:</span><span class="vi">@items</span><span class="p">)</span>
<span class="c1"># =&gt; [1, 2, 3]</span>

<span class="no">Collection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="ss">:items</span><span class="p">)</span>
<span class="c1"># =&gt; [1, 2, 3]</span>
</pre></div>

<p>While this is true, there&#39;s still value in signaling your intentions to users
of the object. Setting explicit access controls guides users to our defined
interface and discourages fiddling with internals.</p>

<p>The Ruby standard library class <code>OpenStruct</code> uses this pattern. <code>OpenStruct</code>
allows a user to set arbitrary attributes that can be accessed with dot
notation.</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s2">&quot;ostruct&quot;</span>

<span class="n">book</span> <span class="o">=</span> <span class="no">OpenStruct</span><span class="o">.</span><span class="n">new</span>
<span class="n">book</span><span class="o">.</span><span class="n">title</span>  <span class="o">=</span> <span class="s2">&quot;The Art of Fielding&quot;</span>
<span class="n">book</span><span class="o">.</span><span class="n">author</span> <span class="o">=</span> <span class="s2">&quot;Chad Harbach&quot;</span>

<span class="n">book</span><span class="o">.</span><span class="n">title</span>
<span class="c1"># =&gt; &quot;The Art of Fielding</span>

<span class="n">book</span><span class="o">.</span><span class="n">author</span>
<span class="c1"># =&gt; &quot;Chad Harbach&quot;</span>
</pre></div>

<p>An <code>OpenStruct</code> is considered equal to another <code>OpenStruct</code> when they hold the
same attributes. Under the hood <code>OpenStruct</code> stores these attributes in an
internal hash table. It exposes this table as a protected method which allows
other <code>OpenStruct</code> instances to determine equivalence. This is implemented
similarly to the <code>Collection</code> example:</p>
<div class="highlight"><pre><span class="c1"># lib/ostruct.rb:224 (ruby 1.9.3-p286)</span>

<span class="kp">attr_reader</span> <span class="ss">:table</span> <span class="c1"># :nodoc:</span>
<span class="kp">protected</span> <span class="ss">:table</span>

<span class="c1">#</span>
<span class="c1"># Compares this object and +other+ for equality.  An OpenStruct is equal &gt;</span>
<span class="c1"># +other+ when +other+ is an OpenStruct and the two object&#39;s Hash tables &gt;</span>
<span class="c1"># equal.</span>
<span class="c1">#</span>
<span class="k">def</span> <span class="nf">==</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
  <span class="k">return</span> <span class="kp">false</span> <span class="k">unless</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">kind_of?</span><span class="p">(</span><span class="no">OpenStruct</span><span class="p">))</span>
  <span class="k">return</span> <span class="vi">@table</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">table</span>
<span class="k">end</span>
</pre></div>

<h3>Mutator Methods for Immutable Objects</h3>

<p>Another use of <code>protected</code> I found in the Ruby standard library is using
protected methods to maintain the immutability of a value object. Let&#39;s say
we&#39;ve decided our <code>Collection</code> is a value object and <a href="http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable">should be
immutable</a>. There are
new requirements that necessitate some operations that require <code>Collection</code> to
change during runtime. Let&#39;s start with the first: the sum of two <code>Collection</code>
instances is a new <code>Collection</code> which holds a superset of the summands&#39;
arrays.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Collection</span>
  <span class="kp">attr_reader</span> <span class="ss">:items</span>
  <span class="kp">protected</span> <span class="ss">:items</span>

  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">items</span><span class="o">=[]</span><span class="p">)</span>
    <span class="vi">@items</span> <span class="o">=</span> <span class="n">items</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">==</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
    <span class="n">items</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">items</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">+</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
    <span class="c1"># TODO: Add our items to the other collection&#39;s items</span>
    <span class="c1"># and return a new collection with the sum.</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>Since we&#39;ve marked <code>items</code> as <code>protected</code> we can reach in from one instance
into another, grab these items, add them to our items and instantiate a new
collection.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Collection</span>
  <span class="kp">attr_reader</span> <span class="ss">:items</span>
  <span class="kp">protected</span> <span class="ss">:items</span>

  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">items</span><span class="o">=[]</span><span class="p">)</span>
    <span class="vi">@items</span> <span class="o">=</span> <span class="n">items</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">==</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
    <span class="n">items</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">items</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">+</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
    <span class="nb">self</span><span class="o">.</span><span class="n">class</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">items</span> <span class="o">+</span> <span class="n">other</span><span class="o">.</span><span class="n">items</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="no">Collection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">)</span> <span class="o">+</span> <span class="no">Collection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">4</span><span class="o">]</span><span class="p">)</span>
<span class="c1"># =&gt; #&lt;Collection:0x007f809207e1c0 @items=[1, 4]&gt;</span>
</pre></div>

<p>This simple example is fairly similar to our last &ndash; it involves overriding an
operator method and using privileged data from the sibling instance in the
operations. While state in neither <code>Collection</code> changed, they were able to
collaborate and return a new <code>Collection</code> with the desired <code>items</code>.</p>

<p><code>IPAddr</code> is a class in the Ruby standard library which is a value object that
represents an IPv4 or IPv6 address. Under the hood it makes extensive use of
this pattern for manipulating the IP address it represent.</p>

<p>Given an IP address (say, <code>192.168.0.77</code>) and a subnet mask
(<code>255.255.255.248</code>), we can use bitwise operations to figure out the upper and
lower boundaries of the network of which this host is a member. The lower
boundary is referred to as the network address and the upper boundary as the
broadcast address.</p>
<div class="highlight"><pre><span class="c1"># For more detail around IP addressing basics see TCP/IP</span>
<span class="c1"># Illustrated (Second Edition) pp. 31-43</span>

<span class="n">address</span> <span class="o">=</span> <span class="no">IPAddr</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;192.168.0.77&quot;</span><span class="p">)</span>
<span class="c1"># #&lt;IPAddr: IPv4:192.168.0.77/255.255.255.255&gt;</span>

<span class="c1"># To calculate an IP address&#39; network address, each bit</span>
<span class="c1"># in the address is bitwise ANDed with each corresponding</span>
<span class="c1"># bit in the subnet mask.</span>
<span class="n">address</span> <span class="o">&amp;</span> <span class="no">IPAddr</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;255.255.255.248&quot;</span><span class="p">)</span>
<span class="c1"># #&lt;IPAddr: IPv4:192.168.0.72/255.255.255.255&gt;</span>

<span class="c1"># To calculate an IP address&#39; broadcast address, take</span>
<span class="c1"># the inverse of the subnet mask (flip ones to zeroes</span>
<span class="c1"># and vice-versa), and perform a bitwise OR against each</span>
<span class="c1"># bit in the address.</span>
<span class="n">address</span> <span class="o">|</span> <span class="p">(</span><span class="o">~</span> <span class="no">IPAddr</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;255.255.255.248&quot;</span><span class="p">))</span>
<span class="c1"># #&lt;IPAddr: IPv4:192.168.0.79/255.255.255.255&gt;</span>

<span class="c1"># So our IP address 192.168.0.77 with subnet mask</span>
<span class="c1"># 255.255.255.248 lies on a network whose network address</span>
<span class="c1"># is 192.168.0.72 and whose broadcast address is 192.168.0.79.</span>
</pre></div>

<p><code>IPAddr</code> exposes these operations but maintains immutability by cloning itself
and calling protected methods on the new instance.</p>
<div class="highlight"><pre><span class="c1"># lib/ipaddr.rb:108 (ruby 1.9.3-p286)</span>

<span class="c1"># Returns a new ipaddr built by bitwise AND.                                  </span>
<span class="k">def</span> <span class="nf">&amp;</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>                                                                  
 <span class="k">return</span> <span class="nb">self</span><span class="o">.</span><span class="n">clone</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="vi">@addr</span> <span class="o">&amp;</span> <span class="n">coerce_other</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">to_i</span><span class="p">)</span>                     
<span class="k">end</span>                                                                           

<span class="c1"># Returns a new ipaddr built by bitwise OR.                                   </span>
<span class="k">def</span> <span class="nf">|</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>                                                                  
  <span class="k">return</span> <span class="nb">self</span><span class="o">.</span><span class="n">clone</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="vi">@addr</span> <span class="o">|</span> <span class="n">coerce_other</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">to_i</span><span class="p">)</span>                     
<span class="k">end</span>

<span class="c1"># lib/ipaddr.rb:128 (ruby 1.9.3-p286)</span>

<span class="c1"># Returns a new ipaddr built by bitwise negation.                             </span>
<span class="k">def</span> <span class="nf">~</span>                                                                         
  <span class="k">return</span> <span class="nb">self</span><span class="o">.</span><span class="n">clone</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">addr_mask</span><span class="p">(</span><span class="o">~</span><span class="vi">@addr</span><span class="p">))</span>                                    
<span class="k">end</span>                                                                           

<span class="c1"># lib/ipaddr.rb:370 (ruby 1.9.3-p286)</span>

<span class="kp">protected</span>

<span class="c1"># Set +@addr+, the internal stored ip address, to given +addr+. The</span>
<span class="c1"># parameter +addr+ is validated using the first +family+ member,</span>
<span class="c1"># which is +Socket::AF_INET+ or +Socket::AF_INET6+.</span>
<span class="k">def</span> <span class="nf">set</span><span class="p">(</span><span class="n">addr</span><span class="p">,</span> <span class="o">*</span><span class="n">family</span><span class="p">)</span>
  <span class="k">case</span> <span class="n">family</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span> <span class="p">?</span> <span class="n">family</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span> <span class="p">:</span> <span class="vi">@family</span>
  <span class="k">when</span> <span class="no">Socket</span><span class="o">::</span><span class="no">AF_INET</span>
    <span class="k">if</span> <span class="n">addr</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">addr</span> <span class="o">&gt;</span> <span class="no">IN4MASK</span>
      <span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">,</span> <span class="s2">&quot;invalid address&quot;</span>
    <span class="k">end</span>
  <span class="k">when</span> <span class="no">Socket</span><span class="o">::</span><span class="no">AF_INET6</span>
    <span class="k">if</span> <span class="n">addr</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">addr</span> <span class="o">&gt;</span> <span class="no">IN6MASK</span>
      <span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">,</span> <span class="s2">&quot;invalid address&quot;</span>
    <span class="k">end</span>
  <span class="k">else</span>
    <span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">,</span> <span class="s2">&quot;unsupported address family&quot;</span>
  <span class="k">end</span>
  <span class="vi">@addr</span> <span class="o">=</span> <span class="n">addr</span>
  <span class="k">if</span> <span class="n">family</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
    <span class="vi">@family</span> <span class="o">=</span> <span class="n">family</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
  <span class="k">end</span>
  <span class="k">return</span> <span class="nb">self</span>
<span class="k">end</span>
</pre></div>

<p>Instead of changing its state during these operations, it creates a copy of
itself using <code>clone</code> and calls protected methods like <code>set</code> to mutate the
instance and return it to the caller.</p>

<h3>Fulfilling an Abstract Class&#39;s Contract</h3>

<p>Another example of the <code>protected</code> keyword is in ActiveSupport&#39;s caching
layer. <code>ActiveSupport::Cache::Store</code> defines an abstract class that can be
inherited to implement a pluggable caching layer. A minimal viable
implementation of a cache store involves implementing three methods:
<code>read_entry</code>, <code>write_entry</code> and <code>delete_entry</code>. These are called by the public
API of the abstract class and implement a specific storage strategy. This
separates the concerns of how the cache behaviors from the specifics of how
its data is stored.</p>
<div class="highlight"><pre><span class="c1"># activesupport/lib/active_support/cache.rb:441</span>

<span class="kp">protected</span>

<span class="c1"># activesupport/lib/active_support/cache.rb:461</span>

<span class="c1"># Read an entry from the cache implementation. Subclasses must implement</span>
<span class="c1"># this method.</span>
<span class="k">def</span> <span class="nf">read_entry</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span> <span class="c1"># :nodoc:</span>
  <span class="k">raise</span> <span class="no">NotImplementedError</span><span class="o">.</span><span class="n">new</span>
<span class="k">end</span>

<span class="c1"># Write an entry to the cache implementation. Subclasses must implement</span>
<span class="c1"># this method.</span>
<span class="k">def</span> <span class="nf">write_entry</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">entry</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span> <span class="c1"># :nodoc:</span>
  <span class="k">raise</span> <span class="no">NotImplementedError</span><span class="o">.</span><span class="n">new</span>
<span class="k">end</span>

<span class="c1"># Delete an entry from the cache implementation. Subclasses must</span>
<span class="c1"># implement this method.</span>
<span class="k">def</span> <span class="nf">delete_entry</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span> <span class="c1"># :nodoc:</span>
  <span class="k">raise</span> <span class="no">NotImplementedError</span><span class="o">.</span><span class="n">new</span>
<span class="k">end</span>
</pre></div>

<p>ActiveSupport ships with implementations to store cache data in memory, a file
and memcached. Each implementation has its own methods for interacting with
its respective store.</p>
<div class="highlight"><pre><span class="c1"># activesupport/lib/active_support/cache/mem_cache_store.rb:121</span>

<span class="kp">protected</span>
  <span class="c1"># Read an entry from the cache.</span>
  <span class="k">def</span> <span class="nf">read_entry</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span> <span class="c1"># :nodoc:</span>
    <span class="n">deserialize_entry</span><span class="p">(</span><span class="vi">@data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">escape_key</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="n">options</span><span class="p">))</span>
  <span class="k">rescue</span> <span class="no">Dalli</span><span class="o">::</span><span class="no">DalliError</span> <span class="o">=&gt;</span> <span class="n">e</span>
    <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;DalliError (</span><span class="si">#{</span><span class="n">e</span><span class="si">}</span><span class="s2">): </span><span class="si">#{</span><span class="n">e</span><span class="o">.</span><span class="n">message</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="n">logger</span>
    <span class="kp">nil</span>
  <span class="k">end</span>

<span class="c1"># activesupport/lib/active_support/cache/mem_cache_store.rb:153</span>

<span class="kp">private</span>

  <span class="c1"># Memcache keys are binaries. So we need to force their encoding to binary</span>
  <span class="c1"># before applying the regular expression to ensure we are escaping all</span>
  <span class="c1"># characters properly.</span>
  <span class="k">def</span> <span class="nf">escape_key</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
    <span class="n">key</span> <span class="o">=</span> <span class="n">key</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">dup</span>
    <span class="n">key</span> <span class="o">=</span> <span class="n">key</span><span class="o">.</span><span class="n">force_encoding</span><span class="p">(</span><span class="s2">&quot;BINARY&quot;</span><span class="p">)</span>
    <span class="n">key</span> <span class="o">=</span> <span class="n">key</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="no">ESCAPE_KEY_CHARS</span><span class="p">){</span> <span class="o">|</span><span class="n">match</span><span class="o">|</span> <span class="s2">&quot;%</span><span class="si">#{</span><span class="n">match</span><span class="o">.</span><span class="n">getbyte</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span><span class="o">.</span><span class="n">upcase</span><span class="si">}</span><span class="s2">&quot;</span> <span class="p">}</span>
    <span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">key</span><span class="o">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">213</span><span class="o">]</span><span class="si">}</span><span class="s2">:md5:</span><span class="si">#{</span><span class="no">Digest</span><span class="o">::</span><span class="no">MD5</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">(</span><span class="n">key</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="n">key</span><span class="o">.</span><span class="n">size</span> <span class="o">&gt;</span> <span class="mi">250</span>
    <span class="n">key</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">deserialize_entry</span><span class="p">(</span><span class="n">raw_value</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">raw_value</span>
      <span class="n">entry</span> <span class="o">=</span> <span class="no">Marshal</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">raw_value</span><span class="p">)</span> <span class="k">rescue</span> <span class="n">raw_value</span>
      <span class="n">entry</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">Entry</span><span class="p">)</span> <span class="p">?</span> <span class="n">entry</span> <span class="p">:</span> <span class="no">Entry</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">entry</span><span class="p">)</span>
    <span class="k">else</span>
      <span class="kp">nil</span>
    <span class="k">end</span>
  <span class="k">end</span>
</pre></div>

<p>By marking the abstract interface methods with <code>protected</code> and the
implementation methods for the storage mechanism as <code>private</code> there&#39;s a
demarcation between the concerns. There&#39;s no direct reason in the
implementation for using protected methods in this case. The calls to these
protected methods use an implicit <code>self</code> which means private method calls
would work to encapsulate the object&#39;s behavior. Using the <code>protected</code> keyword
is primarily a matter of convention to call into relief which concerns belong
to what components to aid in maintenance.</p>

<h3>Framework Hooks</h3>

<p>Another conventional use of protected methods is for methods within an object
that aren&#39;t called directly by the object but are callback hooks that a
framework is configured to call. For example, <code>ActionController::Base</code> allows
an inheriting class to define filters that are called at specific moments in a
request&#39;s lifecycle. We&#39;ll contrive an example using a Blog application.</p>
<div class="highlight"><pre><span class="no">BlogApp</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span>
  <span class="n">resources</span> <span class="ss">:blogs</span> <span class="k">do</span>
    <span class="n">resources</span> <span class="ss">:posts</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>Let&#39;s add a <code>PostsController</code>. We want to use
<a href="http://github.com/rails/strong_parameters">strong_parameters</a> to prevent any
unauthorized mass-assignment and add an authorization check to ensure the
current user&#39;s access to create posts on the current blog.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">PostsController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
  <span class="n">before_filter</span> <span class="ss">:authorize_user</span>

  <span class="k">def</span> <span class="nf">create</span>
    <span class="vi">@post</span> <span class="o">=</span> <span class="n">blog</span><span class="o">.</span><span class="n">posts</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="n">post_parameters</span><span class="p">)</span>

    <span class="k">if</span> <span class="vi">@post</span><span class="o">.</span><span class="n">save</span>
      <span class="n">redirect_to</span> <span class="n">action</span><span class="p">:</span> <span class="ss">:index</span><span class="p">,</span> <span class="n">notice</span><span class="p">:</span> <span class="s2">&quot;Post created.&quot;</span>
    <span class="k">else</span>
      <span class="n">render</span> <span class="ss">:new</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="kp">protected</span>

  <span class="k">def</span> <span class="nf">authorize_user</span>
    <span class="k">unless</span> <span class="n">blog</span><span class="o">.</span><span class="n">authorized?</span><span class="p">(</span><span class="n">current_user</span><span class="p">)</span>
      <span class="n">render</span> <span class="n">nothing</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span> <span class="n">status</span><span class="p">:</span> <span class="ss">:unauthorized</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">blog</span>
    <span class="vi">@blog</span> <span class="o">||=</span> <span class="no">Blog</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:blog_id</span><span class="o">]</span><span class="p">)</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">post_parameters</span>
    <span class="n">params</span><span class="o">.</span><span class="n">require</span><span class="p">(</span><span class="ss">:post</span><span class="p">)</span><span class="o">.</span><span class="n">permit</span><span class="p">(</span><span class="ss">:title</span><span class="p">,</span> <span class="ss">:date</span><span class="p">,</span> <span class="ss">:content</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre></div>

<p>The <code>protected</code> keyword denotes methods that are called by ActionController
and the <code>private</code> keyword is used for methods that we call in the controller
itself to complete our work. Simliar to the previous example above, there&#39;s no
implementation reason that we&#39;re using protected methods here aside from
calling attention to the fact that the methods marked as protected and private
are interfaces aimed at different consumers: the external framework and the
internal object respectively. It&#39;s a hint to future readers of the code that
while these methods aren&#39;t part of the object&#39;s public API, there are users of
the interface beyond the object itself.</p>

<h3>So, when should I use it?</h3>

<p><code>protected</code> is an odd beast; it accomplishes much of what private does but with
the addition of some nuanced complexity and the (dubious) benefit of being
able to call methods on self explicitly. There are some conventions around
what protected means but they seem to vary from project to project. I could
find no project with any guidelines around method visibility. It was not
apparent in most of the code I read that had used protected why the original
author had chosen to use it.</p>

<p>I talked to several developers while writing this who had committed code to
open source projects and had used <code>protected</code>. I received the same response
from each: 1) I don&#39;t remember why I used <code>protected</code> there 2) I wouldn&#39;t use
<code>protected</code> if I was writing that code again, <code>private</code> or <code>public</code> would have
been better 3) I don&#39;t use <code>protected</code> at all today.</p>

<p>In searching ruby-core for conversations about protected methods, it&#39;s clear
this feature even confuses core contributors. The <code>OpenStruct</code> example above
was <a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/1558">discussed on the list</a>
as a replacement of an <code>instance_eval</code>. The contributor who suggested it was
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/1559">tentative about using it</a>:
&ldquo;From my ruby life for now, here&#39;s the only place where protected method lives.&rdquo;</p>

<p>Protected method visibility could make sense to use in workaday code for the
above cases. It was designed for the object interaction patterns shown in the
first two examples &ndash; attributes for comparison operations and mutator methods
for immutable objects. The latter two examples &ndash; fulfilling an abstract class&#39;
contract and framework hooks &ndash; are not universally applied patterns and aren&#39;t
enforced by the language. If you&#39;re going to use <code>protected</code> in this way it&#39;s
worth a quick discussion with your team to determine if the pattern would be
useful or at the very least leaving a paper trail in either the commit message
or the RDoc documentation for the methods briefly explaining why they are
marked <code>protected</code>.</p>
]]></content>
  </entry>
  <entry>
    <id>http://tx.pignata.com/2012/08/kafka-the-great-logfile-in-sky.md</id>
    <published>2012-08-10T00:00:00+00:00</published>
    <updated>2012-08-10T00:00:00+00:00</updated>
    <link href="http://tx.pignata.com/2012/08/kafka-the-great-logfile-in-sky.md" type="text/html" rel="alternate"/>
    <title>Talk: Kafka: The Great Logfile in the Sky
</title>
    <summary>Video and slides from a talk given at the Lone Star Ruby Conference about
Apache Kafka.
</summary>
    <author>
      <name>John Pignata</name>
    </author>
    <content type="html"><![CDATA[<h2>Slides</h2>

<script async class="speakerdeck-embed" data-id="501f4487e796b200020225ad" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

<h2>Video</h2>

<p><iframe width="560" height="340" src="http://cdn.livestream.com/embed/pivotallabs?layout=4&amp;clip=pla_edbd81df-89ec-4933-8295-42bf91a9d301&amp;height=340&amp;width=560&amp;autoplay=false" style="border:0;outline:0" frameborder="0" scrolling="no"></iframe><div style="font-size: 11px;padding-top:10px;text-align:center;width:560px"><a href="http://www.livestream.com/pivotallabs?utm_source=lsplayer&amp;utm_medium=embed&amp;utm_campaign=footerlinks" title="Watch pivotallabs">pivotallabs</a> on livestream.com. <a href="http://www.livestream.com/?utm_source=lsplayer&amp;utm_medium=embed&amp;utm_campaign=footerlinks" title="Broadcast Live Free">Broadcast Live Free</a></div></p>
]]></content>
  </entry>
</feed>
