<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[sqldump]]></title>
  <link href="http://blog.abhinav.ca/atom.xml" rel="self"/>
  <link href="http://blog.abhinav.ca/"/>
  <updated>2015-02-20T06:39:34-05:00</updated>
  <id>http://blog.abhinav.ca/</id>
  <author>
    <name><![CDATA[Abhinav Ajgaonkar]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Scaling with Akka Streams: Fetch 1M Twitter Profiles in less than 5min]]></title>
    <link href="http://blog.abhinav.ca/blog/2015/02/19/scaling-with-akka-streams/"/>
    <updated>2015-02-19T21:15:09-05:00</updated>
    <id>http://blog.abhinav.ca/blog/2015/02/19/scaling-with-akka-streams</id>
    <content type="html"><![CDATA[<p>During these past few weeks, I&rsquo;ve had a chance to play around quite a bit with the soon-to-be-1.0 <a href="http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0-M3/scala.html">Akka Streams</a> module and I&rsquo;ve been looking for a concrete reason to write about why this is an important milestone for the stream processing ecosystem. It just so happens that this week, we were conducting an experiment related to Twitter follower analysis that required pulling a few million public user profiles of followers of large Twitter accounts and the ability to do so in a relatively short amount of time. I decided to use Akka Streams for this project to see how far I could push it in a real world scenario.</p>

<h2>App Skeleton</h2>

<p>I decided to start with a regular Scala command line app and hardcode the Twitter ID of the person whose followers&#8217; profiles we were attempting to retrieve (since this is going to be throwaway code just for the sake of the experiment). The only dependencies were <a href="http://mvnrepository.com/artifact/com.typesafe.akka/akka-actor_2.11/2.3.9">akka-actor</a>, <a href="http://mvnrepository.com/artifact/com.typesafe.akka/akka-stream-experimental_2.11/1.0-M3">akka-stream-experimental</a> and <a href="http://mvnrepository.com/artifact/org.twitter4j/twitter4j-core/4.0.2">twitter4j-core</a>.</p>

<h3>Twitter API Interaction</h3>

<p>We need some way to call the Twitter API primarily for two reasons:</p>

<p>1) Fetch all follower IDs of a given userID<br/>
2) Fetch a user profile given a userID.</p>

<p>Any call made to Twiter&rsquo;s API needs an authenticated <code>twitter4j.Twitter</code> object. Given a set of credentials, a <code>twitter4j.Twitter</code> object is constructed as follows:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">import</span> <span class="nn">twitter4j.</span><span class="o">{</span><span class="nc">Twitter</span><span class="o">,</span> <span class="nc">TwitterFactory</span><span class="o">}</span>
</span><span class='line'><span class="k">import</span> <span class="nn">twitter4j.auth.AccessToken</span>
</span><span class='line'><span class="k">import</span> <span class="nn">twitter4j.conf.ConfigurationBuilder</span>
</span><span class='line'>
</span><span class='line'><span class="k">object</span> <span class="nc">TwitterClient</span> <span class="o">{</span>
</span><span class='line'>    <span class="c1">// Fill these in with your own credentials</span>
</span><span class='line'>    <span class="k">val</span> <span class="n">appKey</span><span class="k">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
</span><span class='line'>    <span class="k">val</span> <span class="n">appSecret</span><span class="k">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
</span><span class='line'>    <span class="k">val</span> <span class="n">accessToken</span><span class="k">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
</span><span class='line'>    <span class="k">val</span> <span class="n">accessTokenSecret</span><span class="k">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="n">apply</span><span class="o">()</span><span class="k">:</span> <span class="kt">Twitter</span> <span class="o">=</span> <span class="o">{</span>
</span><span class='line'>        <span class="k">val</span> <span class="n">factory</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">TwitterFactory</span><span class="o">(</span><span class="k">new</span> <span class="nc">ConfigurationBuilder</span><span class="o">().</span><span class="n">build</span><span class="o">())</span>
</span><span class='line'>        <span class="k">val</span> <span class="n">t</span> <span class="k">=</span> <span class="n">factory</span><span class="o">.</span><span class="n">getInstance</span><span class="o">()</span>
</span><span class='line'>        <span class="n">t</span><span class="o">.</span><span class="n">setOAuthConsumer</span><span class="o">(</span><span class="n">appKey</span><span class="o">,</span> <span class="n">appSecret</span><span class="o">)</span>
</span><span class='line'>        <span class="n">t</span><span class="o">.</span><span class="n">setOAuthAccessToken</span><span class="o">(</span><span class="k">new</span> <span class="nc">AccessToken</span><span class="o">(</span><span class="n">accessToken</span><span class="o">,</span> <span class="n">accessTokenSecret</span><span class="o">))</span>
</span><span class='line'>        <span class="n">t</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h4>Given a user, return all followers</h4>

<p>Using the <code>TwitterClient</code>, we can fetch a user&rsquo;s profile and list of followers with the following <code>TwitterHelpers</code> object:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">object</span> <span class="nc">TwitterHelpers</span> <span class="o">{</span>
</span><span class='line'>    <span class="c1">// Lookup user profiles in batches of 100</span>
</span><span class='line'>    <span class="k">def</span> <span class="n">lookupUsers</span><span class="o">(</span><span class="n">ids</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Long</span><span class="o">])</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">User</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">client</span> <span class="k">=</span> <span class="nc">TwitterClient</span><span class="o">()</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">res</span> <span class="k">=</span> <span class="n">client</span><span class="o">.</span><span class="n">lookupUsers</span><span class="o">(</span><span class="n">ids</span><span class="o">.</span><span class="n">toArray</span><span class="o">)</span>
</span><span class='line'>      <span class="n">res</span><span class="o">.</span><span class="n">toList</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Fetch the IDs of a user&#39;s followers in batches of 5000</span>
</span><span class='line'>    <span class="k">def</span> <span class="n">getFollowers</span><span class="o">(</span><span class="n">userId</span><span class="k">:</span> <span class="kt">Long</span><span class="o">)</span><span class="k">:</span> <span class="kt">Try</span><span class="o">[</span><span class="kt">Set</span><span class="o">[</span><span class="kt">Long</span><span class="o">]]</span> <span class="k">=</span> <span class="o">{</span>
</span><span class='line'>      <span class="nc">Try</span><span class="o">({</span>
</span><span class='line'>        <span class="k">val</span> <span class="n">followerIds</span> <span class="k">=</span> <span class="n">mutable</span><span class="o">.</span><span class="nc">Set</span><span class="o">[</span><span class="kt">Long</span><span class="o">]()</span>
</span><span class='line'>        <span class="k">var</span> <span class="n">cursor</span> <span class="k">=</span> <span class="o">-</span><span class="mi">1L</span>
</span><span class='line'>        <span class="k">do</span> <span class="o">{</span>
</span><span class='line'>          <span class="k">val</span> <span class="n">client</span> <span class="k">=</span> <span class="nc">TwitterClient</span><span class="o">()</span>
</span><span class='line'>          <span class="k">val</span> <span class="n">res</span> <span class="k">=</span> <span class="n">client</span><span class="o">.</span><span class="n">friendsFollowers</span><span class="o">().</span><span class="n">getFollowersIDs</span><span class="o">(</span><span class="n">userId</span><span class="o">,</span> <span class="n">cursor</span><span class="o">,</span> <span class="mi">5000</span><span class="o">)</span>
</span><span class='line'>          <span class="n">res</span><span class="o">.</span><span class="n">getIDs</span><span class="o">.</span><span class="n">toList</span><span class="o">.</span><span class="n">foreach</span><span class="o">(</span><span class="n">x</span> <span class="k">=&gt;</span> <span class="n">followerIds</span><span class="o">.</span><span class="n">add</span><span class="o">(</span><span class="n">x</span><span class="o">))</span>
</span><span class='line'>          <span class="k">if</span> <span class="o">(</span><span class="n">res</span><span class="o">.</span><span class="n">hasNext</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>            <span class="n">cursor</span> <span class="k">=</span> <span class="n">res</span><span class="o">.</span><span class="n">getNextCursor</span>
</span><span class='line'>          <span class="o">}</span>
</span><span class='line'>          <span class="k">else</span> <span class="o">{</span>
</span><span class='line'>            <span class="n">cursor</span> <span class="k">=</span> <span class="o">-</span><span class="mi">1</span> <span class="c1">// Exit the loop</span>
</span><span class='line'>          <span class="o">}</span>
</span><span class='line'>        <span class="o">}</span> <span class="k">while</span> <span class="o">(</span><span class="n">cursor</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="o">)</span>
</span><span class='line'>        <span class="n">followerIds</span><span class="o">.</span><span class="n">toSet</span>
</span><span class='line'>      <span class="o">})</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Akka Boilerplate</h3>

<p>With the Twitter interactions out of the way, we can create a new command line app using:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">object</span> <span class="nc">Main</span> <span class="k">extends</span> <span class="nc">App</span> <span class="o">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// ActorSystem &amp; thread pools</span>
</span><span class='line'>  <span class="k">implicit</span> <span class="k">val</span> <span class="n">system</span><span class="k">:</span> <span class="kt">ActorSystem</span> <span class="o">=</span> <span class="nc">ActorSystem</span><span class="o">(</span><span class="s">&quot;centaur&quot;</span><span class="o">)</span>
</span><span class='line'>  <span class="k">val</span> <span class="n">executorService</span><span class="k">:</span> <span class="kt">ExecutorService</span> <span class="o">=</span> <span class="nc">Executors</span><span class="o">.</span><span class="n">newCachedThreadPool</span><span class="o">()</span>
</span><span class='line'>  <span class="k">val</span> <span class="n">ec</span><span class="k">:</span> <span class="kt">ExecutionContext</span> <span class="o">=</span> <span class="nc">ExecutionContext</span><span class="o">.</span><span class="n">fromExecutorService</span><span class="o">(</span><span class="n">executorService</span><span class="o">)</span>
</span><span class='line'>  <span class="k">val</span> <span class="n">log</span><span class="k">:</span> <span class="kt">LoggingAdapter</span> <span class="o">=</span> <span class="nc">Logging</span><span class="o">.</span><span class="n">getLogger</span><span class="o">(</span><span class="n">system</span><span class="o">,</span> <span class="nc">Main</span><span class="o">)</span>
</span><span class='line'>  <span class="k">implicit</span> <span class="k">val</span> <span class="n">materializer</span> <span class="k">=</span> <span class="nc">ActorFlowMaterializer</span><span class="o">()(</span><span class="n">system</span><span class="o">)</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// Put Stream code here</span>
</span><span class='line'>  <span class="c1">//</span>
</span><span class='line'>  <span class="c1">//</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>At this point, we have a working app that can be invoked using <code>sbt run</code>. Let&rsquo;s get started on the Akka Streams bit.</p>

<h3>The Pipeline</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">val</span> <span class="n">startTime</span> <span class="k">=</span> <span class="nc">System</span><span class="o">.</span><span class="n">nanoTime</span><span class="o">()</span>
</span><span class='line'><span class="k">val</span> <span class="n">userId</span> <span class="k">=</span> <span class="mi">410939902L</span> <span class="c1">// @headinthebox ~12K followers</span>
</span><span class='line'><span class="k">val</span> <span class="n">output</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">ConcurrentLinkedQueue</span><span class="o">[</span><span class="kt">String</span><span class="o">]()</span>
</span><span class='line'><span class="nc">Console</span><span class="o">.</span><span class="n">println</span><span class="o">(</span><span class="n">s</span><span class="s">&quot;Fetching follower profiles for $userId&quot;</span><span class="o">)</span>
</span><span class='line'><span class="nc">Source</span><span class="o">(()</span> <span class="k">=&gt;</span> <span class="nc">TwitterHelpers</span><span class="o">.</span><span class="n">getFollowers</span><span class="o">(</span><span class="n">userId</span><span class="o">).</span><span class="n">get</span><span class="o">.</span><span class="n">toIterable</span><span class="o">.</span><span class="n">iterator</span><span class="o">)</span>
</span><span class='line'>  <span class="o">.</span><span class="n">grouped</span><span class="o">(</span><span class="mi">100</span><span class="o">)</span>
</span><span class='line'>  <span class="o">.</span><span class="n">map</span><span class="o">(</span><span class="n">x</span> <span class="k">=&gt;</span> <span class="nc">TwitterHelpers</span><span class="o">.</span><span class="n">lookupUsers</span><span class="o">(</span><span class="n">x</span><span class="o">.</span><span class="n">toList</span><span class="o">))</span>
</span><span class='line'>  <span class="o">.</span><span class="n">mapConcat</span><span class="o">(</span><span class="n">identity</span><span class="o">)</span>
</span><span class='line'>  <span class="o">.</span><span class="n">runForeach</span><span class="o">(</span><span class="n">x</span> <span class="k">=&gt;</span> <span class="n">output</span><span class="o">.</span><span class="n">offer</span><span class="o">(</span><span class="n">x</span><span class="o">.</span><span class="n">getScreenName</span><span class="o">))</span>
</span><span class='line'>  <span class="o">.</span><span class="n">onComplete</span><span class="o">({</span>
</span><span class='line'>    <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span>
</span><span class='line'>      <span class="nc">Console</span><span class="o">.</span><span class="n">println</span><span class="o">(</span><span class="n">s</span><span class="s">&quot;Fetched ${output.size()} profiles&quot;</span><span class="o">)</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">endTime</span> <span class="k">=</span> <span class="nc">System</span><span class="o">.</span><span class="n">nanoTime</span><span class="o">()</span>
</span><span class='line'>      <span class="nc">Console</span><span class="o">.</span><span class="n">println</span><span class="o">(</span><span class="n">s</span><span class="s">&quot;Time taken: ${(endTime - startTime)/1000000000.00}s&quot;</span><span class="o">)</span>
</span><span class='line'>      <span class="n">system</span><span class="o">.</span><span class="n">shutdown</span><span class="o">()</span>
</span><span class='line'>      <span class="nc">Runtime</span><span class="o">.</span><span class="n">getRuntime</span><span class="o">.</span><span class="n">exit</span><span class="o">(</span><span class="mi">0</span><span class="o">)</span>
</span><span class='line'>  <span class="o">})</span> <span class="o">(</span><span class="n">ec</span><span class="o">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Breaking down the flow line by line</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="nc">Source</span><span class="o">(()</span> <span class="k">=&gt;</span> <span class="nc">TwitterHelpers</span><span class="o">.</span><span class="n">getFollowers</span><span class="o">(</span><span class="n">userId</span><span class="o">).</span><span class="n">get</span><span class="o">.</span><span class="n">toIterable</span><span class="o">.</span><span class="n">iterator</span><span class="o">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>turns the <code>Set[Long]</code> of follower IDs into an Akka Streams <code>Source</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="o">.</span><span class="n">grouped</span><span class="o">(</span><span class="mi">100</span><span class="o">)</span> <span class="c1">// outputs a stream of Seq[Long]</span>
</span><span class='line'><span class="o">.</span><span class="n">map</span><span class="o">(</span><span class="n">x</span> <span class="k">=&gt;</span> <span class="nc">TwitterHelpers</span><span class="o">.</span><span class="n">lookupUsers</span><span class="o">(</span><span class="n">x</span><span class="o">.</span><span class="n">toList</span><span class="o">))</span> <span class="c1">// outputs a stream of List[User]</span>
</span><span class='line'><span class="o">.</span><span class="n">mapConcat</span><span class="o">(</span><span class="n">identity</span><span class="o">)</span> <span class="c1">// flattens the stream of List[User] into a stream of User</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>group</code>, <code>map</code> and <code>mapConcat</code> transform the stream of Longs into a stream of <code>twitter4j.User</code> objects.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="o">.</span><span class="n">runForeach</span><span class="o">(</span><span class="n">x</span> <span class="k">=&gt;</span> <span class="n">output</span><span class="o">.</span><span class="n">offer</span><span class="o">(</span><span class="n">x</span><span class="o">.</span><span class="n">getScreenName</span><span class="o">))</span>
</span></code></pre></td></tr></table></div></figure>


<p>And finally, the user objects are piped into a <code>Sink</code> which adds them to our output queue.</p>

<h3>Run 1 &ndash; 12,199 profiles in 108s</h3>

<p>Running this flow takes 108 seconds to retrieve 12,199 user profiles from Twitter.</p>

<p><a href="http://blog.abhinav.ca/images/2015-02-19-Attempt-1.png"><img src="http://blog.abhinav.ca/images/2015-02-19-Attempt-1.png"></a></p>

<h3>Run 2 &ndash; 12,200 profiles in 11s</h3>

<p>Modifying the flow slightly to allow for more concurrency helps bring down the total time taken by a large value. The obvious bottleneck in the flow implementation is the synchronous fetching of user profiles in the stage where User IDs are mapped to User profile objects. Replacing the</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="o">.</span><span class="n">map</span><span class="o">(</span><span class="n">x</span> <span class="k">=&gt;</span> <span class="nc">TwitterHelpers</span><span class="o">.</span><span class="n">lookupUsers</span><span class="o">(</span><span class="n">x</span><span class="o">.</span><span class="n">toList</span><span class="o">))</span>
</span></code></pre></td></tr></table></div></figure>


<p>with</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="o">.</span><span class="n">mapAsyncUnordered</span><span class="o">[</span><span class="kt">List</span><span class="o">[</span><span class="kt">User</span><span class="o">]](</span><span class="n">x</span> <span class="k">=&gt;</span> <span class="nc">Future</span><span class="o">[</span><span class="kt">List</span><span class="o">[</span><span class="kt">User</span><span class="o">]]({</span> <span class="nc">TwitterHelpers</span><span class="o">.</span><span class="n">lookupUsers</span><span class="o">(</span><span class="n">x</span><span class="o">.</span><span class="n">toList</span><span class="o">)</span> <span class="o">}</span> <span class="o">(</span><span class="n">ec</span><span class="o">)))</span>
</span></code></pre></td></tr></table></div></figure>


<p>reduces the time taken from <strong>108</strong>s to <strong>11</strong>s. <strong>That&rsquo;s almost 10x faster with a single line change!</strong></p>

<p><a href="http://blog.abhinav.ca/images/2015-02-19-Attempt-2.png"><img src="http://blog.abhinav.ca/images/2015-02-19-Attempt-2.png"></a></p>

<p>(It looks like Erik Meijer has gained a follower between our two runs).</p>

<h3>Run 3 &ndash; 1.22M profiles in 256s</h3>

<p><a href="https://twitter.com/netflix">Netflix USA</a> has approximately 1.22M followers. Fetching followers for this account took 256s.</p>

<p><a href="http://blog.abhinav.ca/images/2015-02-19-Attempt-3.png"><img src="http://blog.abhinav.ca/images/2015-02-19-Attempt-3.png"></a></p>

<h3>Run 4 &ndash; 2.88M profiles in 647s</h3>

<p>Twitter co-founder <a href="https://twitter.com/jack">Jack Dorsey</a> has 2.88M followers and the pipeline processed them in 647 seconds.</p>

<p><a href="http://blog.abhinav.ca/images/2015-02-19-Attempt-4.png"><img src="http://blog.abhinav.ca/images/2015-02-19-Attempt-4.png"></a></p>

<p>Since Netflix (1.22M) was processed in 256s and Jack (2.88M) was processed in ~650s, it doesn&rsquo;t look like the pipeline is showing any signs of exhaustion as larger accounts are being processed.</p>

<h3>Final Thoughts</h3>

<p>Before Akka Streams, creating a flow like this would require hand coding each stage as an actor, manually wiring everything up and carefully managing backpressure using a hybrid push/pull system alongwith finely configured timeouts and inbox sizes. Having worked on many such systems at <a href="http://crowdriff.com">CrowdRiff</a>, my experience so far has been mostly positive. Akka delivers exactly what it promises &ndash; an easy way to think about concurrency, excellent performance and a great toolkit to build distributed systems. However, once built, these systems often tend to be very complex and common changes like adding stages to the pipeline or modifying existing stages have to be done very carefully (despite unit tests!). Akka Streams takes this to a whole new level by allowing the user to create arbitrary flows (check out <a href="http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0-M3/scala/stream-graphs.html">stream graphs</a>) in simple and easy to read manner AND managing the backpressure for you! The large quantity of awesome in this module is certainly appreciated by me and my team &ndash; many thanks to the Akka folks and everyone who contributed to the Reactive Streams project. Happy hAkking!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[5-Node Cassandra Cluster. 1 Command.]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/09/15/cassandra-cluster-docker-one-command/"/>
    <updated>2014-09-15T00:16:56-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/09/15/cassandra-cluster-docker-one-command</id>
    <content type="html"><![CDATA[<p>[2014-09-16] Update: The command now brings up a 5-node Cassandra cluster in addition to DataStax OpsCenter 5.0.0 and wires it all up together. See <a href="http://github.com/abh1nav/cassandra">the GitHub repo</a> for details. Each node runs in its own container with the Cassandra process + DataStax Agent while OpsCenter runs in its own container separate from the cluster.</p>

<p>[Original Post]</p>

<p>Run this command to bring up a 5-node Cassandra (2.1.0) cluster locally using Docker.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>bash &lt;(curl -sL http://bit.ly/docker-cassandra)</span></code></pre></td></tr></table></div></figure>


<p>This will:<br/>
1. Pull the <code>abh1nav/cassandra:latest</code> image.<br/>
2. Start the first node with the name <code>cass1</code><br/>
3. Start <code>cass2..5</code> with the environment variable <code>SEED=&lt;ip of cass1&gt;</code></p>

<h2>Manual mode</h2>

<p>If you don&rsquo;t like or trust the one liner, here&rsquo;s how to do it manually.</p>

<h3>Single Node Setup</h3>

<p>To start the first node, pull the latest version of image:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>docker pull abh1nav/cassandra:latest
</span></code></pre></td></tr></table></div></figure>


<p>Start the first instance:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>docker run -d --name cass1 abh1nav/cassandra:latest
</span></code></pre></td></tr></table></div></figure>


<p>Grab its IP using:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">SEED_IP</span><span class="o">=</span><span class="k">$(</span>docker inspect -f <span class="s1">&#39;{{ .NetworkSettings.IPAddress }}&#39;</span> cass1<span class="k">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Connect to it using cqlsh:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>cqlsh <span class="nv">$SEED_IP</span>
</span></code></pre></td></tr></table></div></figure>


<p>The expected output is:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>✈ megatron /opt/cassandra
</span><span class='line'> ↳ bin/cqlsh <span class="nv">$SEED_IP</span>
</span><span class='line'>Connected to Test Cluster at 172.17.0.47:9160.
</span><span class='line'><span class="o">[</span>cqlsh 4.1.1 | Cassandra 2.1.0 | CQL spec 3.1.1 | Thrift protocol 19.39.0<span class="o">]</span>
</span><span class='line'>Use HELP <span class="k">for </span>help.
</span><span class='line'>cqlsh&gt;
</span></code></pre></td></tr></table></div></figure>


<h3>Cluster Setup</h3>

<p>Once your single node is setup, you can add more nodes using:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">for </span>name in cass<span class="o">{</span>2..5<span class="o">}</span>; <span class="k">do</span>
</span><span class='line'><span class="k">  </span><span class="nb">echo</span> <span class="s2">&quot;Starting node $name&quot;</span>
</span><span class='line'>  docker run -d --name <span class="nv">$name</span> -e <span class="nv">SEED</span><span class="o">=</span><span class="nv">$SEED_IP</span> abh1nav/cassandra:latest
</span><span class='line'>  sleep 10
</span><span class='line'><span class="k">done</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can watch the cluster form by tailing the logs on <code>cass1</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>docker logs -f cass1
</span></code></pre></td></tr></table></div></figure>


<p>Once the cluster is up, you can check its status using:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>nodetool --host <span class="nv">$SEED_IP</span> status
</span></code></pre></td></tr></table></div></figure>


<p>The expected output is:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>✈ megatron /opt/cassandra
</span><span class='line'> ↳ bin/nodetool --host <span class="nv">$SEED_IP</span> status
</span><span class='line'>Datacenter: <span class="nv">datacenter1</span>
</span><span class='line'><span class="o">=======================</span>
</span><span class='line'><span class="nv">Status</span><span class="o">=</span>Up/Down
</span><span class='line'>|/ <span class="nv">State</span><span class="o">=</span>Normal/Leaving/Joining/Moving
</span><span class='line'>--  Address      Load       Tokens  Owns <span class="o">(</span>effective<span class="o">)</span>  Host ID                               Rack
</span><span class='line'>UN  172.17.0.47  54.99 KB   256     37.3%             cb925207-ff79-4d1e-84ce-ac6c59353df4  rack1
</span><span class='line'>UN  172.17.0.48  85.8 KB    256     39.4%             baa1b2c1-8f51-4e20-9c33-44cb5f45a4c0  rack1
</span><span class='line'>UN  172.17.0.49  69.35 KB   256     40.1%             d1f96d59-c084-4ba3-a717-4269098cc854  rack1
</span><span class='line'>UN  172.17.0.50  68.92 KB   256     40.2%             d514e844-e07a-4896-ace8-a0b43e25d6fc  rack1
</span><span class='line'>UN  172.17.0.51  69.39 KB   256     43.0%             464cdf00-39e3-4efe-8a9f-83fc5ba839c9  rack1
</span></code></pre></td></tr></table></div></figure>


<p>Check out the <a href="https://registry.hub.docker.com/u/abh1nav/cassandra/">Docker registry page</a> for the image and the <a href="https://github.com/abh1nav/cassandra">GitHub repo</a> to grab the source.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Unit Testing Futures with ScalaTest]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/09/08/unit-testing-futures-with-scalatest/"/>
    <updated>2014-09-08T17:08:08-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/09/08/unit-testing-futures-with-scalatest</id>
    <content type="html"><![CDATA[<p>Unit testing methods that return futures in Scala is quite straightforward using ScalaTest 2.0+</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">import</span> <span class="nn">org.scalatest.FunSuite</span>
</span><span class='line'><span class="k">import</span> <span class="nn">org.scalatest.concurrent.ScalaFutures</span>
</span><span class='line'><span class="k">import</span> <span class="nn">scala.concurrent.Future</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">NiceClass$Test</span> <span class="k">extends</span> <span class="nc">FunSuite</span> <span class="k">with</span> <span class="nc">ScalaFutures</span> <span class="o">{</span>
</span><span class='line'>  <span class="n">test</span><span class="o">(</span><span class="s">&quot;Test a method that returns a future&quot;</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>    <span class="k">val</span> <span class="n">f</span><span class="k">:</span> <span class="kt">Future</span><span class="o">[</span><span class="kt">Boolean</span><span class="o">]</span> <span class="k">=</span> <span class="n">somethingThatReturnsAFuture</span><span class="o">()</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">whenReady</span><span class="o">(</span><span class="n">f</span><span class="o">)</span> <span class="o">{</span> <span class="n">result</span> <span class="k">=&gt;</span>
</span><span class='line'>      <span class="n">assert</span><span class="o">(</span><span class="n">result</span><span class="o">)</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>If your future is making a web service call or doing some sort of IO that takes a few seconds to complete, you might encounter an error like this one:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="n">A</span> <span class="n">timeout</span> <span class="n">occurred</span> <span class="n">waiting</span> <span class="k">for</span> <span class="n">a</span> <span class="n">future</span> <span class="n">to</span> <span class="n">complete</span><span class="o">.</span>
</span><span class='line'><span class="nc">Queried</span> <span class="mi">11</span> <span class="n">times</span><span class="o">,</span> <span class="n">sleeping</span> <span class="mi">15</span> <span class="n">milliseconds</span> <span class="n">between</span> <span class="n">each</span> <span class="n">query</span><span class="o">.</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can fix this by telling ScalaFutures how long it should to wait before declaring that the future has timed out.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">import</span> <span class="nn">org.scalatest.time.</span><span class="o">{</span><span class="nc">Millis</span><span class="o">,</span> <span class="nc">Seconds</span><span class="o">,</span> <span class="nc">Span</span><span class="o">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">implicit</span> <span class="k">val</span> <span class="n">defaultPatience</span> <span class="k">=</span>
</span><span class='line'>  <span class="nc">PatienceConfig</span><span class="o">(</span><span class="n">timeout</span> <span class="k">=</span> <span class="nc">Span</span><span class="o">(</span><span class="mi">5</span><span class="o">,</span> <span class="nc">Seconds</span><span class="o">),</span> <span class="n">interval</span> <span class="k">=</span> <span class="nc">Span</span><span class="o">(</span><span class="mi">500</span><span class="o">,</span> <span class="nc">Millis</span><span class="o">))</span>
</span></code></pre></td></tr></table></div></figure>


<p>Happy testing!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Hackathon: Bike Share Toronto]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/08/19/hackathon-bike-share-toronto/"/>
    <updated>2014-08-19T21:29:58-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/08/19/hackathon-bike-share-toronto</id>
    <content type="html"><![CDATA[<p>This past weekend, I had the pleasure of being a participant at the <a href="https://bikesharearup-hackathonde.squarespace.com">Bike Share Toronto Hackathon &amp; Design Jam</a>. This was my first time attending an Open Data related hackathon in Toronto and simply put, the experience was absolutely phenomenal. 36 hours of non-stop hacking on data related to usage of the Bike Share Toronto service combined with the data from the Cycling App made available by the City of Toronto with the singular aim of getting more people on bikes.</p>

<h2>The Concept</h2>

<p><a href="https://twitter.com/abh1nv/status/501093674634448896">Team Fixie</a> decided to appeal to the users&#8217; common sense by presenting a comparison of various modes of transportation before embarking on a trip.</p>

<p><a href="http://blog.abhinav.ca/images/2014-08-19-Fixie-UI-1.png"><img src="http://blog.abhinav.ca/images/2014-08-19-Fixie-UI-1.png"></a></p>

<p>In a nutshell, the responsive web app asks for details about your trip, such as the reason for the trip, start / end locations and optionally a time of arrival.</p>

<p><a href="http://blog.abhinav.ca/images/2014-08-19-Fixie-UI-2.png"><img src="http://blog.abhinav.ca/images/2014-08-19-Fixie-UI-2.png"></a></p>

<p>It then presents you with three options that include realistic time estimates (as opposed to average speed based estimates provided by Google Maps) by accounting for factors such as weather and average speeds typically achieved by cyclists during the time of day around the arrival time.</p>

<p><a href="http://blog.abhinav.ca/images/2014-08-19-Fixie-UI-3.png"><img src="http://blog.abhinav.ca/images/2014-08-19-Fixie-UI-3.png"></a></p>

<p>When assessing the Bike Share option, Fixie includes the time required to walk from your starting point to the nearest Bike Share station, the time required to bike from the first Bike Share station to the Bike Share station nearest to your destination and the time required to walk to your destination from the second Bike Share station.</p>

<p><a href="http://blog.abhinav.ca/images/2014-08-19-Fixie-UI-4.png"><img src="http://blog.abhinav.ca/images/2014-08-19-Fixie-UI-4.png"></a></p>

<p>Similarly, when calculating the time required for you to ride your own bike, Fixie includes the time required to bike from your starting point to the bike lock post nearest to your destination (so you can secure your bike) and the time required to walk to your destination from the bike post.</p>

<p><a href="http://blog.abhinav.ca/images/2014-08-19-Fixie-UI-5.png"><img src="http://blog.abhinav.ca/images/2014-08-19-Fixie-UI-5.png"></a></p>

<p>For public transit, driving and walking directions, it relies entirely on Google Maps.</p>

<h2>The Hack</h2>

<p>The front end is backed by <a href="http://nodejs.org/">NodeJS</a> / <a href="http://expressjs.com/">ExpressJS</a> REST API and the client side is built using <a href="http://www.w3.org/TR/html5/">HTML5</a>, <a href="http://sass-lang.com/">SASS</a> and <a href="https://angularjs.org/">AngularJS</a>. The auto-complete for address boxes is powered by the <a href="https://developers.google.com/maps/documentation/javascript/">Google Maps Javascript API v3</a> and location detection is enabled using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/Using_geolocation">HTML5 Geo-Location API</a>. The entire javascript layer is uses <a href="http://gulpjs.com/">GulpJS</a> to build and package itself.</p>

<p>The Javascript layer talks to a Python REST API written using <a href="http://www.cherrypy.org/">CherryPy</a> to calculate the time for each type of trip. The python backend talks to the <a href="https://developers.google.com/maps/documentation/directions/">Google Directions API</a> to generate waypoints for a trip and also encapsulates the <a href="http://scikit-learn.org/stable/">SciKit Learn</a> model that predicts travel times between waypoints for a given time of day.</p>

<h2>Datasets Used</h2>

<p>The machine learning system that predicts travel time was trained using data from City of Toronto Cycling App data and the Bike Share data. The difficulty here was that the Bike Share data did not provide the change in elevation for the trip and an analysis of the model&rsquo;s features indicated that altitude change was fairly important to ensure an accurate prediction. Using the <a href="https://developers.google.com/maps/documentation/elevation/">Google Elevation API</a>, we were able to approximate the change in altitude for each Bike Share trip and mix that data to enhance the provided dataset and help train the model.</p>

<p>The python service also used the <a href="http://www1.toronto.ca/wps/portal/contentonly?vgnextoid=d46e94ec9fbf3310VgnVCM1000003dd60f89RCRD">Bicycle Post and Ring Locations</a> dataset provided by the City of Toronto as well as the Bike Share Station dataset to help plan the waypoints for bike trips.</p>

<h2>Conclusion</h2>

<p>At the end some amazing ideas, prototypes and implementations were presented by the 9 participating groups to a packed audience. All in all, the hackathon was a smashing success. I wanted to put this post up to catalogue the concept and implementation that our team came up with, just so I&rsquo;d have something to refer back to, or in case someone else finds some use for it.</p>

<p>I&rsquo;d like to thank <a href="https://twitter.com/alexmansourati">Alex Mansourati</a>, <a href="https://twitter.com/kentenglish">Kent English</a> and <a href="https://twitter.com/maozillah">Kaye Mao</a> for making Team Fixie awesome. Last but not least, a big thank you to all the organizers and sponsors for making this event happen. Shout outs to <a href="https://twitter.com/biancawylie">Bianca Wylie</a>, <a href="https://twitter.com/Naomi_Freeman">Naomi Freeman</a>, <a href="https://twitter.com/abuchanterrell">Allison Buchan-Terrell</a>, <a href="https://twitter.com/MichaelMarkieta">Michael Markieta</a>, <a href="https://twitter.com/CabbagetownMatt">Matthew Browning</a> and Anelia.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Kickstart a Couchbase cluster with Docker]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/07/31/kickstart-a-couchbase-cluster-with-docker/"/>
    <updated>2014-07-31T11:01:15-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/07/31/kickstart-a-couchbase-cluster-with-docker</id>
    <content type="html"><![CDATA[<p>A few days ago, I was officially introduced to <a href="http://www.couchbase.com/">Couchbase</a> at a <a href="http://www.meetup.com/TorontoHUG/events/191410172/">Toronto Hadoop User Group meetup</a>. I say &ldquo;officially&rdquo; because I&rsquo;ve known about some Couchbase use-cases / pros and cons on a high level since v1.8, but never really had the time to look at it in detail.</p>

<p>As the presentation progressed, it got me interested in actually tinkering around with a Couchbase cluster (kudos to <a href="https://twitter.com/NoSQLDon">Don Pinto</a>). My first instinct was to head over to the <a href="https://registry.hub.docker.com">Docker Registry</a> and do a quick search for <code>couchbase</code>. Using the <code>dustin/couchbase</code> image, I was able to get a 5-node cluster running in under 5 minutes.</p>

<h3>Run 5 containers</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>docker run -d -p 11210:11210 -p 11211:11211 -p 8091:8091 -p 8092:8092 --name cb1 dustin/couchbase
</span><span class='line'>docker run -d --name cb2 dustin/couchbase
</span><span class='line'>docker run -d --name cb3 dustin/couchbase
</span><span class='line'>docker run -d --name cb4 dustin/couchbase
</span><span class='line'>docker run -d --name cb5 dustin/couchbase
</span></code></pre></td></tr></table></div></figure>


<h3>Find Container IPs</h3>

<p>Once the containers were up, I used <code>docker inspect</code> to find their internal IPs (usually in the <code>172.17.x.x</code> range). For example, <code>docker inspect cb1</code> returns</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">[{</span>
</span><span class='line'>    <span class="nt">&quot;Args&quot;</span><span class="p">:</span> <span class="p">[</span>
</span><span class='line'>        <span class="s2">&quot;run&quot;</span>
</span><span class='line'>    <span class="p">],</span>
</span><span class='line'>    <span class="nt">&quot;Config&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>        <span class="nt">&quot;AttachStderr&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span><span class='line'>    <span class="err">...</span>
</span><span class='line'>    <span class="nt">&quot;NetworkSettings&quot;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>        <span class="nt">&quot;Bridge&quot;</span><span class="p">:</span> <span class="s2">&quot;docker0&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="nt">&quot;Gateway&quot;</span><span class="p">:</span> <span class="s2">&quot;172.17.42.1&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="nt">&quot;IPAddress&quot;</span><span class="p">:</span> <span class="s2">&quot;172.17.0.27&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="err">...</span>
</span></code></pre></td></tr></table></div></figure>


<p>Update: <a href="https://twitter.com/upthecyberpunks">Nathan LeClaire</a> from <a href="http://docker.io">Docker</a> was kind enough to write up a <a href="https://gist.github.com/nathanleclaire/c7c402f7a9889ca77b98">quick script</a> that combines these two steps:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>docker run -d -p 11210:11210 -p 11211:11211 -p 8091:8091 -p 8092:8092 --name cb1 dustin/couchbase
</span><span class='line'>
</span><span class='line'><span class="k">for </span>name in cb<span class="o">{</span>2..5<span class="o">}</span>; <span class="k">do </span>
</span><span class='line'><span class="k">    </span>docker run -d --name <span class="nv">$name</span> dustin/couchbase
</span><span class='line'><span class="k">done</span>
</span><span class='line'>
</span><span class='line'><span class="k">for </span>name in cb<span class="o">{</span>1..5<span class="o">}</span>; <span class="k">do</span>
</span><span class='line'><span class="k">    </span>docker inspect -f <span class="s1">&#39;{{ .NetworkSettings.IPAddress }}&#39;</span> <span class="nv">$name</span>
</span><span class='line'><span class="k">done</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Setup Cluster using WebUI</h3>

<p>If <code>cb1</code> is at <code>172.17.0.27</code>, then the Couchbase management interface comes up at <code>http://172.17.0.27:8091</code> and the default credentials are:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="err">Username:</span> <span class="err">Administrator</span>
</span><span class='line'><span class="err">Password:</span> <span class="err">password</span>
</span></code></pre></td></tr></table></div></figure>


<p>Once you&rsquo;re in, setting up a cluster is as easy as clicking &ldquo;Add Server&rdquo; and giving it the IPs of the other containers. As soon as you add a new server to the cluster, Couchbase will prompt you to run a &ldquo;Cluster Rebalance&rdquo; operation &ndash; hold off until you&rsquo;ve added all 5 nodes and then run the rebalance.</p>

<p><img src="http://blog.abhinav.ca/images/2014-07-31-Couchbase-WebUI-Rebalance.png"></p>

<h3>Push some data into the cluster</h3>

<p>Once the cluster was up, I wanted to get a feel for how the WebUI works so I wrote this script to grab some data from our existing cluster of JSON-store-that-I-am-too-ashamed-to-mention and added it to Couchbase:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c">#!/usr/bin/env python</span>
</span><span class='line'><span class="c"># encoding: utf-8</span>
</span><span class='line'>
</span><span class='line'><span class="kn">from</span> <span class="nn">pymongo</span> <span class="kn">import</span> <span class="n">MongoClient</span>
</span><span class='line'><span class="kn">from</span> <span class="nn">couchbase</span> <span class="kn">import</span> <span class="n">Couchbase</span>
</span><span class='line'>
</span><span class='line'><span class="n">src</span> <span class="o">=</span> <span class="n">MongoClient</span><span class="p">([</span><span class="s">&#39;m1&#39;</span><span class="p">,</span> <span class="s">&#39;m2&#39;</span><span class="p">,</span> <span class="s">&#39;m3&#39;</span><span class="p">])[</span><span class="s">&#39;twitter_raw&#39;</span><span class="p">][</span><span class="s">&#39;starbucks&#39;</span><span class="p">]</span>
</span><span class='line'><span class="n">tar</span> <span class="o">=</span> <span class="n">Couchbase</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">bucket</span><span class="o">=</span><span class="s">&#39;twitter_starbucks&#39;</span><span class="p">,</span>  <span class="n">host</span><span class="o">=</span><span class="s">&#39;localhost&#39;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">for</span> <span class="n">doc</span> <span class="ow">in</span> <span class="n">src</span><span class="o">.</span><span class="n">find</span><span class="p">():</span>
</span><span class='line'>  <span class="n">key</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">doc</span><span class="p">[</span><span class="s">&#39;_id&#39;</span><span class="p">])</span>
</span><span class='line'>  <span class="k">del</span> <span class="n">doc</span><span class="p">[</span><span class="s">&#39;_id&#39;</span><span class="p">]</span>
</span><span class='line'>  <span class="n">result</span> <span class="o">=</span> <span class="n">tar</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">doc</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>The Couchbase <a href="http://www.couchbase.com/communities/python">python client</a> depends on <a href="http://www.couchbase.com/communities/c-client-library">libcouchbase</a>. Once those two were installed, and the <code>twitter_starbucks</code> bucket had been created in Couchbase, I was able to load ~100k JSON documents in a matter of minutes.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Docker + NodeJS Dev Environment: Take 2 - Container Linking]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/07/25/docker-nodejs-dev-environment-take-2/"/>
    <updated>2014-07-25T10:31:08-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/07/25/docker-nodejs-dev-environment-take-2</id>
    <content type="html"><![CDATA[<p>I&rsquo;ve had lots of feedback on my previous <a href="http://blog.abhinav.ca/blog/2014/06/17/develop-a-nodejs-app-with-docker/">post</a> and I&rsquo;d like to share some of it which I found especially helpful.</p>

<p><a href="https://github.com/larose">Mathieu Larose</a> sent over a much shorter one-liner that installs Node in the docker container. This means my original <code>Dockerfile</code> step</p>

<figure class='code'><figcaption><span>Dockerfile </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>RUN  \
</span><span class='line'>  cd /opt && \
</span><span class='line'>  wget http://nodejs.org/dist/v0.10.28/node-v0.10.28-linux-x64.tar.gz && \
</span><span class='line'>  tar -xzf node-v0.10.28-linux-x64.tar.gz && \
</span><span class='line'>  mv node-v0.10.28-linux-x64 node && \
</span><span class='line'>  cd /usr/local/bin && \
</span><span class='line'>  ln -s /opt/node/bin/* . && \
</span><span class='line'>  rm -f /opt/node-v0.10.28-linux-x64.tar.gz</span></code></pre></td></tr></table></div></figure>


<p>turns into</p>

<figure class='code'><figcaption><span>Dockerfile </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>RUN \
</span><span class='line'>  wget -O - http://nodejs.org/dist/v0.10.29/node-v0.10.29-linux-x64.tar.gz \
</span><span class='line'>  | tar xzf - --strip-components=1 --exclude="README.md" --exclude="LICENSE" \
</span><span class='line'>  --exclude="ChangeLog" -C "/usr/local"</span></code></pre></td></tr></table></div></figure>


<p>The second piece of feedback was via Twitter from <a href="http://twitter.com/DShankar">Darshan Shankar</a></p>

<p><a href="http://blog.abhinav.ca/images/2014-07-25-Feedback-2.png"><img src="http://blog.abhinav.ca/images/2014-07-25-Feedback-2.png"></a></p>

<p>As I explained on Twitter and at the end of the previous post, having Redis and Node in the same container was meant only to demonstrate how Docker works to first-timers. It isn&rsquo;t recommended as a production setup.</p>

<h3>Unbundling Redis and Container Links</h3>

<p>Since I&rsquo;ve already agreed that having Redis and Node together is probably not the greatest idea, I&rsquo;m going to take this opportunity to fix this mistake and demonstrate container linking at the same time.</p>

<p>The fundamental idea is to strive for single-purpose Docker containers and then compose them together to build more complex systems. This implies we need to rip out the Redis related bits from our old Dockerfile and run Redis in a Docker container by itself.</p>

<h3>Redis in a Docker container</h3>

<p>Now that we&rsquo;ve decided to unbundle Redis, let&rsquo;s run it in its own container. Fortunately, as is often the case with Docker, someone else has already done the hard work for us. Running Redis locally is as simple as:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>docker run -d --name="myredis" -p 6379:6379 dockerfile/redis</span></code></pre></td></tr></table></div></figure>


<p>You&rsquo;ll notice the extra <code>--name="myredis"</code> parameter. We&rsquo;ll use that in the next step to tell our app&rsquo;s container about this Redis container.</p>

<h3>Dockerfile update</h3>

<p>The next step is to update our Dockerfile and exclude the Redis-related instructions.</p>

<figure class='code'><figcaption><span>Dockerfile </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>FROM dockerfile/ubuntu
</span><span class='line'>
</span><span class='line'>MAINTAINER Abhinav Ajgaonkar &lt;abhinav316@gmail.com&gt;
</span><span class='line'>
</span><span class='line'># Install pre-reqs
</span><span class='line'>RUN   \
</span><span class='line'>  apt-get -y -qq install python
</span><span class='line'>
</span><span class='line'># Install Node
</span><span class='line'>RUN \
</span><span class='line'>  wget -O - http://nodejs.org/dist/v0.10.29/node-v0.10.29-linux-x64.tar.gz \
</span><span class='line'>  | tar xzf - --strip-components=1 --exclude=&quot;README.md&quot; --exclude=&quot;LICENSE&quot; \
</span><span class='line'>  --exclude=&quot;ChangeLog&quot; -C &quot;/usr/local&quot;
</span><span class='line'>
</span><span class='line'># Set the working directory
</span><span class='line'>WORKDIR   /src
</span><span class='line'>
</span><span class='line'>CMD [&quot;/bin/bash&quot;]
</span></code></pre></td></tr></table></div></figure>


<h3>Build, Link and Run</h3>

<p>Our app image can now be built with:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>docker build -t sqldump/docker-dev:0.2 .</span></code></pre></td></tr></table></div></figure>


<p>Once the build has completed, we can launch a container using the image.
The command for launching an instance of this image also needs to be modified slightly:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>docker run -i -t --rm                     \
</span><span class='line'>      -p 3000:3000                        \
</span><span class='line'>      -v `pwd`:/src                       \
</span><span class='line'>      --name="myapp"                      \
</span><span class='line'>      --link myredis:myredis              \
</span><span class='line'>      -e REDIS_HOST="myredis"             \
</span><span class='line'>      sqldump/docker-dev:0.2</span></code></pre></td></tr></table></div></figure>


<p>Here, I&rsquo;ve used the <code>--link</code> option to tell the <code>myapp</code> container about the <code>redis</code> container. The <code>--link</code> option allows linked containers to communicate securely over the <code>docker0</code> interface. When we link the <code>myredis</code> container to the <code>myapp</code> container, <code>myapp</code> can then access services on <code>myredis</code> just by using the hostname and the hostname-to-IP resolution will be handled transparently by Docker.</p>

<p>I&rsquo;ve also injected an environment variable called <code>REDIS_HOST</code> using the <code>-e</code> flag to tell our node app where to find the linked Redis.</p>

<p>Once the container is running, you can utilize the methods described in the previous post to install dependencies and get your server running.</p>

<p>I hope this provides a satisfactory demonstration of how linked containers can be used to compose single-purpose docker containers into a more complex working system.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Develop a NodeJS app with Docker]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/06/17/develop-a-nodejs-app-with-docker/"/>
    <updated>2014-06-17T01:58:40-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/06/17/develop-a-nodejs-app-with-docker</id>
    <content type="html"><![CDATA[<p>This is the first of two posts. This post covers a somewhat detailed tutorial on using Docker as a replacement for <a href="http://www.vagrantup.com/">Vagrant</a> when developing a Node app using the <a href="http://expressjs.com/">Express</a> framework. To make things a bit non-trivial, the app will persist session information in Redis using the <a href="https://github.com/visionmedia/connect-redis">connect-redis</a> middleware. The second post will cover productionizing this development setup.</p>

<h3>The Node App</h3>

<p>The app consists of a <code>package.json</code>, <code>server.js</code> and a <code>.gitignore</code> file, which is about as simple as it gets.</p>

<figure class='code'><figcaption><span>.gitignore </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>node_modules/*</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>package.json </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;docker-dev&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;version&quot;</span><span class="o">:</span> <span class="s2">&quot;0.1.0&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Docker Dev&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;dependencies&quot;</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'>        <span class="s2">&quot;connect-redis&quot;</span><span class="o">:</span> <span class="s2">&quot;~1.4.5&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;express&quot;</span><span class="o">:</span> <span class="s2">&quot;~3.3.3&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;hiredis&quot;</span><span class="o">:</span> <span class="s2">&quot;~0.1.15&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="s2">&quot;redis&quot;</span><span class="o">:</span> <span class="s2">&quot;~0.8.4&quot;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>server.js </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">),</span>
</span><span class='line'>    <span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">(),</span>
</span><span class='line'>    <span class="nx">redis</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;redis&#39;</span><span class="p">),</span>
</span><span class='line'>    <span class="nx">RedisStore</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;connect-redis&#39;</span><span class="p">)(</span><span class="nx">express</span><span class="p">),</span>
</span><span class='line'>    <span class="nx">server</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;http&#39;</span><span class="p">).</span><span class="nx">createServer</span><span class="p">(</span><span class="nx">app</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">app</span><span class="p">.</span><span class="nx">configure</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="nx">cookieParser</span><span class="p">(</span><span class="s1">&#39;keyboard-cat&#39;</span><span class="p">));</span>
</span><span class='line'>  <span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="nx">session</span><span class="p">({</span>
</span><span class='line'>        <span class="nx">store</span><span class="o">:</span> <span class="k">new</span> <span class="nx">RedisStore</span><span class="p">({</span>
</span><span class='line'>            <span class="nx">host</span><span class="o">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">REDIS_HOST</span> <span class="o">||</span> <span class="s1">&#39;localhost&#39;</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">port</span><span class="o">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">REDIS_PORT</span> <span class="o">||</span> <span class="mi">6379</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">db</span><span class="o">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">REDIS_DB</span> <span class="o">||</span> <span class="mi">0</span>
</span><span class='line'>        <span class="p">}),</span>
</span><span class='line'>        <span class="nx">cookie</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">expires</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">maxAge</span><span class="o">:</span> <span class="mi">30</span> <span class="o">*</span> <span class="mi">24</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}));</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">({</span>
</span><span class='line'>    <span class="nx">status</span><span class="o">:</span> <span class="s2">&quot;ok&quot;</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">port</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">HTTP_PORT</span> <span class="o">||</span> <span class="mi">3000</span><span class="p">;</span>
</span><span class='line'><span class="nx">server</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">port</span><span class="p">);</span>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Listening on port &#39;</span> <span class="o">+</span> <span class="nx">port</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>server.js</code> pulls in all the dependencies and starts an express app. The express app is configured to store session information in Redis and exposes a single endpoint that returns a status message as JSON. Pretty standard stuff.</p>

<p>One thing to note here is that the connection information for redis can be overridden using environment variables &ndash; this will be useful later on when moving from dev to prod.</p>

<h3>The Dockerfile</h3>

<p>For development, we&rsquo;ll have redis and node running in the same container. To make this happen, we&rsquo;ll use a Dockerfile to configure the container.</p>

<figure class='code'><figcaption><span>Dockerfile </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>FROM dockerfile/ubuntu
</span><span class='line'>
</span><span class='line'>MAINTAINER Abhinav Ajgaonkar &lt;abhinav316@gmail.com>
</span><span class='line'>
</span><span class='line'># Install Redis
</span><span class='line'>RUN   \
</span><span class='line'>  apt-get -y -qq install python redis-server
</span><span class='line'>
</span><span class='line'># Install Node
</span><span class='line'>RUN   \
</span><span class='line'>  cd /opt && \
</span><span class='line'>  wget http://nodejs.org/dist/v0.10.28/node-v0.10.28-linux-x64.tar.gz && \
</span><span class='line'>  tar -xzf node-v0.10.28-linux-x64.tar.gz && \
</span><span class='line'>  mv node-v0.10.28-linux-x64 node && \
</span><span class='line'>  cd /usr/local/bin && \
</span><span class='line'>  ln -s /opt/node/bin/* . && \
</span><span class='line'>  rm -f /opt/node-v0.10.28-linux-x64.tar.gz
</span><span class='line'>
</span><span class='line'># Set the working directory
</span><span class='line'>WORKDIR   /src
</span><span class='line'>
</span><span class='line'>CMD ["/bin/bash"]</span></code></pre></td></tr></table></div></figure>


<p>Taking it line by line,</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>FROM dockerfile/ubuntu</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>This tells docker to use the <code>dockerfile/ubuntu</code> image provided by Docker Inc. as the base image for the build.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>RUN  \
</span><span class='line'>  apt-get -y -qq install python redis-server</span></code></pre></td></tr></table></div></figure>


<p>The base image contains absolutely nothing- so we need to apt-get everything needed for our app to run. This statement installs python and redis-server. Redis server is required because we&rsquo;ll be storing session info in it and python is required by npm to be able to build the C-extension used by the redis node module.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>RUN  \
</span><span class='line'>  cd /opt && \
</span><span class='line'>  wget http://nodejs.org/dist/v0.10.28/node-v0.10.28-linux-x64.tar.gz && \
</span><span class='line'>  tar -xzf node-v0.10.28-linux-x64.tar.gz && \
</span><span class='line'>  mv node-v0.10.28-linux-x64 node && \
</span><span class='line'>  cd /usr/local/bin && \
</span><span class='line'>  ln -s /opt/node/bin/* . && \
</span><span class='line'>  rm -f /opt/node-v0.10.28-linux-x64.tar.gz</span></code></pre></td></tr></table></div></figure>


<p>This downloads and extracts the 64-bit NodeJS binaries.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>WORKDIR  /src</span></code></pre></td></tr></table></div></figure>


<p>This tells docker to <code>cd /src</code> once the container has started, before executing what&rsquo;s specified in the <code>CMD</code> property.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>CMD ["/bin/bash"]</span></code></pre></td></tr></table></div></figure>


<p>Launch <code>/bin/bash</code> as a final step.</p>

<h3>Build and run the container</h3>

<p>Now that the docker file is written, let&rsquo;s build a Docker image.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>docker build -t sqldump/docker-dev:0.1 .</span></code></pre></td></tr></table></div></figure>


<p>Once the image done building, we can launch a container using:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>docker run -i -t --rm \
</span><span class='line'>           -p 3000:3000 \
</span><span class='line'>           -v `pwd`:/src \
</span><span class='line'>           sqldump/docker-dev:0.1</span></code></pre></td></tr></table></div></figure>


<p>Let&rsquo;s see what&rsquo;s going on in the docker run command.</p>

<p><code>-i</code> starts the container in interactive mode (versus -d for detached mode). This means the container will exit once the interactive sessions is over.</p>

<p><code>-t</code> allocates a pseudo-tty.</p>

<p><code>--rm</code> removes the container and its filesystem on exit.</p>

<p><code>-p 3000:3000</code> forwards port 3000 on to the host to port 3000 on the container.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>-v `pwd`:/src</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>This mounts the current working directory in the host (i.e. our project files) to <code>/src</code> inside the container. We mount the current folder as a volume rather than using the <code>ADD</code> command in the Dockerfile so that any changes we make to the files in a text editor will be seen by the container right away.</p>

<p><code>sqldump/docker-dev:0.1</code> the name and version of the docker image to run &ndash; this is the same one we used when building the docker image.</p>

<p>Since the Dockerfile specifies <code>CMD ["/bin/bash"]</code>, we&rsquo;re dropped into a bash shell once the container has started. If the docker run command succeeds, it&rsquo;ll look something like this:</p>

<p><a href="http://blog.abhinav.ca/images/2014-06-17-Docker-Run.png"><img src="http://blog.abhinav.ca/images/2014-06-17-Docker-Run.png" width="482" height="139"></a></p>

<h3>Start Developing</h3>

<p>Now that the container is running, we&rsquo;ll need to get a few standard, non-docker related things sorted out before we can start writing code. First, start redis server inside the container using:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>service redis-server start</span></code></pre></td></tr></table></div></figure>


<p>Then, install project dependencies and <code>nodemon</code>. <a href="https://github.com/remy/nodemon">Nodemon</a> watches for changes in project files and restarts the server as needed.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>npm install
</span><span class='line'>npm install -g nodemon</span></code></pre></td></tr></table></div></figure>


<p>Finally, start up the server using:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nodemon server.js</span></code></pre></td></tr></table></div></figure>


<p>Now, if you go to <code>http://localhost:3000</code> in your browser, you should see something like this:</p>

<p><a href="http://blog.abhinav.ca/images/2014-06-17-First-Run.png"><img src="http://blog.abhinav.ca/images/2014-06-17-First-Run.png" width="230" height="110"></a></p>

<p>Let&rsquo;s add another endpoint to <code>server.js</code> to simulate development workflow:</p>

<figure class='code'><figcaption><span>server.js </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/hello/:name&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">({</span>
</span><span class='line'>    <span class="nx">hello</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">name</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>You should see that nodemon has detected your changes and restarted the server:</p>

<p><a href="http://blog.abhinav.ca/images/2014-06-17-Reload.png"><img src="http://blog.abhinav.ca/images/2014-06-17-Reload.png" width="1072" height="390"></a></p>

<p>And now, if you point your browser to <code>http://localhost:3000/hello/world</code>, you should see the response:</p>

<p><a href="http://blog.abhinav.ca/images/2014-06-17-Second-Run.png"><img src="http://blog.abhinav.ca/images/2014-06-17-Second-Run.png" width="348" height="140"></a></p>

<h3>Production</h3>

<p>The container, in its current state, is nowehere near production-ready. The data in redis won&rsquo;t be persisted across container restarts, i.e. if you restart the container, you&rsquo;ll have effectively blown away all your session data. The same thing will happen if you destroy the container and start a new one. Presumably, this is not what you want. I&rsquo;ll cover production setup in part II.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Tracing Akka Projects with Atmos]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/04/19/tracing-akka-projects-with-atmos/"/>
    <updated>2014-04-19T16:37:28-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/04/19/tracing-akka-projects-with-atmos</id>
    <content type="html"><![CDATA[<p><a href="https://github.com/sbt/sbt-atmos">Atmos</a> is an SBT plugin that allows you to trace Akka and Play projects to help identify and fix bottlenecks.</p>

<h3>Installation</h3>

<p>Add the following lines to your project:</p>

<figure class='code'><figcaption><span>project/plugins.sbt </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="n">addSbtPlugin</span><span class="o">(</span><span class="s">&quot;com.typesafe.sbt&quot;</span> <span class="o">%</span> <span class="s">&quot;sbt-atmos&quot;</span> <span class="o">%</span> <span class="s">&quot;0.3.2&quot;</span><span class="o">)</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>build.sbt </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="n">atmosSettings</span>
</span><span class='line'>
</span><span class='line'><span class="n">atmosTestSettings</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Usage</h3>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sbt atmos:run</span></code></pre></td></tr></table></div></figure>


<p>The Atmos UI comes up on <code>localhost:9900</code>.</p>

<h3>Screenshots</h3>

<p>Atmos has a great overview screen that shows you vital system-wide statistics.</p>

<p><a href="http://blog.abhinav.ca/images/2014-04-19-Atmos-Overview.png"><img src="http://blog.abhinav.ca/images/2014-04-19-Atmos-Overview.png" width="1436" height="697"></a></p>

<p>It also allows you to drill down and dig into dispatcher-level as well as ActorSystem level stats.</p>

<p><a href="http://blog.abhinav.ca/images/2014-04-19-Atmos-Dispatchers.png"><img src="http://blog.abhinav.ca/images/2014-04-19-Atmos-Dispatchers.png" width="1078"></a></p>

<p><a href="http://blog.abhinav.ca/images/2014-04-19-Atmos-ActorSystems.png"><img src="http://blog.abhinav.ca/images/2014-04-19-Atmos-ActorSystems.png" width="1077"></a></p>

<p>And, best of all, it shows you Actor-level stats like message throughput, mailbox size over time as well as mean time spent in mailbox- which are extremely helpful when tracing bottlenecks.</p>

<p><a href="http://blog.abhinav.ca/images/2014-04-19-Atmos-Actor.png"><img src="http://blog.abhinav.ca/images/2014-04-19-Atmos-Actor.png" width="1437"></a></p>

<p>I&rsquo;ve put up a working project with Atmos <a href="https://github.com/sqldump/akka-atmos">here</a>. It&rsquo;ll run for about 5 minutes so you can explore the Atmos UI and then terminate. If you want to give it a try:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git clone https://github.com/sqldump/akka-atmos.git
</span><span class='line'>cd akka-atmos
</span><span class='line'>sbt atmos:run</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Scaffolding an Akka project]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/04/17/scaffolding-an-akka-project/"/>
    <updated>2014-04-17T01:34:01-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/04/17/scaffolding-an-akka-project</id>
    <content type="html"><![CDATA[<p>Every time I&rsquo;ve needed to start a new Akka project, I&rsquo;ve had to go through the process of scaffolding a new project from scratch. So I finally got around to creating a skeleton project that includes the bare minimum dependencies along with a build file, plugins and configuration required to create a fat jar as well as the ability to run in place. You can find the akka-skeleton project <a href="https://github.com/abh1nav/akka-skeleton">here</a>.</p>

<p>To get going with akka-skeleton,</p>

<ol>
<li>Modify the <code>organization, name &amp; version</code> in <code>build.sbt</code></li>
<li>Rename the package heirarchy under <code>src/main/scala</code></li>
<li>Ensure you have atleast one class that <code>extends App</code></li>
<li><code>sbt run</code></li>
</ol>


<h3>Included Dependencies</h3>

<ol>
<li>Akka Actor Module</li>
<li>Akka Agent Module</li>
<li>Google Guava</li>
<li>Joda Time (and <code>joda-convert</code> to make it work correctly with Scala)</li>
<li>JUnit, ScalaTest and Akka TestKit</li>
<li>Akka SLF4J Adapter</li>
</ol>


<h3>File Structure</h3>

<p>The project root looks like this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>project/
</span><span class='line'>src/
</span><span class='line'>build.sbt</span></code></pre></td></tr></table></div></figure>


<h4><code>project</code></h4>

<p>The <code>project</code> folder contains all the files that help SBT build the project.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>project
</span><span class='line'>|-Dependencies.scala
</span><span class='line'>|-build.properties
</span><span class='line'>|-plugins.sbt</span></code></pre></td></tr></table></div></figure>


<ul>
<li><code>build.properties</code> describes the SBT version used to build the project</li>
<li><code>plugins.sbt</code> describes all the SBT plugins used to build the project &ndash; for example, the <code>assembly</code> plugin is used to create a fat jar of the project including all the dependencies</li>
<li><code>Dependencies.scala</code> describes all the project dependencies &ndash; objects from here are imported by the <code>build.sbt</code> file when building the project</li>
</ul>


<p>The <code>src</code> folder contains the project source, test and resource files.</p>

<h3>Build, Run and Assembly</h3>

<p><code>sbt clean</code> to clean.<br/>
<code>sbt compile</code> to build.<br/>
<code>sbt run</code> to run.<br/>
<code>sbt assembly</code> to create a fat jar.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Setup a Spark Cluster in 5 minutes]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/04/13/setup-a-spark-cluster-in-5-minutes/"/>
    <updated>2014-04-13T23:31:45-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/04/13/setup-a-spark-cluster-in-5-minutes</id>
    <content type="html"><![CDATA[<h4>Prerequisites</h4>

<p>Assuming you have 3 nodes: <code>node1, node2, node3</code>, ensure the hosts file contains the following entries on all nodes:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>192.168.1.100  node1
</span><span class='line'>192.168.1.101  node2
</span><span class='line'>192.168.1.102  node3
</span></code></pre></td></tr></table></div></figure>


<p>Be sure replace <code>192.168.x.x</code> with the actual IPs for each node.</p>

<h4>Get Spark</h4>

<p>Download binaries from <a href="http://spark.apache.org/downloads.html">http://spark.apache.org/downloads.html</a> and extract it to <code>/opt/</code>.</p>

<h4>Spark Master</h4>

<p>Start the master process on <code>node1</code></p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> /opt/spark-0.9.0-incubating-bin-hadoop1
</span><span class='line'>sbin/start-master.sh
</span></code></pre></td></tr></table></div></figure>


<h4>Spark Workers</h4>

<p>Start worker processes on each node:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> /opt/spark-0.9.0-incubating-bin-hadoop1
</span><span class='line'>bin/spark-class org.apache.spark.deploy.worker.Worker spark://node1:7077
</span></code></pre></td></tr></table></div></figure>


<p>Check the Spark UI at <code>http://node1:8080</code> to make sure all workers have registered with the master.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[File uploads in Scala via Apache HttpComponents]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/02/08/file-uploads-via-apache-httpcomponents/"/>
    <updated>2014-02-08T20:10:05-05:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/02/08/file-uploads-via-apache-httpcomponents</id>
    <content type="html"><![CDATA[<p>In order to upload photos to Facebook from the server-side, the Graph API requires you to make a POST request with the image attached as multipart/form-data. Since I couldn&rsquo;t find any native Scala libraries that make this task easy or intuitive, I went with the battle-tested Apache HttpComponents library.</p>

<p>Since the app was going to upload photos to Facebook in an on-demand fashion, I went with an HTTPClient that could be reused and was able handle multiple requests concurrently.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">val</span> <span class="n">httpClient</span> <span class="k">=</span> <span class="o">{</span>
</span><span class='line'>  <span class="k">val</span> <span class="n">connManager</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">PoolingHttpClientConnectionManager</span><span class="o">()</span>
</span><span class='line'>  <span class="nc">HttpClients</span><span class="o">.</span><span class="n">custom</span><span class="o">().</span><span class="n">setConnectionManager</span><span class="o">(</span><span class="n">connManager</span><span class="o">).</span><span class="n">build</span><span class="o">()</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The next step was to create an entity that contains all the POST data:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">val</span> <span class="n">accessToken</span> <span class="k">=</span> <span class="s">&quot;MY_FACEBOOK_ACCESS_TOKEN&quot;</span>
</span><span class='line'><span class="k">val</span> <span class="n">file</span> <span class="k">=</span> <span class="s">&quot;/absolute/path/to/file.jpg&quot;</span>
</span><span class='line'><span class="k">val</span> <span class="n">reqEntity</span> <span class="k">=</span> <span class="nc">MultipartEntityBuilder</span><span class="o">.</span><span class="n">create</span><span class="o">()</span>
</span><span class='line'><span class="n">reqEntity</span><span class="o">.</span><span class="n">addPart</span><span class="o">(</span><span class="s">&quot;source&quot;</span><span class="o">,</span> <span class="k">new</span> <span class="nc">FileBody</span><span class="o">(</span><span class="n">file</span><span class="o">))</span>
</span><span class='line'><span class="n">reqEntity</span><span class="o">.</span><span class="n">addPart</span><span class="o">(</span><span class="s">&quot;access_token&quot;</span><span class="o">,</span> <span class="k">new</span> <span class="nc">StringBody</span><span class="o">(</span><span class="n">accessToken</span><span class="o">,</span> <span class="nc">ContentType</span><span class="o">.</span><span class="nc">TEXT_PLAIN</span><span class="o">))</span>
</span></code></pre></td></tr></table></div></figure>


<p>In this case <code>source</code> is the name of the form field whose value is the image file. The next step is to create a POST request and execute it using our <code>httpClient</code>.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">val</span> <span class="n">uri</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">URI</span><span class="o">(</span><span class="s">&quot;https://graph.facebook.com/me/photos&quot;</span><span class="o">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">val</span> <span class="n">httpPost</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">HttpPost</span><span class="o">(</span><span class="n">uri</span><span class="o">)</span>
</span><span class='line'><span class="n">httpPost</span><span class="o">.</span><span class="n">setEntity</span><span class="o">(</span><span class="n">reqEntity</span><span class="o">.</span><span class="n">build</span><span class="o">())</span>
</span><span class='line'><span class="k">val</span> <span class="n">response</span> <span class="k">=</span> <span class="n">httpClient</span><span class="o">.</span><span class="n">execute</span><span class="o">(</span><span class="n">httpPost</span><span class="o">,</span> <span class="nc">HttpClientContext</span><span class="o">.</span><span class="n">create</span><span class="o">())</span>
</span></code></pre></td></tr></table></div></figure>


<p>Use <code>EntityUtils</code> to read the response text:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">val</span> <span class="n">entity</span> <span class="k">=</span> <span class="n">response</span><span class="o">.</span><span class="n">getEntity</span>
</span><span class='line'><span class="k">val</span> <span class="n">result</span> <span class="k">=</span> <span class="nc">EntityUtils</span><span class="o">.</span><span class="n">toString</span><span class="o">(</span><span class="n">entity</span><span class="o">)</span>
</span><span class='line'><span class="k">if</span><span class="o">(</span><span class="n">response</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="n">response</span><span class="o">.</span><span class="n">close</span><span class="o">()</span>
</span></code></pre></td></tr></table></div></figure>


<p>Remember to close the response after you&rsquo;re done reading from it. Here&rsquo;s a full example including all the imports:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">import</span> <span class="nn">java.io.File</span>
</span><span class='line'><span class="k">import</span> <span class="nn">java.net.URI</span>
</span><span class='line'><span class="k">import</span> <span class="nn">org.apache.http.client.methods.</span><span class="o">{</span><span class="nc">HttpPost</span><span class="o">,</span> <span class="nc">CloseableHttpResponse</span><span class="o">}</span>
</span><span class='line'><span class="k">import</span> <span class="nn">org.apache.http.client.protocol.HttpClientContext</span>
</span><span class='line'><span class="k">import</span> <span class="nn">org.apache.http.entity.mime.MultipartEntityBuilder</span>
</span><span class='line'><span class="k">import</span> <span class="nn">org.apache.http.entity.mime.content.</span><span class="o">{</span><span class="nc">StringBody</span><span class="o">,</span> <span class="nc">FileBody</span><span class="o">}</span>
</span><span class='line'><span class="k">import</span> <span class="nn">org.apache.http.entity.ContentType</span>
</span><span class='line'><span class="k">import</span> <span class="nn">org.apache.http.util.EntityUtils</span>
</span><span class='line'><span class="k">import</span> <span class="nn">org.apache.http.impl.conn.PoolingHttpClientConnectionManager</span>
</span><span class='line'><span class="k">import</span> <span class="nn">org.apache.http.impl.client.HttpClients</span>
</span><span class='line'><span class="k">import</span> <span class="nn">scala.util.Try</span>
</span><span class='line'>
</span><span class='line'><span class="k">object</span> <span class="nc">Uploader</span> <span class="o">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">lazy</span> <span class="k">val</span> <span class="n">httpClient</span> <span class="k">=</span> <span class="o">{</span>
</span><span class='line'>    <span class="k">val</span> <span class="n">connManager</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">PoolingHttpClientConnectionManager</span><span class="o">()</span>
</span><span class='line'>    <span class="nc">HttpClients</span><span class="o">.</span><span class="n">custom</span><span class="o">().</span><span class="n">setConnectionManager</span><span class="o">(</span><span class="n">connManager</span><span class="o">).</span><span class="n">build</span><span class="o">()</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="n">uploadToFacebook</span><span class="o">(</span><span class="n">file</span><span class="k">:</span> <span class="kt">File</span><span class="o">,</span> <span class="n">accessToken</span><span class="k">:</span> <span class="kt">String</span><span class="o">)</span><span class="k">:</span> <span class="kt">Try</span><span class="o">[</span><span class="kt">String</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
</span><span class='line'>    <span class="k">val</span> <span class="n">uri</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">URI</span><span class="o">(</span><span class="s">&quot;https://graph.facebook.com/me/photos&quot;</span><span class="o">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="nc">Try</span><span class="o">({</span>
</span><span class='line'>      <span class="c1">// Create the entity</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">reqEntity</span> <span class="k">=</span> <span class="nc">MultipartEntityBuilder</span><span class="o">.</span><span class="n">create</span><span class="o">()</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// Attach the file</span>
</span><span class='line'>      <span class="n">reqEntity</span><span class="o">.</span><span class="n">addPart</span><span class="o">(</span><span class="s">&quot;source&quot;</span><span class="o">,</span> <span class="k">new</span> <span class="nc">FileBody</span><span class="o">(</span><span class="n">file</span><span class="o">))</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// Attach the access token as plain text</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">tokenBody</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">StringBody</span><span class="o">(</span><span class="n">accessToken</span><span class="o">,</span> <span class="nc">ContentType</span><span class="o">.</span><span class="nc">TEXT_PLAIN</span><span class="o">)</span>
</span><span class='line'>      <span class="n">reqEntity</span><span class="o">.</span><span class="n">addPart</span><span class="o">(</span><span class="s">&quot;access_token&quot;</span><span class="o">,</span> <span class="n">tokenBody</span><span class="o">)</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// Create POST request</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">httpPost</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">HttpPost</span><span class="o">(</span><span class="n">uri</span><span class="o">)</span>
</span><span class='line'>      <span class="n">httpPost</span><span class="o">.</span><span class="n">setEntity</span><span class="o">(</span><span class="n">reqEntity</span><span class="o">.</span><span class="n">build</span><span class="o">())</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// Execute the request in a new HttpContext</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">ctx</span> <span class="k">=</span> <span class="nc">HttpClientContext</span><span class="o">.</span><span class="n">create</span><span class="o">()</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">response</span><span class="k">:</span> <span class="kt">CloseableHttpResponse</span> <span class="o">=</span> <span class="n">httpClient</span><span class="o">.</span><span class="n">execute</span><span class="o">(</span><span class="n">httpPost</span><span class="o">,</span> <span class="n">ctx</span><span class="o">)</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// Read the response</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">entity</span> <span class="k">=</span> <span class="n">response</span><span class="o">.</span><span class="n">getEntity</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">result</span> <span class="k">=</span> <span class="nc">EntityUtils</span><span class="o">.</span><span class="n">toString</span><span class="o">(</span><span class="n">entity</span><span class="o">)</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// Close the response</span>
</span><span class='line'>      <span class="k">if</span><span class="o">(</span><span class="n">response</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="n">response</span><span class="o">.</span><span class="n">close</span><span class="o">()</span>
</span><span class='line'>
</span><span class='line'>      <span class="n">result</span>
</span><span class='line'>    <span class="o">})</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Akka and Back-pressure]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/01/13/akka-and-backpressure/"/>
    <updated>2014-01-13T12:46:04-05:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/01/13/akka-and-backpressure</id>
    <content type="html"><![CDATA[<p>Two steps are needed in order to correctly apply back-pressure in an Akka system:</p>

<h4>Step 1: Bounded Mailboxes and Push Timeouts</h4>

<p>The default mailbox for an actor is an <code>UnboundedMailbox</code> backed by Java&rsquo;s <code>ConcurrentLinkedQueue</code>. As the name indicates, this mailbox grows without bound and will end up crashing the JVM with an <code>OutOfMemoryError</code> if the consumer significantly slower than the producer. If we want to be able to signal the producer to slow down, the first step is to switch to a <code>BoundedMailbox</code> backed by Java&rsquo;s <code>LinkedBlockingQueue</code> that will block the producer if the mailbox is full. More info about different types of mailboxes can be found <a href="http://doc.akka.io/docs/akka/snapshot/scala/mailboxes.html">here</a>.</p>

<p>Blocking the producer forever is not a good solution because: <code>Rule #1 of Akka =&gt; don't block inside actors</code>. The solution to this problem is provided to us by Akka in the form of a <code>push timeout</code> for an Actor&rsquo;s mailbox. A push timeout is exactly what it sounds like: when you try to push a message to an actor&rsquo;s mailbox, if the mailbox is full, the action will timeout and the message will get routed to the <code>DeadLetterActorRef</code>.</p>

<p>Configuring an actor to use a bounded mailbox with a 1000 message capacity and a push timeout of 100ms requires the following addition to the <code>application.conf</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>bounded-mailbox {
</span><span class='line'>  mailbox-type = "akka.dispatch.BoundedMailbox"
</span><span class='line'>  mailbox-capacity = 1000
</span><span class='line'>  mailbox-push-timeout-time = 100ms
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>The actor can then be initialized as follows</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">val</span> <span class="n">actor</span> <span class="k">=</span> <span class="n">system</span><span class="o">.</span><span class="n">actorOf</span><span class="o">(</span><span class="nc">Props</span><span class="o">[</span><span class="kt">MyActorClass</span><span class="o">].</span><span class="n">withMailbox</span><span class="o">(</span><span class="s">&quot;bounded-mailbox&quot;</span><span class="o">))</span>
</span></code></pre></td></tr></table></div></figure>


<h4>Step 2: DeadLetter Watcher</h4>

<p>When an actor&rsquo;s mailbox is full and sent messages start timing out, they get routed to the <code>DeadLetterActorRef</code> via the <a href="http://doc.akka.io/docs/akka/2.2.3/scala/event-bus.html#event-stream-scala">Event Stream</a> of the actor system. Akka allows actors to subscribe to event streams and listen in on all, or a filtered subset of, the messages flying around in the actor system. Since the dead letters service also utilizes the event stream infrastructure, we can subscribe to all <code>DeadLetter</code> messages being published in the stream and signal the producer to slow down.</p>

<p>The following snipped can be used to get an actor subscribed to all the <code>DeadLetter</code> messages in a system</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="n">system</span><span class="o">.</span><span class="n">eventStream</span><span class="o">.</span><span class="n">subscribe</span><span class="o">(</span><span class="n">listeningActor</span><span class="o">,</span> <span class="n">classOf</span><span class="o">[</span><span class="kt">DeadLetter</span><span class="o">])</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Tying it all together with an Example</h3>

<p>In this example, a fast producer sends messages to a slow consumer. The slow consumer has a bounded mailbox of size 10 and a push timeout of 10ms.</p>

<h5>SlowReceiver</h5>

<p>The <code>SlowReceiver</code> blocks for 100ms after printing each message it receives. The blocking is only present to ensure that it&rsquo;s mailbox fills up.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">import</span> <span class="nn">akka.actor._</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">SlowReceiver</span> <span class="k">extends</span> <span class="nc">Actor</span> <span class="k">with</span> <span class="nc">ActorLogging</span> <span class="o">{</span>
</span><span class='line'>  <span class="k">override</span> <span class="k">def</span> <span class="n">postStop</span><span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    <span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="o">(</span><span class="s">&quot;SlowReceiver#postStop&quot;</span><span class="o">)</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="n">receive</span><span class="k">:</span> <span class="kt">Actor.Receive</span> <span class="o">=</span> <span class="o">{</span>
</span><span class='line'>    <span class="k">case</span> <span class="n">msg</span><span class="k">:</span> <span class="kt">String</span> <span class="o">=&gt;</span>
</span><span class='line'>      <span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="o">(</span><span class="n">s</span><span class="s">&quot;Received: $msg&quot;</span><span class="o">)</span>
</span><span class='line'>      <span class="nc">Thread</span><span class="o">.</span><span class="n">sleep</span><span class="o">(</span><span class="mi">100</span><span class="o">)</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h5>FastSender</h5>

<p>The <code>FastSender</code> waits for a kickoff message and then sends 15 messages to the <code>SlowReceiver</code> and a <code>PoisonPill</code> to itself. After terminating itself, the actor&rsquo;s <code>postStop</code> hook schedules a <code>PoisonPill</code> to be sent to the <code>SlowReceiver</code> 3 seconds after the <code>FastSender</code> has been terminated.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">import</span> <span class="nn">akka.actor._</span>
</span><span class='line'><span class="k">import</span> <span class="nn">scala.concurrent.duration._</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">FastSender</span><span class="o">(</span><span class="n">slow</span><span class="k">:</span> <span class="kt">ActorRef</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Actor</span> <span class="k">with</span> <span class="nc">ActorLogging</span> <span class="o">{</span>
</span><span class='line'>  <span class="k">override</span> <span class="k">def</span> <span class="n">postStop</span><span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    <span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="o">(</span><span class="s">&quot;FastSender#postStop&quot;</span><span class="o">)</span>
</span><span class='line'>    <span class="n">context</span><span class="o">.</span><span class="n">system</span><span class="o">.</span><span class="n">scheduler</span><span class="o">.</span><span class="n">scheduleOnce</span><span class="o">(</span><span class="mf">2.</span><span class="n">seconds</span><span class="o">,</span> <span class="n">slow</span><span class="o">,</span> <span class="nc">PoisonPill</span><span class="o">)(</span><span class="n">context</span><span class="o">.</span><span class="n">dispatcher</span><span class="o">)</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="n">receive</span><span class="k">:</span> <span class="kt">Actor.Receive</span> <span class="o">=</span> <span class="o">{</span>
</span><span class='line'>    <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span>
</span><span class='line'>      <span class="k">for</span><span class="o">(</span><span class="n">i</span> <span class="k">&lt;-</span> <span class="mi">1</span> <span class="n">to</span> <span class="mi">15</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>        <span class="n">slow</span> <span class="o">!</span> <span class="n">s</span><span class="s">&quot;[$i]&quot;</span>
</span><span class='line'>      <span class="o">}</span>
</span><span class='line'>      <span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="o">(</span><span class="s">&quot;Done sending all&quot;</span><span class="o">)</span>
</span><span class='line'>      <span class="n">self</span> <span class="o">!</span> <span class="nc">PoisonPill</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h5>Watcher</h5>

<p>The <code>Watcher</code> watches for and prints <code>DeadLetter</code>s being sent to the <code>SlowReceiver</code>. It also <code>context.watch</code>es the <code>SlowReceiver</code> and terminates the actor system when the <code>SlowReceiver</code> is killed.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">import</span> <span class="nn">akka.actor._</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Watcher</span><span class="o">(</span><span class="n">target</span><span class="k">:</span> <span class="kt">ActorRef</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Actor</span> <span class="k">with</span> <span class="nc">ActorLogging</span> <span class="o">{</span>
</span><span class='line'>  <span class="k">private</span> <span class="k">val</span> <span class="n">targetPath</span> <span class="k">=</span> <span class="n">target</span><span class="o">.</span><span class="n">path</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">override</span> <span class="k">def</span> <span class="n">preStart</span><span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    <span class="n">context</span><span class="o">.</span><span class="n">watch</span><span class="o">(</span><span class="n">target</span><span class="o">)</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="n">receive</span><span class="k">:</span> <span class="kt">Actor.Receive</span> <span class="o">=</span> <span class="o">{</span>
</span><span class='line'>    <span class="k">case</span> <span class="n">d</span><span class="k">:</span> <span class="kt">DeadLetter</span> <span class="o">=&gt;</span>
</span><span class='line'>      <span class="k">if</span><span class="o">(</span><span class="n">d</span><span class="o">.</span><span class="n">recipient</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">equals</span><span class="o">(</span><span class="n">targetPath</span><span class="o">))</span> <span class="o">{</span>
</span><span class='line'>        <span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="o">(</span><span class="n">s</span><span class="s">&quot;Timed out message: ${d.message.toString}&quot;</span><span class="o">)</span>
</span><span class='line'>      <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">case</span> <span class="nc">Terminated</span><span class="o">(</span><span class="n">`target`</span><span class="o">)</span> <span class="k">=&gt;</span>
</span><span class='line'>      <span class="n">context</span><span class="o">.</span><span class="n">system</span><span class="o">.</span><span class="n">shutdown</span><span class="o">()</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h5>BackPressureTest App</h5>

<p>The App that ties it all together.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">object</span> <span class="nc">BackPressureTest</span> <span class="k">extends</span> <span class="nc">App</span> <span class="o">{</span>
</span><span class='line'>  <span class="k">case</span> <span class="k">object</span> <span class="nc">Ping</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">val</span> <span class="n">sys</span> <span class="k">=</span> <span class="nc">ActorSystem</span><span class="o">(</span><span class="s">&quot;testSys&quot;</span><span class="o">)</span>
</span><span class='line'>  <span class="k">val</span> <span class="n">slow</span> <span class="k">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">actorOf</span><span class="o">(</span><span class="nc">Props</span><span class="o">[</span><span class="kt">SlowReceiver</span><span class="o">].</span><span class="n">withMailbox</span><span class="o">(</span><span class="s">&quot;bounded-mailbox&quot;</span><span class="o">),</span> <span class="s">&quot;slow&quot;</span><span class="o">)</span>
</span><span class='line'>  <span class="k">val</span> <span class="n">fast</span> <span class="k">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">actorOf</span><span class="o">(</span><span class="nc">Props</span><span class="o">(</span><span class="n">classOf</span><span class="o">[</span><span class="kt">FastSender</span><span class="o">],</span> <span class="n">slow</span><span class="o">),</span> <span class="s">&quot;fast&quot;</span><span class="o">)</span>
</span><span class='line'>  <span class="k">val</span> <span class="n">watcher</span> <span class="k">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">actorOf</span><span class="o">(</span><span class="nc">Props</span><span class="o">(</span><span class="n">classOf</span><span class="o">[</span><span class="kt">Watcher</span><span class="o">],</span> <span class="n">slow</span><span class="o">),</span> <span class="s">&quot;watcher&quot;</span><span class="o">)</span>
</span><span class='line'>  <span class="n">sys</span><span class="o">.</span><span class="n">eventStream</span><span class="o">.</span><span class="n">subscribe</span><span class="o">(</span><span class="n">watcher</span><span class="o">,</span> <span class="n">classOf</span><span class="o">[</span><span class="kt">DeadLetter</span><span class="o">])</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">fast</span> <span class="o">!</span> <span class="nc">Ping</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h5>Output</h5>

<p>Running the <code>BackPressureTest</code> app gives the following output:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[INFO] [01/13/2014 14:00:56.303] [akka://testSys/user/slow] Received: [1]
</span><span class='line'>[INFO] [01/13/2014 14:00:56.315] [akka://testSys/user/watcher] Timed out message: [12]
</span><span class='line'>[INFO] [01/13/2014 14:00:56.326] [akka://testSys/user/watcher] Timed out message: [13]
</span><span class='line'>[INFO] [01/13/2014 14:00:56.337] [akka://testSys/user/watcher] Timed out message: [14]
</span><span class='line'>[INFO] [01/13/2014 14:00:56.347] [akka://testSys/user/fast] Done sending all
</span><span class='line'>[INFO] [01/13/2014 14:00:56.347] [akka://testSys/user/watcher] Timed out message: [15]
</span><span class='line'>[INFO] [01/13/2014 14:00:56.350] [akka://testSys/user/fast] FastSender#postStop
</span><span class='line'>[INFO] [01/13/2014 14:00:56.403] [akka://testSys/user/slow] Received: [2]
</span><span class='line'>[INFO] [01/13/2014 14:00:56.504] [akka://testSys/user/slow] Received: [3]
</span><span class='line'>[INFO] [01/13/2014 14:00:56.605] [akka://testSys/user/slow] Received: [4]
</span><span class='line'>[INFO] [01/13/2014 14:00:56.705] [akka://testSys/user/slow] Received: [5]
</span><span class='line'>[INFO] [01/13/2014 14:00:56.807] [akka://testSys/user/slow] Received: [6]
</span><span class='line'>[INFO] [01/13/2014 14:00:56.907] [akka://testSys/user/slow] Received: [7]
</span><span class='line'>[INFO] [01/13/2014 14:00:57.008] [akka://testSys/user/slow] Received: [8]
</span><span class='line'>[INFO] [01/13/2014 14:00:57.109] [akka://testSys/user/slow] Received: [9]
</span><span class='line'>[INFO] [01/13/2014 14:00:57.209] [akka://testSys/user/slow] Received: [10]
</span><span class='line'>[INFO] [01/13/2014 14:00:57.310] [akka://testSys/user/slow] Received: [11]
</span><span class='line'>[INFO] [01/13/2014 14:00:58.367] [akka://testSys/user/slow] SlowReceiver#postStop
</span><span class='line'>[DEBUG] [01/13/2014 14:00:58.373] [EventStream] shutting down: StandardOutLogger started
</span><span class='line'>[DEBUG] [01/13/2014 14:00:58.373] [EventStream] shutting down: StandardOutLogger started
</span><span class='line'>[DEBUG] [01/13/2014 14:00:58.375] [EventStream] all default loggers stopped
</span><span class='line'>
</span><span class='line'>Process finished with exit code 0</span></code></pre></td></tr></table></div></figure>


<h5>Back-pressure Strategy</h5>

<p>While this example doesn&rsquo;t actually implement back-pressure, it provides the infrastructure for applying a back-pressure strategy. A possible strategy would be to send <code>FastSender</code> a <code>SlowDown</code> message from within the <code>Watcher</code> for each dead letter received. The <code>SlowDown</code> case class could be defined as</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">case</span> <span class="k">class</span> <span class="nc">SlowDown</span><span class="o">(</span><span class="n">dl</span><span class="k">:</span> <span class="kt">DeadLetter</span><span class="o">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>When <code>FastSender</code> receives a <code>SlowDown</code> message, it could either throttle itself or tell its upstream systems to slow down. The <code>SlowDown</code> message also encapsulates the relevant <code>DeadLetter</code> object to allow for retry logic.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ExecutionContext for Long Running Tasks]]></title>
    <link href="http://blog.abhinav.ca/blog/2014/01/08/executioncontext-for-long-running-tasks/"/>
    <updated>2014-01-08T15:20:32-05:00</updated>
    <id>http://blog.abhinav.ca/blog/2014/01/08/executioncontext-for-long-running-tasks</id>
    <content type="html"><![CDATA[<p>Rule #1 of Akka: don’t block inside actors. If you do have blocking / high latency calls, wrap them in a future and toss them into a different execution context specifically meant for high latency tasks.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='scala'><span class='line'><span class="k">import</span> <span class="nn">java.util.concurrent.Executors</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">ClassyActor</span> <span class="k">extends</span> <span class="nc">Actor</span> <span class="o">{</span>
</span><span class='line'>  <span class="k">val</span> <span class="n">numThreads</span> <span class="k">=</span> <span class="mi">10</span>
</span><span class='line'>  <span class="k">val</span> <span class="n">pool</span> <span class="k">=</span> <span class="nc">Executors</span><span class="o">.</span><span class="n">newFixedThreadPool</span><span class="o">(</span><span class="n">numThreads</span><span class="o">)</span>
</span><span class='line'>  <span class="k">val</span> <span class="n">ctx</span> <span class="k">=</span> <span class="nc">ExecutionContext</span><span class="o">.</span><span class="n">fromExecutorService</span><span class="o">(</span><span class="n">pool</span><span class="o">)</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="n">receive</span><span class="k">:</span> <span class="kt">Actor.Receive</span> <span class="o">=</span> <span class="o">{</span>
</span><span class='line'>    <span class="c1">// An message that needs some high latency work done</span>
</span><span class='line'>    <span class="k">case</span> <span class="n">m</span><span class="k">:</span> <span class="kt">Message</span> <span class="o">=&gt;</span>
</span><span class='line'>      <span class="k">val</span> <span class="n">future</span> <span class="k">=</span> <span class="nc">Future</span> <span class="o">{</span>
</span><span class='line'>        <span class="c1">// do something with m: Message</span>
</span><span class='line'>      <span class="o">}</span> <span class="o">(</span><span class="n">ctx</span><span class="o">)</span>
</span><span class='line'>
</span><span class='line'>      <span class="n">future</span><span class="o">.</span><span class="n">onComplete</span><span class="o">({</span>
</span><span class='line'>        <span class="k">case</span> <span class="nc">Success</span><span class="o">(</span><span class="n">s</span><span class="o">)</span> <span class="k">=&gt;</span>
</span><span class='line'>          <span class="c1">// do something when the task successfully completed</span>
</span><span class='line'>        <span class="k">case</span> <span class="nc">Failure</span><span class="o">(</span><span class="n">f</span><span class="o">)</span> <span class="k">=&gt;</span>
</span><span class='line'>          <span class="c1">// do something when the task failed</span>
</span><span class='line'>      <span class="o">})</span> <span class="o">(</span><span class="n">ctx</span><span class="o">)</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bro, do you even #chromecast?]]></title>
    <link href="http://blog.abhinav.ca/blog/2013/12/31/bro-do-you-even-chromecast/"/>
    <updated>2013-12-31T20:40:13-05:00</updated>
    <id>http://blog.abhinav.ca/blog/2013/12/31/bro-do-you-even-chromecast</id>
    <content type="html"><![CDATA[<p><img src="http://blog.abhinav.ca/images/tumblr/2013-12-31-1.jpg" width="640" height="640"></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Getting the Titan-0.3.2 Java Driver to work in Scala]]></title>
    <link href="http://blog.abhinav.ca/blog/2013/12/10/getting-the-titan-0-3-2-java-driver-to-work-in-scala/"/>
    <updated>2013-12-10T14:32:38-05:00</updated>
    <id>http://blog.abhinav.ca/blog/2013/12/10/getting-the-titan-0-3-2-java-driver-to-work-in-scala</id>
    <content type="html"><![CDATA[<p>Attempting to use the Java driver for Titan-0.3.2 (the current stable Titan release) with Cassandra v1.2.6 in a Scala project throws the following Astyanax error:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>java.lang.NoSuchMethodError: 
</span><span class='line'>org.apache.cassandra.thrift.TBinaryProtocol: 
</span><span class='line'>method (Lorg/apache/thrift/transport/TTransport;)V not found</span></code></pre></td></tr></table></div></figure>


<p>This can be traced back to a <a href="https://github.com/Netflix/astyanax/issues/352">bug</a> in Astyanax v1.56.37 which was fixed in v1.56.43.
This can be fixed by ensuring that <a href="http://mvnrepository.com/artifact/com.netflix.astyanax/astyanax/1.56.43">this</a> dependency is listed above the Titan driver in your pom.xml or sbt.build.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Setup Ruby (2.x) on Rails (4.x) in 10 lines or less]]></title>
    <link href="http://blog.abhinav.ca/blog/2013/12/01/setup-ruby-2-x-on-rails-4-x-in-10-lines-or-less/"/>
    <updated>2013-12-01T01:38:00-05:00</updated>
    <id>http://blog.abhinav.ca/blog/2013/12/01/setup-ruby-2-x-on-rails-4-x-in-10-lines-or-less</id>
    <content type="html"><![CDATA[<p>As a first time user of Ruby and Rails, I was able to setup a sane environment on Ubuntu Server 12.04 (x64) in less than 10 commands:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nb">cd</span> <span class="nv">$HOME</span>
</span><span class='line'>curl -L https://get.rvm.io | bash
</span><span class='line'><span class="nb">source</span> <span class="nv">$HOME</span>/.rvm/scripts/rvm
</span><span class='line'>rvm requirements
</span><span class='line'>rvm install ruby
</span><span class='line'>rvm use ruby --default
</span><span class='line'>rvm rubygems current
</span><span class='line'>gem install rails
</span></code></pre></td></tr></table></div></figure>


<p>And, if you already have a rails app to run, continue along with:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nb">cd </span>myapp
</span><span class='line'>bundle install
</span><span class='line'>rails server
</span></code></pre></td></tr></table></div></figure>


<p>This will get you up and running with a dev server.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Prevent Facebook from tracking you on the Web]]></title>
    <link href="http://blog.abhinav.ca/blog/2013/11/11/prevent-facebook-from-tracking-you-on-the-web/"/>
    <updated>2013-11-11T12:51:00-05:00</updated>
    <id>http://blog.abhinav.ca/blog/2013/11/11/prevent-facebook-from-tracking-you-on-the-web</id>
    <content type="html"><![CDATA[<p>A simple search for “facebook like button tracking you” turns up a bunch of articles and blog posts about how Facebook is creeping on you wherever you go; even if you’re not signed in or actively clicking their ubiquitous <em>like</em> button (<a href="http://bit.ly/1fwCi5i">example</a>). I’ve come up with a simple solution to the problem.</p>

<p><em>Caveat</em>: This will prevent you from being able to use Facebook.</p>

<p><strong>Step 1</strong>: Add the following entries to your hosts file</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>127.0.0.1 facebook.com
</span><span class='line'>127.0.0.1 www.facebook.com
</span><span class='line'>127.0.0.1 connect.facebook.net
</span></code></pre></td></tr></table></div></figure>


<p>If you’re not familiar with editing your hosts file, <a href="http://bit.ly/17jkvci">here’s a tutorial</a>.</p>

<p><strong>Step 2</strong>: Reboot</p>

<p>And done!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Joda Time with Scala]]></title>
    <link href="http://blog.abhinav.ca/blog/2013/10/08/joda-time-with-scala/"/>
    <updated>2013-10-08T14:25:02-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2013/10/08/joda-time-with-scala</id>
    <content type="html"><![CDATA[<p>When trying to use Joda-Time in a Scala project, I encountered a rather cryptic error:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>scala: error while loading Instant, class file '/Users/asdf/.m2/repository/joda-time/joda-time/2.3/joda-time-2.3.jar(org/joda/time/Instant.class)' is broken
</span><span class='line'>(class java.lang.RuntimeException/bad constant pool tag 9 at byte 48)</span></code></pre></td></tr></table></div></figure>


<p>This can be solved by adding the <a href="http://mvnrepository.com/artifact/org.joda/joda-convert/1.5">joda-convert</a> dependency into Maven/SBT.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[pip install scipy on Ubuntu]]></title>
    <link href="http://blog.abhinav.ca/blog/2013/09/19/pip-install-scipy-on-ubuntu/"/>
    <updated>2013-09-19T01:17:29-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2013/09/19/pip-install-scipy-on-ubuntu</id>
    <content type="html"><![CDATA[<p>On Ubuntu 12.04 Server, a pip install scipy barfs with</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>library dfftpack has Fortran sources but no Fortran compiler found</span></code></pre></td></tr></table></div></figure>


<p>because it wants you to</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>sudo apt-get install libamd2.2.0 libblas3gf libc6 libgcc1 <span class="se">\</span>
</span><span class='line'>libgfortran3 liblapack3gf libumfpack5.4.0 libstdc++6 <span class="se">\</span>
</span><span class='line'>build-essential gfortran python-all-dev <span class="se">\</span>
</span><span class='line'>libatlas-base-dev
</span></code></pre></td></tr></table></div></figure>


<p>and,</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>pip install numpy
</span></code></pre></td></tr></table></div></figure>


<p>before you try to</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>pip install scipy
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[System Architecture planning at @CrowdRiff]]></title>
    <link href="http://blog.abhinav.ca/blog/2013/08/20/system-architecture-planning-at-crowdriff/"/>
    <updated>2013-08-20T16:20:02-04:00</updated>
    <id>http://blog.abhinav.ca/blog/2013/08/20/system-architecture-planning-at-crowdriff</id>
    <content type="html"><![CDATA[<p><img src="http://blog.abhinav.ca/images/tumblr/2013-08-20-1.jpg" width="640" height="640"></p>
]]></content>
  </entry>
  
</feed>
