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

  <title><![CDATA[Larry Price]]></title>
  <link href="https://larry-price.com/atom.xml" rel="self"/>
  <link href="https://larry-price.com/"/>
  <updated>2020-11-03T11:30:15-06:00</updated>
  <id>https://larry-price.com/</id>
  <author>
    <name><![CDATA[Larry Price]]></name>
    <email><![CDATA[larry@larry-price.com]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Getting Started With React Hooks]]></title>
    <link href="https://larry-price.com/blog/2019/02/09/getting-started-with-react-hooks/"/>
    <updated>2019-02-09T13:10:46-06:00</updated>
    <id>https://larry-price.com/blog/2019/02/09/getting-started-with-react-hooks</id>
    <content type="html"><![CDATA[<p><a href="https://reactjs.org/docs/hooks-intro.html">React Hooks</a> are a new feature allowing developers to use state in functional components officially released in <a href="https://reactjs.org/blog/2019/02/06/react-v16.8.0.html">React 16.8</a>. I am in love with the idea of Hooks, so much so that I&rsquo;m giving an introductory talk on the topic at an <a href="https://www.meetup.com/C-U-JavaScript/events/258294308/">upcoming local JavaScript meetup</a>.</p>

<p>All code from this post can be found in a <a href="https://codepen.io/collection/XMoJzy/">codepen collection</a>.</p>

<h3>Functional Components</h3>

<p>A functional component (also sometimes referred to as a &ldquo;stateless&rdquo; component) is a method of defining React components with only a render method. These components still take in readonly props and return some JSX, but until now have had no means to perform any stateful logic. The following is a simple functional component that creates a button for canceling a user&rsquo;s account:</p>

<figure class='code'><figcaption><span>https://codepen.io/larryprice/pen/BMJYwe</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='javascript'><span class='line'><span class="kr">const</span> <span class="nx">CancelAccountDeletion</span> <span class="o">=</span> <span class="p">({</span><span class="nx">onClick</span><span class="p">})</span> <span class="o">=&gt;</span> <span class="p">(</span>
</span><span class='line'>  <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;btn btn-default btn-lg cancel-account-deletion&quot;</span> <span class="nx">onClick</span><span class="o">=</span><span class="p">{</span><span class="nx">onClick</span><span class="p">}</span><span class="o">&gt;</span>
</span><span class='line'>    <span class="o">&lt;</span><span class="nx">span</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;glyphicon glyphicon glyphicon-ban-circle&quot;</span><span class="o">&gt;&lt;</span><span class="err">/span&gt;</span>
</span><span class='line'>    <span class="nx">Cancel</span> <span class="nx">Account</span>
</span><span class='line'>  <span class="o">&lt;</span><span class="err">/button&gt;</span>
</span><span class='line'><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>The component takes in a single prop <code>onClick</code> that is called when the button is clicked.</p>

<h3>Adding Stateful Logic The Old Way</h3>

<p>Let&rsquo;s say that we want to add some stateful logic to that component. Marketing has started complaining that users clicking our current &ldquo;Cancel Account&rdquo; button contribute to a loss of revenue, and we need to slow that loss down to appease investors this quarter. We get design involved and decide to prompt the user several times to confirm their cancellation. We&rsquo;ll need to keep track of the number of clicks and the current prompt in state.</p>

<p>Here&rsquo;s how we might do that on February 5th, 2019, using class components:</p>

<figure class='code'><figcaption><span>https://codepen.io/larryprice/pen/XOgKYd</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>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">const</span> <span class="nx">messages</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;Really?&#39;</span><span class="p">,</span> <span class="s1">&#39;Don\&#39;t leave me!&#39;</span><span class="p">,</span> <span class="s1">&#39;OK, fine!&#39;</span><span class="p">];</span>
</span><span class='line'><span class="kr">class</span> <span class="nx">CancelAccountDeletion</span> <span class="kr">extends</span> <span class="nx">React</span><span class="p">.</span><span class="nx">Component</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">constructor</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kr">super</span><span class="p">(</span><span class="nx">props</span><span class="p">);</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">buttonText</span><span class="o">:</span> <span class="s1">&#39;Cancel&#39;</span><span class="p">,</span>
</span><span class='line'>      <span class="nx">clicks</span><span class="o">:</span> <span class="mi">0</span><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">componentDidUpdate</span><span class="p">(</span><span class="nx">prevProps</span><span class="p">,</span> <span class="nx">prevState</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">prevState</span><span class="p">.</span><span class="nx">clicks</span> <span class="o">!==</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">clicks</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">clicks</span> <span class="o">&lt;</span> <span class="nx">messages</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">((</span><span class="nx">prevState</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">({</span>
</span><span class='line'>          <span class="nx">buttonText</span><span class="o">:</span> <span class="nx">messages</span><span class="p">[</span><span class="nx">prevState</span><span class="p">.</span><span class="nx">clicks</span><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="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">onClick</span><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">render</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">(</span>
</span><span class='line'>      <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;btn btn-default btn-lg cancel-account-deletion&quot;</span>
</span><span class='line'>          <span class="nx">onClick</span><span class="o">=</span><span class="p">{()</span> <span class="o">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">((</span><span class="nx">prevState</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">({</span>
</span><span class='line'>            <span class="nx">clicks</span><span class="o">:</span> <span class="nx">prevState</span><span class="p">.</span><span class="nx">clicks</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
</span><span class='line'>          <span class="p">}))}</span><span class="o">&gt;</span>
</span><span class='line'>        <span class="o">&lt;</span><span class="nx">span</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;glyphicon glyphicon glyphicon-ban-circle&quot;</span><span class="o">&gt;&lt;</span><span class="err">/span&gt;</span>
</span><span class='line'>        <span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">buttonText</span><span class="p">}</span>
</span><span class='line'>      <span class="o">&lt;</span><span class="err">/button&gt;</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></code></pre></td></tr></table></div></figure>


<p>Wow! We&rsquo;ve nearly tripled the size of our original component here. In this stateful world, we needed to extend the <code>React.Component</code> class, define a constructor to set our initial state, update our state when the button is clicked, and add the <code>componentDidUpdate</code> lifecycle method. The <code>componentDidUpdate</code> method is called on every re-render, so we first check to see if the number of <code>clicks</code> changed before taking any action. If it did, we check to see if we have more messages than clicks and update the prompt text; otherwise, we call the original <code>onClick</code> function from our props and, unfortunately for our sales goals, churn another user.</p>

<p>This is a lot of boilerplate and has a tendency to get complex really fast. If only there was another way!</p>

<p>&ldquo;Well, actually, Papa Larry,&rdquo; I hear you interjecting from behind your monitor, &ldquo;we could do this without a lifecycle method and only one piece of state.&rdquo; My dear friend. Yes, this code is slightly contrived so that I can show you all the main features of hooks with a fairly straightforward example. Just keep your susurruses to yourself until after the show.</p>

<h3>Adding Stateful Logic the New Way</h3>

<p>This is where Hooks come into play. Let&rsquo;s fast-forward from early evening in the American Midwest on February 5th, 2019, to late evening, when suddenly React 16.8 was released and it was officially titled &ldquo;The One With Hooks.&rdquo;</p>

<p>Let&rsquo;s take our original functional component and add state with Hooks:</p>

<figure class='code'><figcaption><span>https://codepen.io/larryprice/pen/vbgwGx</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">const</span> <span class="nx">messages</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;Cancel&#39;</span><span class="p">,</span> <span class="s1">&#39;Really?&#39;</span><span class="p">,</span> <span class="s1">&#39;Don\&#39;t leave me!&#39;</span><span class="p">,</span> <span class="s1">&#39;OK, fine!&#39;</span><span class="p">];</span>
</span><span class='line'><span class="kr">const</span> <span class="nx">CancelAccountDeletion</span> <span class="o">=</span> <span class="p">({</span><span class="nx">onClick</span><span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="kr">const</span> <span class="p">[</span><span class="nx">clicks</span><span class="p">,</span> <span class="nx">setClicks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'>  <span class="kr">const</span> <span class="p">[</span><span class="nx">buttonText</span><span class="p">,</span> <span class="nx">setButtonText</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">clicks</span> <span class="o">&lt;</span> <span class="nx">messages</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="nx">setButtonText</span><span class="p">(</span><span class="nx">messages</span><span class="p">[</span><span class="nx">clicks</span><span class="p">]);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">onClick</span><span class="p">();</span>
</span><span class='line'>  <span class="p">},</span> <span class="p">[</span><span class="nx">clicks</span><span class="p">]);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="p">(</span>
</span><span class='line'>    <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">onClick</span><span class="o">=</span><span class="p">{()</span> <span class="o">=&gt;</span> <span class="nx">setClicks</span><span class="p">(</span><span class="nx">clicks</span><span class="o">+</span><span class="mi">1</span><span class="p">)}</span>
</span><span class='line'>        <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;btn btn-default btn-lg cancel-account-deletion&quot;</span><span class="o">&gt;</span>
</span><span class='line'>      <span class="o">&lt;</span><span class="nx">span</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;glyphicon glyphicon glyphicon-ban-circle&quot;</span><span class="o">&gt;&lt;</span><span class="err">/span&gt;</span>
</span><span class='line'>      <span class="p">{</span><span class="nx">buttonText</span><span class="p">}</span>
</span><span class='line'>    <span class="o">&lt;</span><span class="err">/button&gt;</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>Our Hooks implementation is about half as long as our class implementation. I would argue that it&rsquo;s also significantly easier to read. Let&rsquo;s break this down bit-by-bit to discuss each piece of the hooks API:</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='javascript'><span class='line'><span class="kr">const</span> <span class="p">[</span><span class="nx">clicks</span><span class="p">,</span> <span class="nx">setClicks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="kr">const</span> <span class="p">[</span><span class="nx">buttonText</span><span class="p">,</span> <span class="nx">setButtonText</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<p>At the top of our function, we call the <code>useState</code> method to declare two state variables: <code>clicks</code> and <code>buttonText</code>. <code>useState</code> takes in an initial value and returns a state variable and setter method, which we access locally using array destructuring. In this case, we set the initial state of <code>clicks</code> to <code>0</code> and leave <code>buttonText</code> empty.</p>

<p>Behind-the-scenes, React is using our component&rsquo;s scope to create and track these state variables. We <em>must</em> always define these variables in the same order when this function is executed, or we&rsquo;ll get our variables all mixed up and our logic won&rsquo;t make any sense.</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='javascript'><span class='line'><span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">clicks</span> <span class="o">&lt;</span> <span class="nx">messages</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">setButtonText</span><span class="p">(</span><span class="nx">messages</span><span class="p">[</span><span class="nx">clicks</span><span class="p">]);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">onClick</span><span class="p">();</span>
</span><span class='line'><span class="p">},</span> <span class="p">[</span><span class="nx">clicks</span><span class="p">]);</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>useEffect</code> method is essentially a replacement for the <code>componentDidMount</code> and <code>componentDidUpdate</code> lifecycle methods. It takes in a function that will be called after every render. Here we take advantage of closures to test the value of our <code>clicks</code> state variable and use <code>setButtonText</code> to update our <code>buttonText</code> state variable. The second argument to <code>useEffect</code> is an array of state variables to check - if none of the given state variables were changed, the effect will be skipped.</p>

<p>We can call <code>useEffect</code> as many times as we want in our component. This allows us to create a clear separation of concerns if we need to define several different effects.</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="k">return</span> <span class="p">(</span>
</span><span class='line'>  <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">onClick</span><span class="o">=</span><span class="p">{()</span> <span class="o">=&gt;</span> <span class="nx">setClicks</span><span class="p">(</span><span class="nx">clicks</span><span class="o">+</span><span class="mi">1</span><span class="p">)}</span>
</span><span class='line'>      <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;btn btn-default btn-lg cancel-account-deletion&quot;</span><span class="o">&gt;</span>
</span><span class='line'>    <span class="o">&lt;</span><span class="nx">span</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;glyphicon glyphicon glyphicon-ban-circle&quot;</span><span class="o">&gt;&lt;</span><span class="err">/span&gt;</span>
</span><span class='line'>    <span class="p">{</span><span class="nx">buttonText</span><span class="p">}</span>
</span><span class='line'>  <span class="o">&lt;</span><span class="err">/button&gt;</span>
</span><span class='line'><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is our same old render logic, but in this case we&rsquo;re using the <code>setClicks</code> function returned to us by <code>useState</code>.</p>

<h3>Custom Hooks</h3>

<p>Design and marketing like this concept of delaying an action and just changing the text so much that they want to use it all over the site. Now we have stateful logic that needs to be reused. This is where the concept of &ldquo;Custom Hooks&rdquo; comes in:</p>

<figure class='code'><figcaption><span>https://codepen.io/larryprice/pen/GzENrZ</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">const</span> <span class="nx">useTextByCount</span> <span class="o">=</span> <span class="p">(</span><span class="nx">count</span><span class="p">,</span> <span class="nx">messages</span><span class="p">,</span> <span class="nx">onFinished</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="kr">const</span> <span class="p">[</span><span class="nx">text</span><span class="p">,</span> <span class="nx">setText</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="nx">messages</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">count</span> <span class="o">&lt;</span> <span class="nx">messages</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="nx">setText</span><span class="p">(</span><span class="nx">messages</span><span class="p">[</span><span class="nx">count</span><span class="p">]);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">onFinished</span><span class="p">();</span>
</span><span class='line'>  <span class="p">},</span> <span class="p">[</span><span class="nx">count</span><span class="p">]);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="nx">text</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kr">const</span> <span class="nx">messages</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;Cancel&#39;</span><span class="p">,</span> <span class="s1">&#39;Really?&#39;</span><span class="p">,</span> <span class="s1">&#39;Don\&#39;t leave me!&#39;</span><span class="p">,</span> <span class="s1">&#39;OK, fine!&#39;</span><span class="p">]</span>
</span><span class='line'><span class="kr">const</span> <span class="nx">CancelAccountDeletion</span> <span class="o">=</span> <span class="p">({</span><span class="nx">onClick</span><span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="kr">const</span> <span class="p">[</span><span class="nx">clicks</span><span class="p">,</span> <span class="nx">setClicks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'>  <span class="kr">const</span> <span class="nx">buttonText</span> <span class="o">=</span> <span class="nx">useTextByCount</span><span class="p">(</span><span class="nx">clicks</span><span class="p">,</span> <span class="nx">messages</span><span class="p">,</span> <span class="nx">onClick</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="p">(</span>
</span><span class='line'>    <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">onClick</span><span class="o">=</span><span class="p">{()</span> <span class="o">=&gt;</span> <span class="nx">setClicks</span><span class="p">(</span><span class="nx">clicks</span><span class="o">+</span><span class="mi">1</span><span class="p">)}</span>
</span><span class='line'>        <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;btn btn-default btn-lg cancel-account-deletion&quot;</span><span class="o">&gt;</span>
</span><span class='line'>      <span class="o">&lt;</span><span class="nx">span</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;glyphicon glyphicon glyphicon-ban-circle&quot;</span><span class="o">&gt;&lt;</span><span class="err">/span&gt;</span>
</span><span class='line'>      <span class="p">{</span><span class="nx">buttonText</span><span class="p">}</span>
</span><span class='line'>    <span class="o">&lt;</span><span class="err">/button&gt;</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>Here I&rsquo;ve created my own hook called <code>useTextByCount</code> that abstracts away the entire concept of the <code>buttonText</code> state variable. We can use this custom hook in any functional component. Abstracting stateful logic is a tall task in class components, but it&rsquo;s completely natural using Hooks.</p>

<h3>Conclusion</h3>

<p>Hooks are the result of the React maintainers responding to the way React developers want to write code, enabling us to use powerful stateful concepts in a cleaner, functional system. This is a natural next step for the React API, but it&rsquo;s not going to deprecate all your class components. Hooks are completely optional and backwards compatible with current React concepts, so there&rsquo;s no need to make a Jira ticket to refactor all your components tomorrow morning. Hooks are here to help you write new components faster and better, giving you new options when you need to start adding state to that simple button component.</p>

<p>Check out the <a href="https://reactjs.org/docs/hooks-intro.html">Hooks Guide</a> and the <a href="https://reactjs.org/docs/hooks-rules.html">Rules of Hooks</a> for more information.</p>

<p>Happy hooking!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Notes From All Things Open 2018]]></title>
    <link href="https://larry-price.com/blog/2018/10/27/notes-from-all-things-open-2018/"/>
    <updated>2018-10-27T15:56:45-05:00</updated>
    <id>https://larry-price.com/blog/2018/10/27/notes-from-all-things-open-2018</id>
    <content type="html"><![CDATA[<p>This is a brief overview of the talks I sat through while attending <a href="https://allthingsopen.org/">All Things Open 2018</a> in Raleigh, NC.</p>

<h3>Day 1</h3>

<p>First day was okay, but I had trouble finding sessions that interested me and weren&rsquo;t geared towards introductory use.</p>

<h4>Keynotes</h4>

<p>The first keynote, &ldquo;The Next Billion Internet Users&rdquo; by Angela Oduor Lungati, described the rapid rise in internet users in Africa and Asia. Her team made their app mobile-first, as many users only have access to the internet on a smart device. This allowed the app to be used in many different and unexpected situations. Increased connectivity also allows more people to participate in the world of software. According to a recent GitHub survey, Asia is opening the largest number of repos on the site.</p>

<p>Burr Sutter of Red Hat talked about Istio, Red Hat&rsquo;s &ldquo;service mesh&rdquo; system. It&rsquo;s a pretty neat way to manage services with k8s and OpenShift. Users can launch multiple service containers with different features and seamlessly direct traffic to these containers based on certain rules. Users could even direct traffic to a new and old version of a container to determine how a new version interacts with a production environment, with end-users only ever interacting with the old version.</p>

<p>&ldquo;The Next Big Wave&rdquo; (Zaheda Bhorat) mostly focused on how to create a welcoming open-source project that&rsquo;s easy to contribute to, especially in a rapidly more connected world. As usual, READMEs and CONTRIBUTING docs are king, as well as good tutorials, wikis, and getting started guides.</p>

<p>In &ldquo;Design in Open Source&rdquo;, Una Kravets discusssed how Design Thinking can benefit open-source projects. Unfortunately, it&rsquo;s really difficult to get designers to participate.</p>

<h4>Track Sessions</h4>

<p>&ldquo;Turning &lsquo;Wat&rsquo; into &lsquo;Why&rsquo;&rdquo; (Katie McLaughlin) brought up a few idiosyncrasies from many different languages and discussed <em>why</em> the language behaves in that manner. No blame; just curiosity.</p>

<p>&ldquo;Why Modern Apps Need a New Application Server&rdquo; (Nick Shadrin) was an overview of the new Nginx Unit project, iterating on <code>nginx</code> with a focus on microservice architectures. This system actually launches applications, and several libraries/packages/modules are available for things like NodeJS and Go to enable this functionality. Configuration of any language was nearly identical, and defining the number of running instances was really easy through JSON endpoints. Auto-scaling was also included out-of-the-box.</p>

<p>&ldquo;Open Data: Notes from the Field&rdquo; was a panel discussion on how the Research Triangle uses citizens' data to make decisions. Much of the data used is decided upon on a municipal level as opposed to federal or state.</p>

<p>&ldquo;Using Open Source for Large Scale Simulation in Robotic and Autonomous Driving Applications&rdquo; (Nate Koenig) was largely a discussion about tools used to simulate robots. Obviously, testing robots in real life can be dangerous and expensive, so advanced simulation technology is crucial to iterating fast on this kind of hardware.</p>

<p>&ldquo;React Already Did That&rdquo; (Dylan Schiemann) hit on how React has evolved our ecosystem; components and functional programming will leave a permanent mark on JS development. Although React may not be around in 5 years, it is highly likely that the popular frameworks at that time will be fairly similar (think: Vue, Ionic, Svelte). This talk sort of devolved into a discussion of the speaker&rsquo;s &ldquo;competing&rdquo; technology Dojo, which was somewhat of a precursor to React. It also uses TypeScript, which reminds me a lot of the tech stack we use at Granular.</p>

<p>&ldquo;You XSS Your Life! How do we keep failing at security on the web?&rdquo; (David Rogers) was an overview of how easy it is to fall for cross-site scripting attacks in modern web applications. Malicious user input could take down our system or reveal user data, so we should be scrubbing data anywhere it gets entered. Lots of tools available. Although this is touched upon a lot, I know that I&rsquo;m guilty of just taking user input and using it unthinkingly.</p>

<h3>Day 2</h3>

<p>I found more relevant sessions to go to during the second day, which surprised me as normally the &ldquo;last&rdquo; day of a conference is worse than the first.</p>

<h4>Keynotes</h4>

<p>&ldquo;Five Things You Didn&rsquo;t Know Python Can Do!&rdquo; by Nina Zakharenko went over things I already knew Python could do. Python runs important code in all industries, and has found itself indispensable in the world of science.</p>

<p>Babel developer Henry Zhu gave a talk titled &ldquo;Maintainer&rsquo;s Virtual&rdquo; describing the world of full-time open-source development. Zhu left his job and works on Babel based on donations from the community. He talked about the guilt associated with taking breaks when people are donating their money to you, and how that easily leads to burnout. He talked about trying not to put too much pressure on yourself to be constantly contributing.</p>

<p>The final keynote, &ldquo;Money as an Open Protocol&rdquo; by Andreas Antonopoulos, was&hellip; interesting. A dash of conspiracy theory and anarchism made this talk a little uncomfortable. Big banks are not our friends, and this speaker was adamant that we would see the fall of centralized banking in the next 20 years. Bitcoin and friends are the predecessor to a new global digital currency. The choice we&rsquo;ll be facing soon is whether we have a decentralized open currency akin to Bitcoin as our primary form of money or something more insidious such as &ldquo;Facebook Coin&rdquo;, &ldquo;Google Coin&rdquo;, &ldquo;Apple Coin&rdquo;, or &ldquo;America Coin.&rdquo; A fun quote from this talk was &ldquo;The opposite of authority is autonomy.&rdquo; Also &ldquo;If money is the root of all evil, then <code>sudo evil</code>.&rdquo; Although this talk was captivating, it felt like a pitch for a dystopian novel. Crowd ate it up.</p>

<h4>Track Sessions</h4>

<p>Kyle Simpson&rsquo;s &ldquo;Keep Betting on JavaScript&rdquo; was probably my favorite session. Kyle gave a brief history of JavaScript, from its creation through its stagnation to the rapidly-evolving language we all know and love today. JavaScript&rsquo;s failures to change in the 00s was largely due to a lack of unity in the community, ultimately leading to a spec that was thrown away. Other languages began to appear that looked like they would leave JS in the dust. Just as JS was on the brink of death, the community united, new features were specced out, and JS rose from the ashes. Many people still hate on JavaScript, and this is largely due to the fact that they are &ldquo;emotionally attached to the idea that JavaScript sucks.&rdquo; JavaScript is lingua franca in programming; it&rsquo;s readable by developers of many languages, and ideas can easily be expressed. Kyle was very much into progressive web applications, with native apps becoming an unnecessary part of the ecosystem. Every app should have at least one ServiceWorker to guarantee that a tab will continue to exist, even after we get on an airplane. &ldquo;TypeScript is a really intelligent linter&rdquo;, Kyle says, but aside from that, can begin to confuse the world we live in if we use too many extended features. Transforming our code with all of these tools can make debugging harder, and can make it difficult for other developers to figure out what we&rsquo;ve done using &ldquo;View Source.&rdquo; &ldquo;View Source&rdquo; is the ultimate tool in a new developer&rsquo;s toolkit, allowing them to see how a site works and helping them develop new ideas. Kyle was weary of many of the new JavaScript features that are machine-centric; code features that will only be used by libraries and generators and never by an everyday programmer. Kyle insists that we should focus on developers first. Even WebAssembly and simimlar ideas are going to make web development a more complicated landscape to enter. Kyle started early and ended late. Further reading: Alan Kay, Douglas Englebart, Tom Dale.</p>

<p>&ldquo;Cross-Platform Desktop Apps with Electron&rdquo; (David Neal) was an introductory guide to using Electron, the cross-platform desktop UI technology behind Atom, VSCode, and the Slack desktop app. Starting in Electron seems easier than I expected. Architecture is similar to developing for the web, where we have server-side code and client-side code. It&rsquo;s better to make calls to the server than to run on the UI thread. Pretty much anything that you can install with npm can readily be used in Electron, including UI frameworks such as React and testing tools such as mocha.</p>

<p>I watched some lightning talks during lunch. Raspberry Pi celebrates their 6th year, something something Blockchain databases, jump-starting an open-source career via blogging or speaking, examples of unconscious bias in AI datasets, all the wrong ways to pronounce &ldquo;kubectl&rdquo;, more on Red Hat&rsquo;s Istio service mesh framework, and ideas for replacing <code>docker</code> with other container tools.</p>

<p>&ldquo;Framework Free – Building a Single Page Application Without a JS Framework&rdquo; (Ryan Miller) described the way we used to make websites in 2013 without frameworks, but with all the nice HTML5 features. It&rsquo;s somewhat important to know how all of these things work under the covers, especially if you have to debug in the browser. It&rsquo;s not always necessary to have a big, hefty framework. I was somewhat horrified by the number of people in the audience who didn&rsquo;t know what jQuery was.</p>

<p>In &ldquo;Intro to SVG&rdquo;, Tanner Hodges explained the basics of SVGs, when to use them, and when to seek alternatives. Interesting cases included textured content (which rendered significantly smaller as a PNG over an SVG), content that included text (which needed to be checked to verify that the text was rendered as native SVG elements), and photography (which, when rendered to SVG, literally included a data hash of the original image at high resolution, creating a massive file). He also touted the importance of new standards such as <code>webp</code> and <code>webv</code> when displaying content on the web.</p>

<p>In &ldquo;WTH is JWT&rdquo;, Joel Lord broke down how JWTs are constructed by combining the encryption method, the payload (basic user information), and a secret key. Although the key can be deserialized and parsed to get to the information, the secret at the end is determined by hashing the key and the payload, so would-be attackers cannot simply change the JWT to gain access to the system without knowing the secret key. Of course, more security measures are necessary to keep intruders from gaining access, such as encrypted sessions and auth servers. The JWT Spec is still in the <a href="https://tools.ietf.org/html/rfc7519">proposal period</a>, so its definition may still change before finalization.</p>

<h3>Conclusion</h3>

<p>Pretty good conference. I made a few interesting connections. I learned that a lot of people are in love with Vue right now, TypeScript is still popular, and microservices are the only way to build an application. My biggest complaint was that coffee was hard to come by.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to Use getDerivedStateFromProps in React 16.3+]]></title>
    <link href="https://larry-price.com/blog/2018/06/27/how-to-use-getderivedstatefromprops-in-react-16-dot-3-plus/"/>
    <updated>2018-06-27T15:12:09-05:00</updated>
    <id>https://larry-price.com/blog/2018/06/27/how-to-use-getderivedstatefromprops-in-react-16-dot-3-plus</id>
    <content type="html"><![CDATA[<p>From <a href="https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html">a blog post in late March 2018</a>, it was announced that the React lifecycle methods <code>componentWillReceiveProps</code>, <code>componentWillMount</code>, and <code>componentWillUpdate</code> will be deprecated in a future version of React. This is because of the eventual migration of React to async rendering; these lifecycle methods will become unreliable when async rendering is made default.</p>

<p>In place of these methods, the new <strong>static</strong> method <code>getDerivedStateFromProps</code> was introduced. My team and I struggled at first in wrapping our heads around how to migrate our many uses of <code>componentWillReceiveProps</code> to this new method. It&rsquo;s generally easier than you think, but you need to keep in mind that the new method is <strong>static</strong>, and therefore does not have access to the <code>this</code> context that the old lifecycle methods provided.</p>

<p><code>getDerivedStateFromProps</code> is invoked every time a component is rendered. It takes in two arguments: the next <code>props</code> object (which may be the same as the previous object) and the previous <code>state</code> object of the component in question. When implementing this method, we need to return the changes to our component <code>state</code> or <code>null</code> (or <code>{}</code>) if no changes need to be made.</p>

<h3>componentWillReceiveProps</h3>

<p>Here&rsquo;s a pattern we were using in many components throughout our codebase:</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='javascript'><span class='line'><span class="nx">componentWillReceiveProps</span><span class="p">(</span><span class="nx">nextProps</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">nextProps</span><span class="p">.</span><span class="nx">selectedTab</span> <span class="o">!==</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">selectedTab</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="k">return</span> <span class="p">{</span><span class="nx">selectedTab</span><span class="o">:</span> <span class="nx">nextProps</span><span class="p">.</span><span class="nx">selectedTab</span><span class="p">}</span> <span class="p">})</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>This lifecycle method fired when we were about to receive new <code>props</code> in our component, passing in the new value as the first argument. We needed to check whether the new <code>props</code> indicated a change in the state of our tab bar, which we stored in <code>state</code>. This is one of the simplest patterns to address with <code>getDerivedStateFromProps</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>
<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="kr">static</span> <span class="nx">getDerivedStateFromProps</span><span class="p">(</span><span class="nx">nextProps</span><span class="p">,</span> <span class="nx">prevState</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">nextProps</span><span class="p">.</span><span class="nx">selectedTab</span> <span class="o">===</span> <span class="nx">prevState</span><span class="p">.</span><span class="nx">selectedTab</span>
</span><span class='line'>    <span class="o">?</span> <span class="p">{}</span>
</span><span class='line'>    <span class="o">:</span> <span class="p">{</span><span class="nx">selectedTab</span><span class="o">:</span> <span class="nx">nextProps</span><span class="p">.</span><span class="nx">selectedTab</span><span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This code works in exactly the same way, but, since it&rsquo;s <strong>static</strong>, we no longer use the context provided by <code>this</code>. Instead, we return any state changes. In this case, I&rsquo;ve returned an empty object (<code>{}</code>) to indicate no state change when the tabs are identical; otherwise, I return an object with the new <code>selectedTab</code> value.</p>

<p>Sometimes you may have to perform some operations on the new <code>props</code>, but then you can still just compare the result to your previous state to figure out if anything changed. There may be other areas where you need to store some extra state duplicating your old <code>props</code> to make this work, but that may also be an indication that you need to use an alternative method.</p>

<h3>componentWillMount</h3>

<p>We also needed to replace calls to <code>componentWillMount</code>. I found that these calls were usually directly replaceable by <code>componentDidMount</code>, which will allow your component to perform an initial render and then execute blocking tasks. This may also require adding some loading-style capacity to your component, but will be better than a hanging app.</p>

<p>Here&rsquo;s an example of a <code>componentWillMount</code> we had originally that blocked render until after an API call was made:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">componentWillMount</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">loading</span><span class="o">:</span> <span class="s1">&#39;Loading tool info&#39;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">})</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">getTool</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">match</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">id</span><span class="p">).</span><span class="nx">then</span><span class="p">((</span><span class="nx">res</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">tool</span><span class="o">:</span> <span class="nx">res</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">loading</span><span class="o">:</span> <span class="kc">null</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 class="k">catch</span><span class="p">((</span><span class="nx">err</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">api</span><span class="p">.</span><span class="nx">errors</span><span class="p">.</span><span class="nx">put</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">loading</span><span class="o">:</span> <span class="kc">null</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 class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Afterwards, I changed the state to show the component as loading on initial render and replaced the <code>componentWillMount</code> with <code>componentDidMount</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>
<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='javascript'><span class='line'><span class="nx">state</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">tool</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">loading</span><span class="o">:</span> <span class="s1">&#39;Loading tool info&#39;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">componentDidMount</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">getTool</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">match</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">id</span><span class="p">).</span><span class="nx">then</span><span class="p">((</span><span class="nx">res</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="k">return</span> <span class="p">{</span><span class="nx">tool</span><span class="o">:</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">loading</span><span class="o">:</span> <span class="kc">null</span><span class="p">}</span> <span class="p">})</span>
</span><span class='line'>  <span class="p">}).</span><span class="k">catch</span><span class="p">((</span><span class="nx">err</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">api</span><span class="p">.</span><span class="nx">errors</span><span class="p">.</span><span class="nx">put</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="k">return</span> <span class="p">{</span><span class="nx">loading</span><span class="o">:</span> <span class="kc">null</span><span class="p">}</span> <span class="p">})</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>


<h3>componentWillUpdate</h3>

<p>Very similar to the methods discussed above, <code>componentWillUpdate</code> is invoked when a component is about to receive new props and the <code>render</code> method is definitely going to be called. Here&rsquo;s an example of something we were doing previously:</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='javascript'><span class='line'><span class="nx">componentWillUpdate</span><span class="p">(</span><span class="nx">nextProps</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">nextProps</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">isLogged</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">nextProps</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">authenticating</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">context</span><span class="p">.</span><span class="nx">router</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</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>And, replacing that usage with <code>componentDidUpdate</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>
<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">componentDidUpdate</span><span class="p">(</span><span class="cm">/*prevProps, prevState*/</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">isLogged</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">authenticating</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">context</span><span class="p">.</span><span class="nx">router</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</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><code>componentDidUpdate</code> is similar to <code>componentDidMount</code> except that is caused after a change in state or props occurs instead of just on initial mount. As opposed to <code>getDerivedStateFromProps</code>, we have access to the context provided by <code>this</code>. Note that this method also has arguments for <code>prevProps</code> and <code>prevState</code>, which provides the previous versions of the component&rsquo;s <code>props</code> and <code>state</code> for comparison to the current values.</p>

<h3>Conclusion</h3>

<p>The deprecation of these lifecycle methods won&rsquo;t happen until React 17, but it&rsquo;s always good to plan ahead. Many of the ways my team was using these deprecated methods could be considered an anti-pattern, and I suspect that your team may be in the same predicament.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Quick Start to Vendor Go Dependencies With Govendor]]></title>
    <link href="https://larry-price.com/blog/2018/04/26/quick-start-to-vendor-go-dependencies-with-govendor/"/>
    <updated>2018-04-26T19:34:04-05:00</updated>
    <id>https://larry-price.com/blog/2018/04/26/quick-start-to-vendor-go-dependencies-with-govendor</id>
    <content type="html"><![CDATA[<p>I recently spent a few days adapting my <a href="https://www.packtpub.com/web-development/go-web-development-video">Go for Web Development video series</a> into a text-based course. In doing so, I had the chance to investigate some of the new vendoring tools available in Go. As of Go 1.5, &ldquo;vendoring&rdquo; dependencies has become the norm. Vendoring means tracking your dependencies and their versions and including those dependencies as part of your project.</p>

<p>In particular, I explored the uses of the <a href="https://github.com/kardianos/govendor">govendor</a> package, mostly because it&rsquo;s supported by default by Heroku. The docs on the GitHub are a lot more thorough than what I&rsquo;ll go over here.</p>

<p><code>govendor</code> is easily installed within the go ecosystem. Assuming that <code>$GOPATH/bin</code> is in your path:</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='bash'><span class='line'><span class="nv">$ </span>go get -u github.com/kardianos/govendor
</span><span class='line'><span class="nv">$ </span>which govendor
</span><span class='line'>/home/lrp/go/bin/govendor
</span></code></pre></td></tr></table></div></figure>


<p>Now we just initialize the <code>govendor</code> directory and start installing dependencies. The <code>govendor fetch</code> command is pretty much all you&rsquo;ll need:</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='bash'><span class='line'><span class="nv">$ </span>govendor init
</span><span class='line'><span class="nv">$ </span>govendor fetch github.com/jinzhu/gorm
</span><span class='line'><span class="nv">$ </span>govendor fetch golang.org/x/crypto/bcrypt
</span></code></pre></td></tr></table></div></figure>


<p><code>init</code> will create a <code>vendor</code> directory in your project path. Go will check this directory for any packages as though they were in your <code>$GOPATH/src</code> directory. The <code>fetch</code> calls will add new packages or update the given package in your <code>vendor</code> directory; in this case, I&rsquo;ve fetched the latest versions of <code>gorm</code> and <code>bcrypt</code>.</p>

<p>This might seem painful, but the thing to do next is to commit everything in the vendor directory to your repository. Now you have it forever! This means that anyone who wants to run this version of your code in the future doesn&rsquo;t have to worry about dependency versions and can instantly run your package with a valid go install.</p>

<p>If you don&rsquo;t want to add all these packages to your repository, I don&rsquo;t blame you. You can get around this by committing just your <code>vendor/vendor.json</code> file and then using <code>govendor sync</code> to install the missing packages after downloading your source code. This should be familiar to anyone who&rsquo;s used <code>bundler</code> in ruby, <code>virtualenv</code> in python, or <code>npm</code> in Node.JS. If you&rsquo;re using git, you&rsquo;ll want a <code>.gitignore</code> with the following:</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='bash'><span class='line'>vendor/*
</span><span class='line'>!vendor/vendor.json
</span></code></pre></td></tr></table></div></figure>


<p>This will ignore everything in <code>vendor/</code> except for the <code>vendor.json</code> file which lists all your packages and their corresponding versions. Now, to install any packages from <code>vendor.json</code> that you don&rsquo;t already have in your <code>vendor</code> directory:</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'><span class="nv">$ </span>govendor sync
</span></code></pre></td></tr></table></div></figure>


<p><code>govendor</code> is a pretty powerful tool for vendoring your go dependencies and getting your application Heroku-ready, and I recommend <a href="https://github.com/kardianos/govendor">checking out the docs</a> for a more advanced overview. There are also many other vendoring options available, including an official go vendoring tool called <a href="https://github.com/golang/dep">dep</a> that works with go 1.9+. <code>dep</code> will most definitely play a big role in refining the ideas that these third-party tools have created and the go ecosystem will become more stable.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Redirecting to Your Main Site With Heroku]]></title>
    <link href="https://larry-price.com/blog/2018/04/25/redirecting-to-your-main-site-with-heroku/"/>
    <updated>2018-04-25T20:52:19-05:00</updated>
    <id>https://larry-price.com/blog/2018/04/25/redirecting-to-your-main-site-with-heroku</id>
    <content type="html"><![CDATA[<p>We have a lot of domains that we want to redirect to the same server, but we use a DNS service that does not allow doing a domain forward, and we&rsquo;re not allowed to upgrade. I wanted to do this in the simplest way possible, so I created a workaround using a PHP script and Heroku. The source discussed in detail in this post is available on GitHub: <a href="https://github.com/larryprice/simple-heroku-redirect-app">https://github.com/larryprice/simple-heroku-redirect-app</a>.</p>

<p>The goal here is for users to visit a page and then be immediately redirected to the new site. I&rsquo;ve defined two environment variables to be used in this project: <code>SITENAME</code>, a human-readable name for our website, and <code>SITEURL</code>, the full URL that we actually want the user to end up on. I&rsquo;ve defined a PHP file called <code>index.php</code>:</p>

<figure class='code'><figcaption><span>index.php</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>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="o">&lt;!</span><span class="nx">DOCTYPE</span> <span class="nx">html</span><span class="o">&gt;</span>
</span><span class='line'><span class="o">&lt;</span><span class="nx">html</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="o">&lt;</span><span class="nx">head</span><span class="o">&gt;</span>
</span><span class='line'>    <span class="o">&lt;</span><span class="nx">title</span><span class="o">&gt;&lt;?</span><span class="nx">php</span> <span class="k">echo</span> <span class="nb">getenv</span><span class="p">(</span><span class="s1">&#39;SITENAME&#39;</span><span class="p">)</span> <span class="cp">?&gt;</span><span class="x"> - You will be redirected shortly...&lt;/title&gt;</span>
</span><span class='line'><span class="x">    &lt;meta http-equiv=&quot;refresh&quot; content=&quot;0;URL=&#39;</span><span class="cp">&lt;?php</span> <span class="k">echo</span> <span class="nb">getenv</span><span class="p">(</span><span class="s1">&#39;SITEURL&#39;</span><span class="p">)</span> <span class="cp">?&gt;</span><span class="x">&#39;&quot; /&gt;</span>
</span><span class='line'><span class="x">  &lt;/head&gt;</span>
</span><span class='line'><span class="x">  &lt;body&gt;</span>
</span><span class='line'><span class="x">    &lt;p&gt;Please visit the official </span><span class="cp">&lt;?php</span> <span class="k">echo</span> <span class="nb">getenv</span><span class="p">(</span><span class="s1">&#39;SITENAME&#39;</span><span class="p">)</span> <span class="cp">?&gt;</span><span class="x"> site at &lt;a href=&quot;</span><span class="cp">&lt;?php</span> <span class="k">echo</span> <span class="nb">getenv</span><span class="p">(</span><span class="s1">&#39;SITEURL&#39;</span><span class="p">)</span> <span class="cp">?&gt;</span><span class="x">&quot;&gt;</span><span class="cp">&lt;?php</span> <span class="k">echo</span> <span class="nb">getenv</span><span class="p">(</span><span class="s1">&#39;SITEURL&#39;</span><span class="p">)</span> <span class="cp">?&gt;</span><span class="x">&lt;/a&gt;.&lt;/p&gt;</span>
</span><span class='line'><span class="x">  &lt;/body&gt;</span>
</span><span class='line'><span class="x">&lt;/html&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The important piece here is the <code>&lt;meta&gt;</code> tag, which actually does the redirect for us. The only PHP code here are <code>echo getenv</code> commands that render our environment variables in the template. Since I&rsquo;m a PHP novice, there may be a better way to do this, but the <code>echo</code> works just fine.</p>

<p>We also need to tell Apache how to serve the application. We want to match any routes and render our <code>index.php</code>. So we create an <code>.htcaccess</code> file:</p>

<figure class='code'><figcaption><span>.htaccess</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='sh'><span class='line'>RewriteEngine on
</span><span class='line'>RewriteRule . index.php <span class="o">[</span>L<span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>To satisfy Heroku, we need to list the dependencies for our PHP application. Fortunately for us, we don&rsquo;t have any dependencies that Heroku does not provide by default. We&rsquo;ll just create a <code>composer.json</code> file in the root of our project with an empty object:</p>

<figure class='code'><figcaption><span>composer.json</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='json'><span class='line'><span class="p">{}</span>
</span></code></pre></td></tr></table></div></figure>


<p>That&rsquo;s everything we need. You could recreate the project, but you could also just pull down the project listed above and push it up to Heroku:</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='bash'><span class='line'><span class="nv">$ </span>git clone https://github.com/larryprice/simple-heroku-redirect-app.git
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>simple-heroku-redirect-app
</span><span class='line'><span class="nv">$ </span>heroku create
</span><span class='line'><span class="nv">$ </span>git push heroku master
</span></code></pre></td></tr></table></div></figure>


<p>With your application available on Heroku, we still need to set the environment variables described earlier as <a href="https://devcenter.heroku.com/articles/config-vars">config variables</a>:</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='bash'><span class='line'><span class="nv">$ </span>heroku config:set <span class="nv">SITENAME</span><span class="o">=</span>yourgooddomain.com
</span><span class='line'><span class="nv">$ </span>heroku config:set <span class="s2">&quot;SITEURL=Your Good Domain&#39;s Website Name&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now tell Heroku all <a href="https://devcenter.heroku.com/articles/custom-domains">the domains</a> that will be accessing this application. These are the domains you want users <em>not</em> to use:</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='bash'><span class='line'><span class="nv">$ </span>heroku domains:add yourbaddomain.com
</span><span class='line'><span class="nv">$ </span>heroku domains:add www.yourbaddomain.com
</span></code></pre></td></tr></table></div></figure>


<p>Now you just need to add the records indicated by the above command to your DNS records. These will probably be CNAME records pointing from <code>@</code> to <code>yourbaddomain.com.herokudns.com</code> or <code>www</code> to <code>yourbaddomain.com.herokudns.com</code>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Async and Await - a New Promise]]></title>
    <link href="https://larry-price.com/blog/2018/02/02/async-and-await-a-new-promise/"/>
    <updated>2018-02-02T15:19:48-06:00</updated>
    <id>https://larry-price.com/blog/2018/02/02/async-and-await-a-new-promise</id>
    <content type="html"><![CDATA[<p>In my <a href="https://larry-price.com/blog/2017/09/14/promise-youll-call-back/">last post</a>, I discussed the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">ES2015 concept of a <code>Promise</code></a>. A <code>Promise</code> provides a simplified mechanism for performing asynchronous work in JavaScript without using the classic <code>setTimeout</code>-callback approach. Seeing as it&rsquo;s been about 4 months since my previous post, a new asynchronous concept is on the rise as part of the <a href="https://tc39.github.io/ecma262/2017/#sec-async-function-definitions">ES2017 specification</a>: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function"><code>async</code> and <code>await</code></a>.</p>

<p>I became aware of <code>async</code> and <code>await</code> after reading <a href="https://davidwalsh.name/async-await">David Walsh&rsquo;s blog</a>, at which point I disregarded the new features as being &ldquo;too soon&rdquo; and &ldquo;not different enough&rdquo; from a <code>Promise</code> to warrant a second thought. Then, yesterday, I used them, and my life was, once again, forever changed.</p>

<p><code>await</code> is used to essentially wait for a <code>Promise</code> to finish. Instead of using a callback with a <code>then</code> clause, <code>await</code> allows you to perform the action and/or store the result like you&rsquo;re within a synchronous function.</p>

<p><code>async</code> is a keyword identifier used on functions to specify that that function will use <code>await</code>. Try to call <code>await</code> in a function not labeled as <code>async</code> and you&rsquo;re going to have a bad time. Any <code>async</code> function returns a <code>Promise</code>.</p>

<p>Let&rsquo;s see an example:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">getFirstName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;Charles&#39;</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">getMiddleName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;Entertainment&#39;</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">getLastName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;Cheese&#39;</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">getName</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="kr">const</span> <span class="nx">first</span> <span class="o">=</span> <span class="nx">await</span> <span class="nx">getFirstName</span><span class="p">();</span>
</span><span class='line'>  <span class="kr">const</span> <span class="nx">middle</span> <span class="o">=</span> <span class="nx">await</span> <span class="nx">getMiddleName</span><span class="p">();</span>
</span><span class='line'>  <span class="kr">const</span> <span class="nx">last</span> <span class="o">=</span> <span class="nx">await</span> <span class="nx">getLastName</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="err">`</span><span class="nx">$</span><span class="p">{</span><span class="nx">first</span><span class="p">}</span> <span class="nx">$</span><span class="p">{</span><span class="nx">middle</span><span class="p">}</span> <span class="nx">$</span><span class="p">{</span><span class="nx">last</span><span class="p">}</span><span class="err">`</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">getName</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">name</span><span class="p">)</span> <span class="o">=&gt;</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="nx">name</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</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;My next guest needs no introduction:&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Result:</span>
</span><span class='line'><span class="c1">//   My next guest needs no introduction:</span>
</span><span class='line'><span class="c1">//   Charles Entertainment Cheese</span>
</span></code></pre></td></tr></table></div></figure>


<p>We have three functions which each return a <code>Promise</code>, and an <code>async</code> function which calls those functions sequentially and uses the results to construct a string. We call the <code>getName</code> function (which is <code>async</code> and therefore returns a <code>Promise</code>) and log the results. Our last command logs a special message. Due to the asynchronous nature of the <code>getName</code> function, our special message is logged first, and then the result of <code>getName</code>.</p>

<p>This comes in handy when you&rsquo;re depending on the results of a <code>Promise</code> to do some work or pass into another asynchronous call. But, in the case of our <code>getName</code> function above, we could be getting all three of the names at once. This calls for the brilliant <code>Promise.all</code> method, which can also be used with <code>async</code>. Let&rsquo;s modify our sub-name functions to all use <code>async</code> and then fetch them all at once:</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='javascript'><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">getFirstName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="s1">&#39;Charles&#39;</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">getMiddleName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="s1">&#39;Entertainment&#39;</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">getLastName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="s1">&#39;Cheese&#39;</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">getName</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="kr">const</span> <span class="nx">names</span> <span class="o">=</span> <span class="nx">await</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">([</span><span class="nx">getFirstName</span><span class="p">(),</span> <span class="nx">getMiddleName</span><span class="p">(),</span> <span class="nx">getLastName</span><span class="p">()]);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="err">`</span><span class="nx">$</span><span class="p">{</span><span class="nx">names</span><span class="p">[</span><span class="mi">0</span><span class="p">]}</span> <span class="nx">$</span><span class="p">{</span><span class="nx">names</span><span class="p">[</span><span class="mi">1</span><span class="p">]}</span> <span class="nx">$</span><span class="p">{</span><span class="nx">names</span><span class="p">[</span><span class="mi">2</span><span class="p">]}</span><span class="err">`</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">getName</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">name</span><span class="p">)</span> <span class="o">=&gt;</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="nx">name</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</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;My next guest needs no introduction:&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Result:</span>
</span><span class='line'><span class="c1">//   My next guest needs no introduction:</span>
</span><span class='line'><span class="c1">//   Charles Entertainment Cheese</span>
</span></code></pre></td></tr></table></div></figure>


<p>Since an <code>async</code> function just returns a <code>Promise</code>, we can directly use (and even inter-mix) <code>async</code> functions inside <code>Promise.all</code>, and the results come back in an ordered array.</p>

<p>OK, what if we want to fire off some long-running task and do some other work in the meantime? We can defer our use of <code>await</code> until after we&rsquo;ve performed all the intermediate work:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">getFirstName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="s1">&#39;Charles&#39;</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">getMiddleName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="s1">&#39;Entertainment&#39;</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">getLastName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="s1">&#39;Cheese&#39;</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">getName</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="kr">const</span> <span class="nx">first</span>  <span class="o">=</span> <span class="nx">getFirstName</span><span class="p">();</span>  <span class="c1">// first, middle, and last will all</span>
</span><span class='line'>  <span class="kr">const</span> <span class="nx">middle</span> <span class="o">=</span> <span class="nx">getMiddleName</span><span class="p">();</span> <span class="c1">// be pending Promises at this</span>
</span><span class='line'>  <span class="kr">const</span> <span class="nx">last</span>   <span class="o">=</span> <span class="nx">getLastName</span><span class="p">();</span>   <span class="c1">// point, to be resolved in time</span>
</span><span class='line'>
</span><span class='line'>  <span class="kr">const</span> <span class="nx">title</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">&gt;</span> <span class="p">.</span><span class="mi">5</span> <span class="o">?</span> <span class="s1">&#39;Sr.&#39;</span> <span class="o">:</span> <span class="s1">&#39;Esq.&#39;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="err">`</span><span class="nx">$</span><span class="p">{</span><span class="nx">await</span> <span class="nx">first</span><span class="p">}</span> <span class="nx">$</span><span class="p">{</span><span class="nx">await</span> <span class="nx">middle</span><span class="p">}</span> <span class="nx">$</span><span class="p">{</span><span class="nx">await</span> <span class="nx">last</span><span class="p">},</span> <span class="nx">$</span><span class="p">{</span><span class="nx">title</span><span class="p">}</span><span class="err">`</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">getName</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">name</span><span class="p">)</span> <span class="o">=&gt;</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="nx">name</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</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;My next guest needs no introduction:&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Result will be quasi-random:</span>
</span><span class='line'><span class="c1">//   My next guest needs no introduction:</span>
</span><span class='line'><span class="c1">//   Charles Entertainment Cheese, (Esq.|Sr.)</span>
</span></code></pre></td></tr></table></div></figure>


<p>This example reiterates that you can use <code>async</code> functions just like you would a <code>Promise</code>, but with the added benefit of using <code>await</code> to wait for the results when necessary.</p>

<p>I know what you&rsquo;re thinking: &ldquo;All these positives, Larry! Is there nothing negative about <code>async</code>/<code>await</code>?&rdquo; As always, there are a couple of pitfalls to using these functions. The biggest nuisance for me is the loss of the <code>catch</code> block when converting from a <code>Promise</code> chain. In order to catch errors with <code>async</code>/<code>await</code>, you&rsquo;ll have to go back to traditional <code>try/catch</code> statements:</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='javascript'><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">checkStatus</span><span class="p">()</span> <span class="p">{</span> <span class="k">throw</span> <span class="s1">&#39;The Cheese is displeased!&#39;</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">async</span> <span class="kd">function</span> <span class="nx">checks</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">try</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">await</span> <span class="nx">checkStatus</span><span class="p">();</span>
</span><span class='line'>    <span class="k">return</span> <span class="s1">&#39;No problems.&#39;</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">e</span><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">checks</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">status</span><span class="p">)</span> <span class="o">=&gt;</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="nx">status</span><span class="p">)</span>
</span><span class='line'><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;Current status:&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Result will be quasi-random:</span>
</span><span class='line'><span class="c1">//   Current status:</span>
</span><span class='line'><span class="c1">//   The Cheese is displeased!</span>
</span></code></pre></td></tr></table></div></figure>


<p>The only other real downside is that <code>async</code> and <code>await</code> may not be fully supported in your users' browsers or your version of Node.JS. There are plenty of ways to get around this with Babel and polyfills, but, to be honest, I dedicated a large chunk of time yesterday afternoon to upgrading all of our libraries and babel versions to get this to work properly everywhere. Your mileage may vary, and, if you&rsquo;re reading this 6 months from when it was posted, I&rsquo;m sure it will be available by default in any implementations of ECMAScript.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Promise You'll Call Back: A Guide to the Javascript Promise Class]]></title>
    <link href="https://larry-price.com/blog/2017/09/14/promise-youll-call-back/"/>
    <updated>2017-09-14T21:45:08-05:00</updated>
    <id>https://larry-price.com/blog/2017/09/14/promise-youll-call-back</id>
    <content type="html"><![CDATA[<p><em>This article introduces the Javascript Promise class, and how to use a Promise to perform asynchronous work. At the end of this post, you&rsquo;ll have been exposed to the most important components of the Promise API.</em></p>

<p>Introduced in the <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-promise-objects">ES2015 specification</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">MDN</a> dryly describes a <code>Promise</code> as:</p>

<blockquote><p>The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.</p></blockquote>

<p>But&hellip; what exactly does that entail? How does it differ from just using callbacks?</p>

<p>Let&rsquo;s start with a simple example. If I want to perform an operation asynchronously, traditionally I would use <code>setTimeout</code> to do work after the main thread has finished and use a callback parameter to let the caller utilize the results. For example:</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='javascript'><span class='line'><span class="kr">const</span> <span class="nx">someAsyncTask</span> <span class="o">=</span> <span class="p">(</span><span class="nx">after</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">after</span><span class="p">(</span><span class="s1">&#39;the task is happening&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</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;before calling someAsyncTask&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">someAsyncTask</span><span class="p">((</span><span class="nx">result</span><span class="p">)</span> <span class="o">=&gt;</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="nx">result</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</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;after calling someAsyncTask&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Try running this yourself with <code>node</code>, and you&rsquo;ll see that &lsquo;before&hellip;&rsquo; and &lsquo;after&hellip;&rsquo; are printed followed by &lsquo;the task is happening&rsquo;.</p>

<p>This is perfectly valid code, but it&rsquo;s just so <em>unnatural</em> to handle asynchronous tasks this way. There&rsquo;s no standard to which parameter should be the callback, and there&rsquo;s no standard to what arguments will be passed back to a given callback. Let&rsquo;s take a look at the same situation using the new <code>Promise</code> class:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">const</span> <span class="nx">someAsyncTask</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;the task is happening&#39;</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</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;before calling someAsyncTask&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">someAsyncTask</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">result</span><span class="p">)</span> <span class="o">=&gt;</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="nx">result</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</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;after calling someAsyncTask&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Let&rsquo;s walk through this. In <code>someAsyncTask</code>, we&rsquo;re now returning a call to <code>Promise.resolve</code> with our result. We call <code>then</code> on the result of <code>someAsyncTask</code> and then handle the results. <code>Promise.resolve</code> is returning a resolved <code>Promise</code>, which is run asynchronously after the main thread finishes its initial work (the final <code>console.log</code>, in this case).</p>

<p>Immediately, this feels a lot cleaner to me, but this is a really simple example.</p>

<p>Think about a situation where you need to perform multiple asynchronous callbacks that each depend on the results of the last callback. Here&rsquo;s an example implementation using callbacks;</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">const</span> <span class="nx">getFirstName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">callback</span><span class="p">(</span><span class="s1">&#39;Harry&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kr">const</span> <span class="nx">getLastName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">callback</span><span class="p">(</span><span class="s1">&#39;Potter&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kr">const</span> <span class="nx">concatName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">callback</span><span class="p">(</span><span class="err">`</span><span class="nx">$</span><span class="p">{</span><span class="nx">first</span><span class="p">}</span> <span class="nx">$</span><span class="p">{</span><span class="nx">last</span><span class="p">}</span><span class="err">`</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">getFirstName</span><span class="p">((</span><span class="nx">first</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">getLastName</span><span class="p">((</span><span class="nx">last</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">concatName</span><span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">,</span> <span class="p">(</span><span class="nx">fullname</span><span class="p">)</span> <span class="o">=&gt;</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="nx">fullname</span><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 class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>I think we can all agree that this is not friendly code. What makes a <code>Promise</code> truly special is its natural chainability. As long as we keep returning <code>Promise</code> objects, we can keep calling <code>then</code> on the results:</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='javascript'><span class='line'><span class="kr">const</span> <span class="nx">getFirstName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;Harry&#39;</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kr">const</span> <span class="nx">getLastName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;Potter&#39;</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kr">const</span> <span class="nx">concatName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="err">`</span><span class="nx">$</span><span class="p">{</span><span class="nx">first</span><span class="p">}</span> <span class="nx">$</span><span class="p">{</span><span class="nx">last</span><span class="p">}</span><span class="err">`</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">getFirstName</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">first</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">getLastName</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">last</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">concatName</span><span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">}).</span><span class="nx">then</span><span class="p">((</span><span class="nx">fullname</span><span class="p">)</span> <span class="o">=&gt;</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="nx">fullname</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Since <code>concatName</code> is dependent on the result of both <code>getFirstName</code> and <code>getLastName</code>, we still do a little bit of nesting. However, our final asynchronous action can now occur on the outside of the nesting, which will take advantage of the last returned result of our <code>Promise</code> resolutions.</p>

<p>Error handling is another can of worms in callbacks. Which return value is the error and which is the result? Every level of nesting in a callback has to either handle errors, or maybe the top-most callback has to contain a try-catch block. Here&rsquo;s a particularly nasty example:</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>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">const</span> <span class="nx">getFirstName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">)</span> <span class="k">return</span> <span class="nx">callback</span><span class="p">(</span><span class="s1">&#39;Sorry, firstName errored&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">callback</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="s1">&#39;Harry&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kr">const</span> <span class="nx">getLastName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">)</span> <span class="k">return</span> <span class="nx">callback</span><span class="p">(</span><span class="s1">&#39;Sorry, lastName errored&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">callback</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="s1">&#39;Potter&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kr">const</span> <span class="nx">concatName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">)</span> <span class="k">return</span> <span class="nx">callback</span><span class="p">(</span><span class="s1">&#39;Sorry, fullName errored&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">callback</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="err">`</span><span class="nx">$</span><span class="p">{</span><span class="nx">first</span><span class="p">}</span> <span class="nx">$</span><span class="p">{</span><span class="nx">last</span><span class="p">}</span><span class="err">`</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">getFirstName</span><span class="p">((</span><span class="nx">err</span><span class="p">,</span> <span class="nx">first</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span> <span class="c1">// no return, will fall through despite error</span>
</span><span class='line'>  <span class="nx">getLastName</span><span class="p">((</span><span class="nx">err</span><span class="p">,</span> <span class="nx">last</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="k">return</span> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">concatName</span><span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">fullname</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="k">return</span> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">err</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="nx">fullname</span><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 class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Every callback has to check for an individual error, and if any level mishandles the error (note the lack of a return on error after <code>getFirstName</code>), you&rsquo;re guaranteed to end up with undefined behavior. A <code>Promise</code> allows us to handle errors at any level with a <code>catch</code> statement:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">const</span> <span class="nx">getFirstName</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">)</span> <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">reject</span><span class="p">(</span><span class="s1">&#39;Sorry, firstName errored&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;Harry&#39;</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kr">const</span> <span class="nx">getLastName</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">)</span> <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">reject</span><span class="p">(</span><span class="s1">&#39;Sorry, lastName errored&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;Potter&#39;</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kr">const</span> <span class="nx">concatName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">)</span> <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">reject</span><span class="p">(</span><span class="s1">&#39;Sorry, fullName errored&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="err">`</span><span class="nx">$</span><span class="p">{</span><span class="nx">first</span><span class="p">}</span> <span class="nx">$</span><span class="p">{</span><span class="nx">last</span><span class="p">}</span><span class="err">`</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">getFirstName</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">first</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">getLastName</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">last</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">concatName</span><span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">}).</span><span class="nx">then</span><span class="p">((</span><span class="nx">fullname</span><span class="p">)</span> <span class="o">=&gt;</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="nx">fullname</span><span class="p">);</span>
</span><span class='line'><span class="p">}).</span><span class="k">catch</span><span class="p">((</span><span class="nx">err</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>We return the result of <code>Promise.reject</code> to signify that we have an error. We only need to call <code>catch</code> once. Any <code>then</code> statements from unresolved promises will be ignored. A <code>catch</code> could be inserted at any nesting point, which could give you the ability to continue the chain:</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='javascript'><span class='line'><span class="c1">// ...</span>
</span><span class='line'>
</span><span class='line'><span class="nx">getFirstName</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">first</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">getLastName</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">last</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">concatName</span><span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}).</span><span class="k">catch</span><span class="p">((</span><span class="nx">err</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">concatName</span><span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="s1">&#39;Houdini&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">}).</span><span class="nx">then</span><span class="p">((</span><span class="nx">fullname</span><span class="p">)</span> <span class="o">=&gt;</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="nx">fullname</span><span class="p">);</span>
</span><span class='line'><span class="p">}).</span><span class="k">catch</span><span class="p">((</span><span class="nx">err</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>So far, we&rsquo;ve been returning <code>Promise</code> objects using <code>resolve</code> and <code>reject</code>, but there&rsquo;s also the ability to define our own <code>Promise</code> objects with their own <code>resolve</code> and <code>reject</code> methods. Updating the <code>getFirstName</code> variable:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">const</span> <span class="nx">getFirstName</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="k">new</span> <span class="nx">Promise</span><span class="p">((</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">reject</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">)</span> <span class="k">return</span> <span class="nx">reject</span><span class="p">(</span><span class="s1">&#39;Sorry, firstName errored&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;Harry&#39;</span><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 class="c1">// ...</span>
</span></code></pre></td></tr></table></div></figure>


<p>We can also run our asynchronous tasks without nesting by using the <code>Promise.all</code> method:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">// ...</span>
</span><span class='line'>
</span><span class='line'><span class="nx">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">([</span><span class="nx">getFirstName</span><span class="p">(),</span> <span class="nx">getLastName</span><span class="p">()]).</span><span class="nx">then</span><span class="p">((</span><span class="nx">names</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">concatName</span><span class="p">(</span><span class="nx">names</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">names</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
</span><span class='line'><span class="p">}).</span><span class="nx">then</span><span class="p">((</span><span class="nx">fullname</span><span class="p">)</span> <span class="o">=&gt;</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="nx">fullname</span><span class="p">);</span>
</span><span class='line'><span class="p">}).</span><span class="k">catch</span><span class="p">((</span><span class="nx">err</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Give <code>Promise.all</code> a list of promises and it will call them (in some order) and return all the results in an array (in the order given) as a resolved <code>Promise</code> once all given promises have been resolved. If any of the promises are rejected, the entire <code>Promise</code> will be rejected, resulting in the <code>catch</code> statement.</p>

<p>Sometimes you need to run several methods, and you only care about the first result. <code>Promise.race</code> is similar to <code>Promise.all</code>, but only waits for one of the given promises to return:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">const</span> <span class="nx">func1</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="k">new</span> <span class="nx">Promise</span><span class="p">((</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">reject</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;func1&#39;</span><span class="p">),</span> <span class="mi">5</span><span class="o">*</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><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="kr">const</span> <span class="nx">func2</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="k">new</span> <span class="nx">Promise</span><span class="p">((</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">reject</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;func2&#39;</span><span class="p">),</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><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">Promise</span><span class="p">.</span><span class="nx">race</span><span class="p">([</span><span class="nx">func1</span><span class="p">(),</span> <span class="nx">func2</span><span class="p">()]).</span><span class="nx">then</span><span class="p">((</span><span class="nx">name</span><span class="p">)</span> <span class="o">=&gt;</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="nx">name</span><span class="p">);</span>
</span><span class='line'><span class="p">}).</span><span class="k">catch</span><span class="p">((</span><span class="nx">err</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Sometimes, &lsquo;func1&rsquo; will be printed, but most of the time &lsquo;func2&rsquo; will be printed.</p>

<p>&hellip;And that&rsquo;s the basics! Hopefully, you have a better understanding of how a <code>Promise</code> works and the advantages provided over traditional callback architectures. More and more libraries are depending on the <code>Promise</code> class, and you can really clean up your logic by using those methods. As Javascript continues to evolve, hopefully we find ourselves getting more of these well-designed systems to make writing code more pleasant.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Demystifying Public Speaking]]></title>
    <link href="https://larry-price.com/blog/2017/08/31/demystifying-public-speaking/"/>
    <updated>2017-08-31T19:55:20-05:00</updated>
    <id>https://larry-price.com/blog/2017/08/31/demystifying-public-speaking</id>
    <content type="html"><![CDATA[<h3>The Gist</h3>

<p>Public speaking makes me nervous, and I&rsquo;m not alone. A crowd of people is listening to your stutters, nit-picking your errors, and judging your clothing. No one is immune from the fear of public speaking. What can you do about it? Armed with Lara Hogan&rsquo;s <em><a href="https://abookapart.com/products/demystifying-public-speaking">Demystifying Public Speaking</a></em>, we can learn how to make public speaking a bit less stressful. There is no complete answer, but this book is full of tips and guidance for speaking engagements of any size and gravitas.</p>

<h3>Takeaways</h3>

<p>Need ideas for public speaking? Take advantage of the work you do every day. Prepare a presentation for the tough code you wrote last week, the library you found, the Agile processes you use, or how you set up your workstation, favorite tool, or cloud service.</p>

<p>Start small. Run the topic by your coworkers with a rough outline. Run it by your spouse to get an outside perspective. You can tweak your ideas based on the feedback, and then move on to bigger venues. Do a lunch and learn, a lightning talk, or a local meetup.</p>

<p>Your end goal does not have to be a conference. Conferences can be huge events with many attendees, and can be extremely daunting. Many people only go to conferences for the big names, and your talk might be more easily forgotten amongst all the ultra-hyped celebrity talks.</p>

<p>Then again, if that&rsquo;s what you&rsquo;re into, you could become the celebrity after doing a few conference talks. If you do well at one or two conferences, there&rsquo;s a good chance you&rsquo;ll start getting invited to more conferences. These conferences might want you to rehash your past talk (score! minimal effort!), give you a topic, or hand you the reigns to get creative.</p>

<p>Your audience wants you to do well. It&rsquo;s a common misconception that your audience is rooting against you. They want to learn, and they want to believe that what you&rsquo;re telling them is worthwhile. If you make a mistake, you don&rsquo;t need to be embarrassed: everyone knows it&rsquo;s hard to go on-stage in front of a group of people. Just try to correct yourself and move on.</p>

<p>Always include some levity in your presentation. A joke or a cat picture can help reengage an audience that may be succumbing to fatigue. Ask a silly or surprising question, maybe even going so far as to ask for some audience participation.</p>

<p>Presentations with lots of imagery are great, but your presentation style doesn&rsquo;t have to follow any conventions. Some people are comfortable getting their cues from their notes and images, but others may prefer more traditional header and bullet point slides.</p>

<p>If there&rsquo;s going to be a Q&amp;A section, have your coworkers or peers hit you with some potential questions. Maybe you can beef up parts of your presentation that were misinterpreted or underrepresented.</p>

<p>It&rsquo;s okay to say &ldquo;I don&rsquo;t know&rdquo; during a Q&amp;A session. You just laid down a lot of knowledge on your audience, but that doesn&rsquo;t mean you have to know all the answers. Furthermore, if someone &ldquo;stumps&rdquo; you during a Q&amp;A section, just admit it and move on. There&rsquo;s always that one guy who asks a &ldquo;question&rdquo; that he already knows the answer to to make himself appear intelligent. Ignore that guy. He&rsquo;s got issues. Just say &ldquo;OK&rdquo; and move on to the next question.</p>

<p>Do what&rsquo;s comfortable for you. Read directly from your notes. Put comforting reminders in your slides, like pictures of your cats or Superman squashing fascism. Use &ldquo;wizard hands&rdquo; or other embarrassing hand gestures. Let your personality come out, or invent a completely separate stage persona to assume while you&rsquo;re presenting. All that matters is that you accomplish your task of dropping some knowledge bombs on your intended audience.</p>

<p>Remember: you&rsquo;re the expert on this topic. If you weren&rsquo;t, you wouldn&rsquo;t be able to put together that presentation to begin with. Your presentation was chosen because the organizer(s) had confidence in you, your ability, and your knowledge. The audience members are there because they find meaning in your topic and believe you&rsquo;re the right person to transfer that information. You&rsquo;re in control.</p>

<h3>Action Items</h3>

<p>I really only have one action item from this book:</p>

<ul>
<li><strong>Do some public speaking!</strong></li>
</ul>


<p>I&rsquo;ve moved to a new city this summer, and I&rsquo;m starting to actively seek out local meetup groups. My goal is to find the right opportunity and the courage to participate in some lightning talks or possibly longer presentations.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Where's Larry?]]></title>
    <link href="https://larry-price.com/blog/2017/08/26/wheres-larry/"/>
    <updated>2017-08-26T18:30:48-05:00</updated>
    <id>https://larry-price.com/blog/2017/08/26/wheres-larry</id>
    <content type="html"><![CDATA[<p>I&rsquo;ve been on hiatus for a few months. Aside from the technical writing I usually do on this blog, I haven&rsquo;t pushed much extracurricular code or read any programming books. So what have I been doing?</p>

<p><em>Warning: This is going to come off as a diary entry about my life and is not intended as a free, highly technical post about programming. Come back later for more of that.</em></p>

<h3>Downhill</h3>

<h4>Old Job</h4>

<p>In mid-April, Canonical went through a major focus shift and with it <a href="https://www.theregister.co.uk/2017/04/12/80_canonical_staff_face_chop/">a major round of layoffs</a>. The company sought to become a more profitable business, and no longer believed the innovative work being done around Unity 8, Mir, and convergence could lead to profitability, and instead decided to focus on snaps and the cloud. Most of us working on the projects I mentioned got the axe, as well as others in various other departments.</p>

<p>To quote Vonnegut: &ldquo;So it goes.&rdquo;</p>

<p>I understand the shift from a business perspective, but have many opinions about the layoff process and the future of Ubuntu. Ticket price is currently set at two whiskey drinks. Ubuntu is shifting to Gnome 3 by default in October, making the line between Ubuntu and Fedora a bit cloudier. The open-source community lost a unique desktop environment, an interesting (if ambitious) vision for the future, and a large number of contributors putting in at least 40 hours a week.</p>

<h4>Wanderer</h4>

<p>In the meantime, my wife had set a date to leave her job and go back to graduate school in another state. We needed to find a new place to live in the next couple months and sell our home in Indiana. Needless to say, losing 2/3 of our income added a little bit of stress to the situation.</p>

<h4>A Matter of Health</h4>

<p>Ever since I got back from FOSDEM in February, I was slowly losing weight. No matter how much I ate, the pounds continued to drop. After the layoff, my health deteriorated quickly. Going to bed each night, I could hear my heart beating way too fast. I got tired walking up the stairs. It literally hurt to sit on my bony behind. With the layoff, my health insurance was also gone unless I wanted to pay $500+ each month to &ldquo;take advantage&rdquo; of COBRA.</p>

<p>So it goes.</p>

<h3>Uphill</h3>

<h4>New Job</h4>

<p>Fortunately, I was able to find a new job fairly quickly. There are lots of companies looking for programmers right now, so I had my pick of interesting domains to apply to. I landed at a company called <a href="http://www.illinoisrocstar.com/">Illinois Rocstar</a> (IR for short) as a <em>Research Engineer</em>, working on SBIR contracts for the Department of Energy and Department of Defense. The company is mostly non-traditional programmers, and I came in with a lot to offer as far as writing software, building applications, and designing processes. It&rsquo;s a fairly unique experience to work in the world of science with co-workers who come from very different backgrounds. I work in an office again, but it&rsquo;s an office of fewer than 20 people in the beautiful University of Illinois Research Park.</p>

<h4>New Bill of Health</h4>

<p>With new job on hand, I acquired new health insurance as quickly as possible and went to see a physician. The diagnosis: adult-onset diabetes. Over the past three months, I have made drastic changes to my diet and significantly improved my health. It&rsquo;s amazing how carb-heavy the American diet is; added sugar pervades practically everything we eat. I currently make most of my own meals at home, and it has intensified my love of the culinary arts.</p>

<h4>Migration</h4>

<p>We found a new home in our new city (Champaign-Urbana, IL) quickly: it&rsquo;s a 1913 arts &amp; crafts style home with a tiny yard, big kitchen, and a basement. It&rsquo;s walking distance to downtown, parks, and grocery stores. We adore this home and were really lucky to find it.</p>

<h3>Flatlander</h3>

<p>For a while, it seemed the pattern was all tragic events followed by a series of purely positive events. But the story is never quite that simple.</p>

<p>While my health has been slowly improving, my great-grandmother passed away naturally, and my parents revealed that they had been secretly dealing with some health issues of my father&rsquo;s. Although I am getting better, I still have a ways to go before I could be described as fully healthy; but I&rsquo;ve found a new physician in Champaign, and we&rsquo;re working on it.</p>

<p>Although we found the new house in Champaign quickly, selling our home in Indiana is another story. With the housing market the way it is right now, every schmuck on the street was telling us we would sell our home the first weekend we listed. The reality is that it took about 80 days to find a buyer, and the closing date is 134 days after listing (still a couple weeks from the date I&rsquo;m writing this post). This meant two mortgages for a couple months, which has forced us to stretch our dollar a bit. The good news, of course, is that I will no longer be a real estate mogul in a short couple of weeks.</p>

<h3>Dear Journal</h3>

<p>Enough of my sob story.</p>

<p>I&rsquo;m just about ready to start looking for opportunities to get involved in programming outside of the office again. I have at least one mobile application in mind, I could blog forever about all the React I&rsquo;ve done and scientific tools I&rsquo;ve learned to use, and I&rsquo;ll be looking for locals to start sharing my experience with.</p>

<p>Time to get back in the game.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[On Gender Bias and Home Improvement]]></title>
    <link href="https://larry-price.com/blog/2017/04/18/on-gender-bias-and-home-improvement/"/>
    <updated>2017-04-18T10:42:10-04:00</updated>
    <id>https://larry-price.com/blog/2017/04/18/on-gender-bias-and-home-improvement</id>
    <content type="html"><![CDATA[<p>Instead of a highly technical guide, today I have a short anecdote of some recent electrical work we did in the master bathroom.</p>

<p>I met my wife when I joined my high school robotics team. I was a hammer: with no singular skill that I wanted to focus on, I was thrown into painting, cutting, drilling, electrical, lifting, sanding, building the website, and even marketing. Funnily enough, I never actually worked on programming the robot. As far as I knew at the time, my wife was doing similar work with more focus on marketing and operating the robot.</p>

<p>Fast-forward 10 years. I do most of the indoor home improvement work (electrical, dry walling, painting), and our yard work is fairly balanced. A few weekends ago, we were swapping out the light fixtures in the master bathroom. Well, she was mostly holding the flashlight while I cursed at the previous owner&rsquo;s hackwork. As we&rsquo;re wrapping up the first fixture, she starts asking really basic electrical questions. Beginner&rsquo;s questions.</p>

<p>This struck me as a little odd. I answer with a bit of sarcasm, mentioning that it&rsquo;s the absolute basic stuff she should remember from being on the robotics team. As it turns out, the (all-male) mentor staff never really encouraged the girls to work directly on the robot. The girls were pushed toward things like &ldquo;marketing&rdquo; and operating the robot, presumably because it reflected well on the team to have female drivers/operators. I started to think back on our overlapping time on the team and&hellip; Come to think of it, the girls really were pushed into a less-technical experience while I was pushed towards the greasy work.</p>

<p>This was 10 years ago, so I would hope things are a bit different now as more girls are influenced to get interested in STEM in high school. It&rsquo;s a shame that she wasn&rsquo;t encouraged to take on the same tasks as the boys, and it&rsquo;s left an obvious effect on her into adulthood.</p>

<p>So I started thinking about my parents. My father would include me as much as possible in fixing up the house. My sister, on the other hand, would generally not be included. Granted, she&rsquo;s 4 years younger than me, but I was forced to help my dad do things from a very young age when I would have rather been playing video games than learning life lessons. My wife is the eldest of three daughters, and they also were never really invited to help with home improvement outside of yard work.</p>

<p>We may not have grown up in the most forward-thinking town, but our parents are not sexists. Our robotics mentors may have lived a bit in the past, but they intended no malice while directing students towards work. In both of these cases, the adults were following the same pattern they&rsquo;ve seen for generations. The trick now is to break that pattern.</p>

<p>For the second light fixture in the master bathroom, I held the flashlight. I instructed my wife in removing and replacing the fixture, only intervening on stubborn bolts. After we finished, she thanked me. I felt a bit guilty for not letting her take the wheel for so long. My assumption had always been she had the skills but no desire to get her hands dirty. Turns out she only needed the opportunity to break the pattern.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using D-Bus Signals in Python]]></title>
    <link href="https://larry-price.com/blog/2017/04/11/using-d-bus-signals-in-python/"/>
    <updated>2017-04-11T15:30:58-04:00</updated>
    <id>https://larry-price.com/blog/2017/04/11/using-d-bus-signals-in-python</id>
    <content type="html"><![CDATA[<p><em>This is the third in a series of blog posts on creating an asynchronous D-Bus service in python. For the inital entry, <a href="https://larry-price.com/blog/2017/04/04/creating-a-d-bus-service-with-python/">go here</a>. For the previous entry, <a href="https://larry-price.com/blog/2017/04/05/creating-an-asynchronous-d-bus-service-with-python/">go here</a></em></p>

<p>Last time we transformed our base synchronous D-Bus service to include asynchronous calls in a rather naive way. In this post, we&rsquo;ll refactor those asynchronous calls to include D-Bus signals; codewise, we&rsquo;ll pick up right where we left off after part 2: <a href="https://github.com/larryprice/python-dbus-blog-series/tree/part2">https://github.com/larryprice/python-dbus-blog-series/tree/part2</a>. Of course, all of today&rsquo;s code can be found in the same project with the part3 tag: <a href="https://github.com/larryprice/python-dbus-blog-series/tree/part3">https://github.com/larryprice/python-dbus-blog-series/tree/part3</a>.</p>

<h3>Sending Signals</h3>

<p>We can fire signals from within our D-Bus service to notify clients of tasks finishing, progress updates, or data availability. Clients subscribe to these signals and act accordingly. Let&rsquo;s start by changing the signature of the <code>slow_result</code> method of <code>RandomData</code> to be a signal:</p>

<figure class='code'><figcaption><span>random_data.py</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='python'><span class='line'><span class="c"># ...</span>
</span><span class='line'><span class="nd">@dbus.service.signal</span><span class="p">(</span><span class="s">&quot;com.larry_price.test.RandomData&quot;</span><span class="p">,</span> <span class="n">signature</span><span class="o">=</span><span class="s">&#39;ss&#39;</span><span class="p">)</span>
</span><span class='line'><span class="k">def</span> <span class="nf">slow_result</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">thread_id</span><span class="p">,</span> <span class="n">result</span><span class="p">):</span>
</span><span class='line'>    <span class="k">pass</span>
</span></code></pre></td></tr></table></div></figure>


<p>We&rsquo;ve replaced the context decorator with a <code>signal</code>, and we&rsquo;ve swapped out the guts of this method for a <code>pass</code>, meaning the method will call but doesn&rsquo;t do anything else. We now need a way to call this signal, which we can do from the <code>SlowThread</code> class we were using before. When creating a <code>SlowThread</code> in the <code>slow</code> method, we can pass in this signal as a callback. At the same time, we can remove the <code>threads</code> list we used to use to keep track of existing <code>SlowThread</code> objects.</p>

<figure class='code'><figcaption><span>random_data.py</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="k">class</span> <span class="nc">RandomData</span><span class="p">(</span><span class="n">dbus</span><span class="o">.</span><span class="n">service</span><span class="o">.</span><span class="n">Object</span><span class="p">):</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bus_name</span><span class="p">):</span>
</span><span class='line'>        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">bus_name</span><span class="p">,</span> <span class="s">&quot;/com/larry_price/test/RandomData&quot;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>    <span class="nd">@dbus.service.method</span><span class="p">(</span><span class="s">&quot;com.larry_price.test.RandomData&quot;</span><span class="p">,</span>
</span><span class='line'>                         <span class="n">in_signature</span><span class="o">=</span><span class="s">&#39;i&#39;</span><span class="p">,</span> <span class="n">out_signature</span><span class="o">=</span><span class="s">&#39;s&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">slow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="o">=</span><span class="mi">8</span><span class="p">):</span>
</span><span class='line'>        <span class="n">thread</span> <span class="o">=</span> <span class="n">SlowThread</span><span class="p">(</span><span class="n">bits</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">slow_result</span><span class="p">)</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">thread</span><span class="o">.</span><span class="n">thread_id</span>
</span><span class='line'>
</span><span class='line'>    <span class="c"># ...</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we can make some updates to <code>SlowThread</code>. The first thing we should do is add a new parameter <code>callback</code> and store it on the object. Because <code>slow_result</code> no longer checks the <code>done</code> property, we can remove that and the <code>finished</code> event. Instead of calling <code>set</code> on the event, we can now simply call the <code>callback</code> we stored with the current <code>thread_id</code> and <code>result</code>. We end up with a couple of unused variables here, so I&rsquo;ve also gone ahead and refactored the <code>work</code> method on <code>SlowThread</code> to be a little cleaner.</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>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c"># ...</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">SlowThread</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="p">,</span> <span class="n">callback</span><span class="p">):</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_callback</span> <span class="o">=</span> <span class="n">callback</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">result</span> <span class="o">=</span> <span class="s">&#39;&#39;</span>
</span><span class='line'>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">work</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">bits</span><span class="p">,))</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">thread_id</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">thread</span><span class="o">.</span><span class="n">ident</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">work</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="p">):</span>
</span><span class='line'>        <span class="n">num</span> <span class="o">=</span> <span class="s">&#39;&#39;</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
</span><span class='line'>            <span class="n">num</span> <span class="o">+=</span> <span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
</span><span class='line'>            <span class="n">bits</span> <span class="o">-=</span> <span class="mi">1</span>
</span><span class='line'>            <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>            <span class="k">if</span> <span class="n">bits</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
</span><span class='line'>                <span class="k">break</span>
</span><span class='line'>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_callback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">thread_id</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="mi">2</span><span class="p">)))</span>
</span></code></pre></td></tr></table></div></figure>


<p>And that&rsquo;s it for the service-side. Any callers will need to subscribe to our <code>slow_result</code> method, call our <code>slow</code> method, and wait for the result to come in.</p>

<h3>Receiving Signals</h3>

<p>We need to make some major changes to our <code>client</code> program in order to receive signals. We&rsquo;ll need to introduce a main loop, which we&rsquo;ll spin up in a separate thread, for communicating on the bus. The way I like to do this is with a ContextManager so we can guarantee that the loop will be exited when the program exits. We&rsquo;ll move the logic we previously used in <code>client</code> to get the <code>RandomData</code> object into a private member method called <code>_setup_object</code>, which we&rsquo;ll call on context entry after creating the loop. On context exit, we&rsquo;ll simply call <code>quit</code> on the loop.</p>

<figure class='code'><figcaption><span>client</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='python'><span class='line'><span class="c"># Encapsulate calling the RandomData object on the session bus with a main loop</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">dbus</span><span class="o">,</span> <span class="nn">dbus.exceptions</span><span class="o">,</span> <span class="nn">dbus.mainloop.glib</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">threading</span>
</span><span class='line'><span class="kn">from</span> <span class="nn">gi.repository</span> <span class="kn">import</span> <span class="n">GLib</span>
</span><span class='line'><span class="k">class</span> <span class="nc">RandomDataClient</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_setup_dbus_loop</span><span class="p">()</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_setup_object</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="bp">self</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">traceback</span><span class="p">):</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_loop</span><span class="o">.</span><span class="n">quit</span><span class="p">()</span>
</span><span class='line'>        <span class="k">return</span> <span class="bp">True</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">_setup_dbus_loop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'>        <span class="n">dbus</span><span class="o">.</span><span class="n">mainloop</span><span class="o">.</span><span class="n">glib</span><span class="o">.</span><span class="n">DBusGMainLoop</span><span class="p">(</span><span class="n">set_as_default</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_loop</span> <span class="o">=</span> <span class="n">GLib</span><span class="o">.</span><span class="n">MainLoop</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_loop</span><span class="o">.</span><span class="n">run</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">_setup_object</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'>        <span class="k">try</span><span class="p">:</span>
</span><span class='line'>            <span class="bp">self</span><span class="o">.</span><span class="n">_bus</span> <span class="o">=</span> <span class="n">dbus</span><span class="o">.</span><span class="n">SessionBus</span><span class="p">()</span>
</span><span class='line'>            <span class="bp">self</span><span class="o">.</span><span class="n">_random_data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bus</span><span class="o">.</span><span class="n">get_object</span><span class="p">(</span><span class="s">&quot;com.larry-price.test&quot;</span><span class="p">,</span>
</span><span class='line'>                                                     <span class="s">&quot;/com/larry_price/test/RandomData&quot;</span><span class="p">)</span>
</span><span class='line'>        <span class="k">except</span> <span class="n">dbus</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">DBusException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span class='line'>            <span class="k">print</span><span class="p">(</span><span class="s">&quot;Failed to initialize D-Bus object: &#39;</span><span class="si">%s</span><span class="s">&#39;&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
</span><span class='line'>            <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>We can add methods on <code>RandomDataClient</code> to encapsulate <code>quick</code> and <code>slow</code>. <code>quick</code> is easy - we&rsquo;ll just return <code>self._random_data.quick(bits)</code>. <code>slow</code>, on the other hand, will take a bit of effort. We&rsquo;ll need to subscribe to the <code>slow_result</code> signal, giving a callback for when the signal is received. Since we want to wait for the result here, we&rsquo;ll create a <code>threading.Event</code> object and <code>wait</code> for it to be <code>set</code>, which we&rsquo;ll do in our handler. The handler, which we&rsquo;ll call <code>_finished</code> will validate that it has received the right result based on the current <code>thread_id</code> and then set the <code>result</code> on the <code>RandomDataClient</code> object. After all this, we&rsquo;ll remove the signal listener from our bus connection and return the final result.</p>

<figure class='code'><figcaption><span>client</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>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="k">class</span> <span class="nc">RandomDataClient</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span><span class='line'>    <span class="c"># ...</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">quick</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="p">):</span>
</span><span class='line'>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_random_data</span><span class="o">.</span><span class="n">quick</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">_finished</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">thread_id</span><span class="p">,</span> <span class="n">result</span><span class="p">):</span>
</span><span class='line'>        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_thread_id</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_thread_id</span><span class="p">:</span>
</span><span class='line'>            <span class="bp">self</span><span class="o">.</span><span class="n">_result</span> <span class="o">=</span> <span class="n">result</span>
</span><span class='line'>            <span class="bp">self</span><span class="o">.</span><span class="n">_done</span><span class="o">.</span><span class="n">set</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">slow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="p">):</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_done</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Event</span><span class="p">()</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_thread_id</span> <span class="o">=</span> <span class="bp">None</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_result</span> <span class="o">=</span> <span class="bp">None</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">signal</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bus</span><span class="o">.</span><span class="n">add_signal_receiver</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s">&quot;/com/larry_price/test/RandomData&quot;</span><span class="p">,</span> <span class="n">handler_function</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_finished</span><span class="p">,</span>
</span><span class='line'>                                               <span class="n">dbus_interface</span><span class="o">=</span><span class="s">&quot;com.larry_price.test.RandomData&quot;</span><span class="p">,</span> <span class="n">signal_name</span><span class="o">=</span><span class="s">&#39;slow_result&#39;</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_thread_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_random_data</span><span class="o">.</span><span class="n">slow</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">_done</span><span class="o">.</span><span class="n">wait</span><span class="p">()</span>
</span><span class='line'>        <span class="n">signal</span><span class="o">.</span><span class="n">remove</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_result</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we&rsquo;re ready to actually call these methods. We&rsquo;ll wrap our old calling code with the <code>RandomDataClient</code> context manager, and we&rsquo;ll directly call the methods as we did before on the client:</p>

<figure class='code'><figcaption><span>client</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='python'><span class='line'><span class="c"># ...</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Call the appropriate method with the given number of bits</span>
</span><span class='line'><span class="k">with</span> <span class="n">RandomDataClient</span><span class="p">()</span> <span class="k">as</span> <span class="n">client</span><span class="p">:</span>
</span><span class='line'>    <span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">slow</span><span class="p">:</span>
</span><span class='line'>        <span class="k">print</span><span class="p">(</span><span class="s">&quot;Your random number is: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">client</span><span class="o">.</span><span class="n">slow</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">bits</span><span class="p">)))</span>
</span><span class='line'>    <span class="k">else</span><span class="p">:</span>
</span><span class='line'>        <span class="k">print</span><span class="p">(</span><span class="s">&quot;Your random number is: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">client</span><span class="o">.</span><span class="n">quick</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">bits</span><span class="p">)))</span>
</span></code></pre></td></tr></table></div></figure>


<p>This should have feature-parity with our part 2 code, but now we don&rsquo;t have to deal with an infinite loop waiting for the service to return.</p>

<h3>Next time</h3>

<p>We have a working asynchronous D-Bus service using signals. Next time I&rsquo;d like to dive into forwarding command output from a D-Bus service to a client.</p>

<p>As a reminder, the end result of our code in this post is MIT Licensed and can be found on Github: <a href="https://github.com/larryprice/python-dbus-blog-series/tree/part3">https://github.com/larryprice/python-dbus-blog-series/tree/part3</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Creating an Asynchronous D-Bus Service With Python]]></title>
    <link href="https://larry-price.com/blog/2017/04/05/creating-an-asynchronous-d-bus-service-with-python/"/>
    <updated>2017-04-05T15:41:56-04:00</updated>
    <id>https://larry-price.com/blog/2017/04/05/creating-an-asynchronous-d-bus-service-with-python</id>
    <content type="html"><![CDATA[<p><em>This is the second in a series of blog posts on creating an asynchronous D-Bus service in python. For part 1, <a href="https://larry-price.com/blog/2017/04/04/creating-a-d-bus-service-with-python/">go here</a>.</em></p>

<p>Last time we created a base for our asynchronous D-Bus service with a simple synchronous server/client. In this post, we&rsquo;ll start from that base which can be found on Github: <a href="https://github.com/larryprice/python-dbus-blog-series/tree/part1">https://github.com/larryprice/python-dbus-blog-series/tree/part1</a>. Of course, all of today&rsquo;s code can be found in the same project with the part2 tag: <a href="https://github.com/larryprice/python-dbus-blog-series/tree/part2">https://github.com/larryprice/python-dbus-blog-series/tree/part2</a>.</p>

<h3>Why Asynchronous?</h3>

<p>Before we dive into making our service asynchronous, we need a reason to make our service asynchronous. Currently, our only d-bus object contains a single method, <code>quick</code>, which lives up to its namesake and is done very quickly. Let&rsquo;s add another method to <code>RandomData</code> which takes a while to finish its job.</p>

<figure class='code'><figcaption><span>random_data.py</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>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="kn">import</span> <span class="nn">dbus.service</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">random</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">time</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">RandomData</span><span class="p">(</span><span class="n">dbus</span><span class="o">.</span><span class="n">service</span><span class="o">.</span><span class="n">Object</span><span class="p">):</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bus_name</span><span class="p">):</span>
</span><span class='line'>        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">bus_name</span><span class="p">,</span> <span class="s">&quot;/com/larry_price/test/RandomData&quot;</span><span class="p">)</span>
</span><span class='line'>        <span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>    <span class="nd">@dbus.service.method</span><span class="p">(</span><span class="s">&quot;com.larry_price.test.RandomData&quot;</span><span class="p">,</span>
</span><span class='line'>                         <span class="n">in_signature</span><span class="o">=</span><span class="s">&#39;i&#39;</span><span class="p">,</span> <span class="n">out_signature</span><span class="o">=</span><span class="s">&#39;s&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">quick</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="o">=</span><span class="mi">8</span><span class="p">):</span>
</span><span class='line'>        <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="n">bits</span><span class="p">))</span>
</span><span class='line'>
</span><span class='line'>    <span class="nd">@dbus.service.method</span><span class="p">(</span><span class="s">&quot;com.larry_price.test.RandomData&quot;</span><span class="p">,</span>
</span><span class='line'>                         <span class="n">in_signature</span><span class="o">=</span><span class="s">&#39;i&#39;</span><span class="p">,</span> <span class="n">out_signature</span><span class="o">=</span><span class="s">&#39;s&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">slow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="o">=</span><span class="mi">8</span><span class="p">):</span>
</span><span class='line'>        <span class="n">num</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
</span><span class='line'>        <span class="k">while</span> <span class="n">bits</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
</span><span class='line'>            <span class="n">num</span> <span class="o">+=</span> <span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
</span><span class='line'>            <span class="n">bits</span> <span class="o">-=</span> <span class="mi">1</span>
</span><span class='line'>            <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note the addition of the <code>slow</code> method on the <code>RandomData</code> object. <code>slow</code> is a contrived implementation of building an n-bit random number by concatenating 1s and 0s, sleeping for 1 second between each iteration. This will still go fairly quickly for a small number of bits, but could take quite some time for numbers as low as 16 bits.</p>

<p>In order to call the new method, we need to modify our <code>client</code> binary. Let&rsquo;s add in the <code>argparse</code> module and take in a new argument: <code>--slow</code>. Of course, <code>--slow</code> will instruct the program to call <code>slow</code> instead of <code>quick</code>, which we&rsquo;ll add to the bottom of the program.</p>

<figure class='code'><figcaption><span>client</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='python'><span class='line'><span class="c">#!/usr/bin/env python3</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Take in a single optional integral argument</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">sys</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">argparse</span>
</span><span class='line'>
</span><span class='line'><span class="n">arg_parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s">&#39;Get random numbers&#39;</span><span class="p">)</span>
</span><span class='line'><span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s">&#39;bits&#39;</span><span class="p">,</span> <span class="n">nargs</span><span class="o">=</span><span class="s">&#39;?&#39;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span>
</span><span class='line'><span class="n">arg_parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s">&#39;-s&#39;</span><span class="p">,</span> <span class="s">&#39;--slow&#39;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s">&#39;store_true&#39;</span><span class="p">,</span>
</span><span class='line'>                        <span class="n">default</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
</span><span class='line'>                        <span class="n">help</span><span class="o">=</span><span class="s">&#39;Use the slow method&#39;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">args</span> <span class="o">=</span> <span class="n">arg_parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Create a reference to the RandomData object on the  session bus</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">dbus</span><span class="o">,</span> <span class="nn">dbus.exceptions</span>
</span><span class='line'><span class="k">try</span><span class="p">:</span>
</span><span class='line'>    <span class="n">bus</span> <span class="o">=</span> <span class="n">dbus</span><span class="o">.</span><span class="n">SessionBus</span><span class="p">()</span>
</span><span class='line'>    <span class="n">random_data</span> <span class="o">=</span> <span class="n">bus</span><span class="o">.</span><span class="n">get_object</span><span class="p">(</span><span class="s">&quot;com.larry-price.test&quot;</span><span class="p">,</span> <span class="s">&quot;/com/larry_price/test/RandomData&quot;</span><span class="p">)</span>
</span><span class='line'><span class="k">except</span> <span class="n">dbus</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">DBusException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span class='line'>    <span class="k">print</span><span class="p">(</span><span class="s">&quot;Failed to initialize D-Bus object: &#39;</span><span class="si">%s</span><span class="s">&#39;&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
</span><span class='line'>    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Call the appropriate method with the given number of bits</span>
</span><span class='line'><span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">slow</span><span class="p">:</span>
</span><span class='line'>    <span class="k">print</span><span class="p">(</span><span class="s">&quot;Your random number is: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">random_data</span><span class="o">.</span><span class="n">slow</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">bits</span><span class="p">)))</span>
</span><span class='line'><span class="k">else</span><span class="p">:</span>
</span><span class='line'>    <span class="k">print</span><span class="p">(</span><span class="s">&quot;Your random number is: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">random_data</span><span class="o">.</span><span class="n">quick</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">bits</span><span class="p">)))</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we can run our <code>client</code> a few times to see the result of running in slow mode. Make sure to start or restart the <code>service</code> binary before running these commands:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>./client 4
</span><span class='line'>Your random number is: 2
</span><span class='line'><span class="nv">$ </span>./client <span class="m">4</span> --slow
</span><span class='line'>Your random number is: 15
</span><span class='line'><span class="nv">$ </span>./client 16
</span><span class='line'>Your random number is: 64992
</span><span class='line'><span class="nv">$ </span>./client <span class="m">16</span> --slow
</span><span class='line'>Traceback <span class="o">(</span>most recent call last<span class="o">)</span>:
</span><span class='line'>  File <span class="s2">&quot;./client&quot;</span>, line 26, in &lt;module&gt;
</span><span class='line'>    print<span class="o">(</span><span class="s2">&quot;Your random number is: %s&quot;</span> % random_data.slow<span class="o">(</span>int<span class="o">(</span>args.bits<span class="o">)))</span>
</span><span class='line'>  File <span class="s2">&quot;/usr/lib/python3/dist-packages/dbus/proxies.py&quot;</span>, line 70, in __call__
</span><span class='line'>    <span class="k">return</span> self._proxy_method<span class="o">(</span>*args, **keywords<span class="o">)</span>
</span><span class='line'>  File <span class="s2">&quot;/usr/lib/python3/dist-packages/dbus/proxies.py&quot;</span>, line 145, in __call__
</span><span class='line'>    **keywords<span class="o">)</span>
</span><span class='line'>  File <span class="s2">&quot;/usr/lib/python3/dist-packages/dbus/connection.py&quot;</span>, line 651, in call_blocking
</span><span class='line'>    message, timeout<span class="o">)</span>
</span><span class='line'>dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoReply: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
</span></code></pre></td></tr></table></div></figure>


<p>Your mileage may vary (it <em>is</em> a random number generator, after all), but you should eventually see a similar crash which is caused by a timeout in the response of the D-Bus server. We know that this algorithm works; it just needs more time to run. Since a synchronous call won&rsquo;t work here, we&rsquo;ll have to switch over to more asynchronous methods&hellip;</p>

<h3>An Asynchronous Service</h3>

<p>At this point, we can go one of two ways. We can use the <code>threading</code> module to spin threads within our process, or we can use the <code>multiprocessing</code> module to create child processes. Child processes will be slightly pudgier, but will give us more functionality. Threads are a little simpler, so we&rsquo;ll start there. We&rsquo;ll create a class called <code>SlowThread</code>, which will do the work we used to do within the <code>slow</code> method. This class will spin up a thread that performs our work. When the work is finished, it will set a <code>threading.Event</code> that can be used to check that the work is completed. <code>threading.Event</code> is a cross-thread synchronization object; when the thread calls <code>set</code> on the <code>Event</code>, we know that the thread is ready for us to check the result. In our case, we call <code>is_set</code> on our event to tell a user whether or not our data is ready.</p>

<figure class='code'><figcaption><span>random_data.py</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>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c"># ...</span>
</span><span class='line'>
</span><span class='line'><span class="kn">import</span> <span class="nn">threading</span>
</span><span class='line'><span class="k">class</span> <span class="nc">SlowThread</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="p">):</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">finished</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Event</span><span class="p">()</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">result</span> <span class="o">=</span> <span class="s">&#39;&#39;</span>
</span><span class='line'>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">work</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">bits</span><span class="p">,))</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">thread_id</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">thread</span><span class="o">.</span><span class="n">ident</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="nd">@property</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">done</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">finished</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">work</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="p">):</span>
</span><span class='line'>        <span class="n">num</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
</span><span class='line'>        <span class="k">while</span> <span class="n">bits</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
</span><span class='line'>            <span class="n">num</span> <span class="o">+=</span> <span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
</span><span class='line'>            <span class="n">bits</span> <span class="o">-=</span> <span class="mi">1</span>
</span><span class='line'>            <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">result</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">num</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">finished</span><span class="o">.</span><span class="n">set</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="c"># ...</span>
</span></code></pre></td></tr></table></div></figure>


<p>On the <code>RandomData</code> object itself, we&rsquo;ll initialize a new thread tracking list called <code>threads</code>. In <code>slow</code>, we&rsquo;ll initialize a <code>SlowThread</code> object, append it to our <code>threads</code> list, and return the thread identifier from <code>SlowThread</code>. We&rsquo;ll also want to add a method to try to get the result from a given <code>SlowThread</code> called <code>slow_result</code>, which will take in the thread identifier we returned earlier and try to find the appropriate thread. If the thread is finished (the <code>event</code> is set), we&rsquo;ll remove the thread from our list and return the result to the caller.</p>

<figure class='code'><figcaption><span>random_data.py</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>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c"># ...</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">RandomData</span><span class="p">(</span><span class="n">dbus</span><span class="o">.</span><span class="n">service</span><span class="o">.</span><span class="n">Object</span><span class="p">):</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bus_name</span><span class="p">):</span>
</span><span class='line'>        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">bus_name</span><span class="p">,</span> <span class="s">&quot;/com/larry_price/test/RandomData&quot;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">()</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">threads</span> <span class="o">=</span> <span class="p">[]</span>
</span><span class='line'>
</span><span class='line'>    <span class="c"># ...</span>
</span><span class='line'>
</span><span class='line'>    <span class="nd">@dbus.service.method</span><span class="p">(</span><span class="s">&quot;com.larry_price.test.RandomData&quot;</span><span class="p">,</span>
</span><span class='line'>                         <span class="n">in_signature</span><span class="o">=</span><span class="s">&#39;i&#39;</span><span class="p">,</span> <span class="n">out_signature</span><span class="o">=</span><span class="s">&#39;s&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">slow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="o">=</span><span class="mi">8</span><span class="p">):</span>
</span><span class='line'>        <span class="n">thread</span> <span class="o">=</span> <span class="n">SlowThread</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">threads</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">thread</span><span class="p">)</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">thread</span><span class="o">.</span><span class="n">thread_id</span>
</span><span class='line'>
</span><span class='line'>    <span class="nd">@dbus.service.method</span><span class="p">(</span><span class="s">&quot;com.larry_price.test.RandomData&quot;</span><span class="p">,</span>
</span><span class='line'>                         <span class="n">in_signature</span><span class="o">=</span><span class="s">&#39;s&#39;</span><span class="p">,</span> <span class="n">out_signature</span><span class="o">=</span><span class="s">&#39;s&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">slow_result</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">thread_id</span><span class="p">):</span>
</span><span class='line'>        <span class="n">thread</span> <span class="o">=</span> <span class="p">[</span><span class="n">t</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">threads</span> <span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">thread_id</span> <span class="o">==</span> <span class="n">thread_id</span><span class="p">]</span>
</span><span class='line'>        <span class="k">if</span> <span class="ow">not</span> <span class="n">thread</span><span class="p">:</span>
</span><span class='line'>            <span class="k">return</span> <span class="s">&#39;No thread matching id </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="n">thread_id</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">thread</span> <span class="o">=</span> <span class="n">thread</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span><span class='line'>        <span class="k">if</span> <span class="n">thread</span><span class="o">.</span><span class="n">done</span><span class="p">:</span>
</span><span class='line'>            <span class="n">result</span> <span class="o">=</span> <span class="n">thread</span><span class="o">.</span><span class="n">result</span>
</span><span class='line'>            <span class="bp">self</span><span class="o">.</span><span class="n">threads</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">thread</span><span class="p">)</span>
</span><span class='line'>            <span class="k">return</span> <span class="n">result</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="s">&#39;&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Last thing we need to do is to update the client to use the new methods. We&rsquo;ll call <code>slow</code> as we did before, but this time we&rsquo;ll store the intermediate result as the thread identifier. Next we&rsquo;ll use a while loop to spin forever until the result is ready.</p>

<figure class='code'><figcaption><span>client</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"># ...</span>
</span><span class='line'>
</span><span class='line'><span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">slow</span><span class="p">:</span>
</span><span class='line'>    <span class="kn">import</span> <span class="nn">time</span>
</span><span class='line'>    <span class="n">thread_id</span> <span class="o">=</span> <span class="n">random_data</span><span class="o">.</span><span class="n">slow</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">bits</span><span class="p">))</span>
</span><span class='line'>    <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
</span><span class='line'>        <span class="n">result</span> <span class="o">=</span> <span class="n">random_data</span><span class="o">.</span><span class="n">slow_result</span><span class="p">(</span><span class="n">thread_id</span><span class="p">)</span>
</span><span class='line'>        <span class="k">if</span> <span class="n">result</span><span class="p">:</span>
</span><span class='line'>            <span class="k">print</span><span class="p">(</span><span class="s">&quot;Your random number is: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">result</span><span class="p">)</span>
</span><span class='line'>            <span class="k">break</span>
</span><span class='line'>        <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c"># ...</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note that this is not the smartest way to do this; more on that in the next post. Let&rsquo;s give it a try!</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>./client 4
</span><span class='line'>Your random number is: 7
</span><span class='line'><span class="nv">$ </span>./client <span class="m">4</span> --slow
</span><span class='line'>Your random number is: 12
</span><span class='line'><span class="nv">$ </span>./client 16
</span><span class='line'>Your random number is: 5192
</span><span class='line'><span class="nv">$ </span>./client <span class="m">16</span> --slow
</span><span class='line'>27302
</span></code></pre></td></tr></table></div></figure>


<h3>Next time</h3>

<p>This polling method works as a naive approach, but we can do better. Next time we&rsquo;ll look into using D-Bus signals to make our client more asynchronous and remove our current polling implementation.</p>

<p>As a reminder, the end result of our code in this post is MIT Licensed and can be found on Github: <a href="https://github.com/larryprice/python-dbus-blog-series/tree/part2">https://github.com/larryprice/python-dbus-blog-series/tree/part2</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Creating a D-Bus Service With Python]]></title>
    <link href="https://larry-price.com/blog/2017/04/04/creating-a-d-bus-service-with-python/"/>
    <updated>2017-04-04T21:40:49-04:00</updated>
    <id>https://larry-price.com/blog/2017/04/04/creating-a-d-bus-service-with-python</id>
    <content type="html"><![CDATA[<p>I&rsquo;ve been working on a d-bus service to replace some of the management guts of my project for a while now. We started out creating a simple service, but some of our management processes take a long time to run, causing a timeout error when calling these methods. I needed a way to run these tasks in the background and report status to any possible clients. I&rsquo;d like to outline my approach to making this possible. This will be a multi-part blog series starting from the bottom: a very simple, synchronous d-bus service. By the end of this series, we&rsquo;ll have a small codebase with asynchronous tasks which can be interacted with (input/output) from D-Bus clients.</p>

<p>All of this code is written with python3.5 on Ubuntu 17.04 (beta), is MIT licensed, and can be found on Github: <a href="https://github.com/larryprice/python-dbus-blog-series/tree/part1">https://github.com/larryprice/python-dbus-blog-series/tree/part1</a>.</p>

<h3>What is D-Bus?</h3>

<p>From Wikipedia:</p>

<blockquote><p>In computing, D-Bus or DBus (for &ldquo;Desktop Bus&rdquo;), a software bus, is an inter-process communication (IPC) and remote procedure call (RPC) mechanism that allows communication between multiple computer programs (that is, processes) concurrently running on the same machine.</p></blockquote>

<p>D-Bus allows different processes to communicate indirectly through a known interface. The bus can be system-wide or user-specific (session-based). A D-Bus service will post a list of available objects with available methods which D-Bus clients can consume. It&rsquo;s at the heart of much Linux desktop software, allowing processes to communicate with one another without forcing direct dependencies.</p>

<h3>A synchronous service</h3>

<p>Let&rsquo;s start by building a base of a simple, synchronous service. We&rsquo;re going to initialize a loop as a context to run our service within, claim a unique name for our service on the session bus, and then start the loop.</p>

<figure class='code'><figcaption><span>service</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='python'><span class='line'><span class="c">#!/usr/bin/env python3</span>
</span><span class='line'>
</span><span class='line'><span class="kn">import</span> <span class="nn">dbus</span><span class="o">,</span> <span class="nn">dbus.service</span><span class="o">,</span> <span class="nn">dbus.exceptions</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">sys</span>
</span><span class='line'>
</span><span class='line'><span class="kn">from</span> <span class="nn">dbus.mainloop.glib</span> <span class="kn">import</span> <span class="n">DBusGMainLoop</span>
</span><span class='line'><span class="kn">from</span> <span class="nn">gi.repository</span> <span class="kn">import</span> <span class="n">GLib</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Initialize a main loop</span>
</span><span class='line'><span class="n">DBusGMainLoop</span><span class="p">(</span><span class="n">set_as_default</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</span><span class='line'><span class="n">loop</span> <span class="o">=</span> <span class="n">GLib</span><span class="o">.</span><span class="n">MainLoop</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Declare a name where our service can be reached</span>
</span><span class='line'><span class="k">try</span><span class="p">:</span>
</span><span class='line'>    <span class="n">bus_name</span> <span class="o">=</span> <span class="n">dbus</span><span class="o">.</span><span class="n">service</span><span class="o">.</span><span class="n">BusName</span><span class="p">(</span><span class="s">&quot;com.larry-price.test&quot;</span><span class="p">,</span>
</span><span class='line'>                                    <span class="n">bus</span><span class="o">=</span><span class="n">dbus</span><span class="o">.</span><span class="n">SessionBus</span><span class="p">(),</span>
</span><span class='line'>                                    <span class="n">do_not_queue</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</span><span class='line'><span class="k">except</span> <span class="n">dbus</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">NameExistsException</span><span class="p">:</span>
</span><span class='line'>    <span class="k">print</span><span class="p">(</span><span class="s">&quot;service is already running&quot;</span><span class="p">)</span>
</span><span class='line'>    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Run the loop</span>
</span><span class='line'><span class="k">try</span><span class="p">:</span>
</span><span class='line'>    <span class="n">loop</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</span><span class='line'><span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span class="p">:</span>
</span><span class='line'>    <span class="k">print</span><span class="p">(</span><span class="s">&quot;keyboard interrupt received&quot;</span><span class="p">)</span>
</span><span class='line'><span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span class='line'>    <span class="k">print</span><span class="p">(</span><span class="s">&quot;Unexpected exception occurred: &#39;{}&#39;&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
</span><span class='line'><span class="k">finally</span><span class="p">:</span>
</span><span class='line'>    <span class="n">loop</span><span class="o">.</span><span class="n">quit</span><span class="p">()</span>
</span></code></pre></td></tr></table></div></figure>


<p>Make this binary executable (<code>chmod +x service</code>) and run it. Your service should run indefinitely and do&hellip; nothing. Although we&rsquo;ve already written a lot of code, we haven&rsquo;t added any objects or methods which can be accessed on our service. Let&rsquo;s fix that.</p>

<figure class='code'><figcaption><span>dbustest/random_data.py</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='python'><span class='line'><span class="kn">import</span> <span class="nn">dbus.service</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">random</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">RandomData</span><span class="p">(</span><span class="n">dbus</span><span class="o">.</span><span class="n">service</span><span class="o">.</span><span class="n">Object</span><span class="p">):</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bus_name</span><span class="p">):</span>
</span><span class='line'>        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">bus_name</span><span class="p">,</span> <span class="s">&quot;/com/larry_price/test/RandomData&quot;</span><span class="p">)</span>
</span><span class='line'>        <span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>    <span class="nd">@dbus.service.method</span><span class="p">(</span><span class="s">&quot;com.larry_price.test.RandomData&quot;</span><span class="p">,</span>
</span><span class='line'>                         <span class="n">in_signature</span><span class="o">=</span><span class="s">&#39;i&#39;</span><span class="p">,</span> <span class="n">out_signature</span><span class="o">=</span><span class="s">&#39;s&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">quick</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="o">=</span><span class="mi">8</span><span class="p">):</span>
</span><span class='line'>        <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="n">bits</span><span class="p">))</span>
</span></code></pre></td></tr></table></div></figure>


<p>We&rsquo;ve defined a D-Bus object <code>RandomData</code> which can be accessed using the path <code>/com/larry_price/test/RandomData</code>. This style of string is the general style of an object path. We&rsquo;ve defined an interface implemented by <code>RandomData</code> called <code>com.larry_price.test.RandomData</code> with a single method <code>quick</code> as declared with the <code>@dbus.service.method</code> context decorator. <code>quick</code> will take in a single parameter, <code>bits</code>, which must be an integer as designated by the <code>in_signature</code> in our context decorator. <code>quick</code> will return a string as specified by the <code>out_signature</code> parameter. All that <code>quick</code> does is return a random string given a number of bits. It&rsquo;s simple and it&rsquo;s fast.</p>

<p>Now that we have an object, we need to declare an instance of that object in our service to attach it properly. Let&rsquo;s assume that <code>random_data.py</code> is in a directory <code>dbustest</code> with an empty <code>__init__.py</code>, and our service binary is still sitting in the root directory. Just before we start the loop in the <code>service</code> binary, we can add the following code:</p>

<figure class='code'><figcaption><span>service</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>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c"># ...</span>
</span><span class='line'><span class="c"># Run the loop</span>
</span><span class='line'><span class="k">try</span><span class="p">:</span>
</span><span class='line'>    <span class="c"># Create our initial objects</span>
</span><span class='line'>    <span class="kn">from</span> <span class="nn">dbustest.random_data</span> <span class="kn">import</span> <span class="n">RandomData</span>
</span><span class='line'>    <span class="n">RandomData</span><span class="p">(</span><span class="n">bus_name</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">loop</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</span><span class='line'><span class="c"># ...</span>
</span></code></pre></td></tr></table></div></figure>


<p>We don&rsquo;t need to do anything with the object we&rsquo;ve initialized; creating it is enough to attach it to our D-Bus service and prevent it from being garbage collected until the service exits. We pass in <code>bus_name</code> so that <code>RandomData</code> will connect to the right bus name.</p>

<h3>A synchronous client</h3>

<p>Now that you have an object with an available method on our service, you&rsquo;re probably interested in calling that method. You can do this on the command line with something like <code>dbus-send</code>, or you could find the service using a GUI tool such as <code>d-feet</code> and call the method directly. But eventually we&rsquo;ll want to do this with a custom program, so let&rsquo;s build a very small program to get started.</p>

<figure class='code'><figcaption><span>client</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>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c">#!/usr/bin/env python3</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Take in a single optional integral argument</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">sys</span>
</span><span class='line'><span class="n">bits</span> <span class="o">=</span> <span class="mi">16</span>
</span><span class='line'><span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
</span><span class='line'>    <span class="k">try</span><span class="p">:</span>
</span><span class='line'>        <span class="n">bits</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
</span><span class='line'>    <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
</span><span class='line'>        <span class="k">print</span><span class="p">(</span><span class="s">&quot;input argument must be integer&quot;</span><span class="p">)</span>
</span><span class='line'>        <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Create a reference to the RandomData object on the  session bus</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">dbus</span><span class="o">,</span> <span class="nn">dbus.exceptions</span>
</span><span class='line'><span class="k">try</span><span class="p">:</span>
</span><span class='line'>    <span class="n">bus</span> <span class="o">=</span> <span class="n">dbus</span><span class="o">.</span><span class="n">SessionBus</span><span class="p">()</span>
</span><span class='line'>    <span class="n">random_data</span> <span class="o">=</span> <span class="n">bus</span><span class="o">.</span><span class="n">get_object</span><span class="p">(</span><span class="s">&quot;com.larry-price.test&quot;</span><span class="p">,</span> <span class="s">&quot;/com/larry_price/test/RandomData&quot;</span><span class="p">)</span>
</span><span class='line'><span class="k">except</span> <span class="n">dbus</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">DBusException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span class='line'>    <span class="k">print</span><span class="p">(</span><span class="s">&quot;Failed to initialize D-Bus object: &#39;</span><span class="si">%s</span><span class="s">&#39;&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
</span><span class='line'>    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Call the quick method with the given number of bits</span>
</span><span class='line'><span class="k">print</span><span class="p">(</span><span class="s">&quot;Your random number is: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">random_data</span><span class="o">.</span><span class="n">quick</span><span class="p">(</span><span class="n">bits</span><span class="p">))</span>
</span></code></pre></td></tr></table></div></figure>


<p>A large chunk of this code is parsing an input argument as an integer. By default, <code>client</code> will request a 16-bit random number unless it gets a number as input from the command line. Next we spin up a reference to the session bus and attempt to find our <code>RandomData</code> object on the bus using our known service name and object path. Once that&rsquo;s initialized, we can directly call the <code>quick</code> method over the bus with the specified number of bits and print the result.</p>

<p>Make this binary executable also. If you try to run <code>client</code> without running <code>service</code>, you should see an error message explaining that the <code>com.larry-price.test</code> D-Bus service is not running (which would be true). Start <code>service</code>, and then run <code>client</code> with a few different input options and observe the results:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>./service <span class="p">&amp;</span> <span class="c"># to kill service later, be sure to note the pid here!</span>
</span><span class='line'><span class="nv">$ </span>./client
</span><span class='line'>Your random number is: 41744
</span><span class='line'><span class="nv">$ </span>./client 100
</span><span class='line'>Your random number is: 401996322348922753881103222071
</span><span class='line'><span class="nv">$ </span>./client 4
</span><span class='line'>Your random number is: 14
</span><span class='line'><span class="nv">$ </span>./client <span class="s2">&quot;new donk city&quot;</span>
</span><span class='line'>input argument must be integer
</span></code></pre></td></tr></table></div></figure>


<p>That&rsquo;s all there is to it. A simple, synchronous server and client. The server and client do not directly depend on each other but are able to communicate unidirectionally through simple method calls.</p>

<h3>Next time</h3>

<p>Next time, I&rsquo;ll go into detail on how we can create an asynchronous service and client, and hopefully utilize signals to add a new direction to our communication.</p>

<p>Again, all the code can be found on Github: <a href="https://github.com/larryprice/python-dbus-blog-series/tree/part1">https://github.com/larryprice/python-dbus-blog-series/tree/part1</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Snappy Libertine]]></title>
    <link href="https://larry-price.com/blog/2017/02/15/snappy-libertine/"/>
    <updated>2017-02-15T18:38:44-05:00</updated>
    <id>https://larry-price.com/blog/2017/02/15/snappy-libertine</id>
    <content type="html"><![CDATA[<p>Libertine is software suite for runnin X11 apps in non-X11 environments and installing deb-based applications on a system without dpkg. Snappy is a package management system to confine applications from one another. Wouldn&rsquo;t it be cool to run libertine as a snap?</p>

<p>Yes. Yes it would.</p>

<h3>snapd</h3>

<p>The first thing to install is snapd itself. You can find installation instructions for many Linux distros at <a href="https://snapcraft.io/docs/core/install">snapcraft.io</a>, but here&rsquo;s the simple command if you&rsquo;re on a debian-based operating system:</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'><span class="nv">$ </span>sudo apt install snapd
</span></code></pre></td></tr></table></div></figure>


<p>Ubuntu users may be surprised to find that snapd is already installed on their systems. snapd is the daemon for handling all things snappy: installing, removing, handling interface connections, etc.</p>

<h3>lxd</h3>

<p>We use lxd as our container backend for libertine in the snap. lxd is essentially a layer on top of lxc to give a better user experience. Fortunately for us, lxd has a snap all ready to go. Unfortunately, the snap version of lxd is incompatible with the deb-based version, so you&rsquo;ll need to completely remove that before continuing. Skip this step if you never installed lxd:</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='bash'><span class='line'><span class="nv">$ </span>sudo apt remove --purge lxd lxd-client
</span><span class='line'><span class="nv">$ </span>sudo zpool destroy lxd                 <span class="c"># if you use zfs</span>
</span><span class='line'><span class="nv">$ </span>sudo ip link <span class="nb">set </span>lxdbr0 down           <span class="c"># take down the bridge (lxdbr0 is the default)</span>
</span><span class='line'><span class="nv">$ </span>sudo brctl delbr lxdbr0                <span class="c"># delete the bridge</span>
</span></code></pre></td></tr></table></div></figure>


<p>For installing, in-depth instructions can be found <a href="https://stgraber.org/2016/10/17/lxd-snap-available/">in this blog post by one of the lxd devs</a>. In short, we&rsquo;re going to create a new group called <code>lxd</code>, add ourselves to it, and then add our own user ID and group ID to map to root within the container.</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'><span class="nv">$ </span>sudo groupadd --system lxd                      <span class="c"># Create the group on your system</span>
</span><span class='line'><span class="nv">$ </span>sudo usermod -G lxd -a <span class="nv">$USER</span>                    <span class="c"># Add the current user</span>
</span><span class='line'><span class="nv">$ </span>newgrp lxd                                      <span class="c"># update current session with new group</span>
</span><span class='line'><span class="nv">$ </span><span class="nb">echo </span>root:<span class="sb">`</span>id --user <span class="k">${</span><span class="nv">USER</span><span class="k">}</span><span class="sb">`</span>:1 &gt;&gt; /etc/subuid  <span class="c"># Setup subuid to map correctly</span>
</span><span class='line'><span class="nv">$ </span><span class="nb">echo </span>root:<span class="sb">`</span>id --group <span class="k">${</span><span class="nv">USER</span><span class="k">}</span><span class="sb">`</span>:1 &gt;&gt; /etc/subgid <span class="c"># Setup subgid to map correctly</span>
</span><span class='line'><span class="nv">$ </span>sudo snap install lxd                           <span class="c"># actually install the snap!</span>
</span></code></pre></td></tr></table></div></figure>


<p>We also need to initialize lxd manually. For me, the defaults all work great. The important pieces here are setting up a new network bridge and a new filestore for lxd to use. You can optionally use zfs if you have it installed (<code>zfsutils-linux</code> should do it on Ubuntu). Generally, I just hit &ldquo;return&rdquo; as fast as the questions show up and everything turns out alright. If anything goes wrong, you may need to manually delete zpools, network bridges, or reinstall the lxd snap. No warranties here.</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>sudo lxd init
</span><span class='line'>Do you want to configure a new storage pool <span class="o">(</span>yes/no<span class="o">)</span> <span class="o">[</span><span class="nv">default</span><span class="o">=</span>yes<span class="o">]</span>?
</span><span class='line'>Name of the new storage pool <span class="o">[</span><span class="nv">default</span><span class="o">=</span>default<span class="o">]</span>:
</span><span class='line'>Name of the storage backend to use <span class="o">(</span>dir or zfs<span class="o">)</span> <span class="o">[</span><span class="nv">default</span><span class="o">=</span>zfs<span class="o">]</span>:
</span><span class='line'>Create a new ZFS pool <span class="o">(</span>yes/no<span class="o">)</span> <span class="o">[</span><span class="nv">default</span><span class="o">=</span>yes<span class="o">]</span>?
</span><span class='line'>Would you like to use an existing block device <span class="o">(</span>yes/no<span class="o">)</span> <span class="o">[</span><span class="nv">default</span><span class="o">=</span>no<span class="o">]</span>?
</span><span class='line'>Would you like LXD to be available over the network <span class="o">(</span>yes/no<span class="o">)</span> <span class="o">[</span><span class="nv">default</span><span class="o">=</span>no<span class="o">]</span>?
</span><span class='line'>Would you like stale cached images to be updated automatically <span class="o">(</span>yes/no<span class="o">)</span> <span class="o">[</span><span class="nv">default</span><span class="o">=</span>yes<span class="o">]</span>?
</span><span class='line'>Would you like to create a new network bridge <span class="o">(</span>yes/no<span class="o">)</span> <span class="o">[</span><span class="nv">default</span><span class="o">=</span>yes<span class="o">]</span>?
</span><span class='line'>What should the new bridge be called <span class="o">[</span><span class="nv">default</span><span class="o">=</span>lxdbr0<span class="o">]</span>?
</span><span class='line'>What IPv4 address should be used <span class="o">(</span>CIDR subnet notation, “auto” or “none”<span class="o">)</span> <span class="o">[</span><span class="nv">default</span><span class="o">=</span>auto<span class="o">]</span>?
</span></code></pre></td></tr></table></div></figure>


<p>You should now be able to run <code>lxd.lxc list</code> without errors. It may warn you about running <code>lxd init</code>, but don&rsquo;t worry about that if your initialization succeeded.</p>

<h3>libertine</h3>

<p>Now we&rsquo;re onto the easy part. <code>libertine</code> is only available from <code>edge</code> channels in the app store, but we&rsquo;re fairly close to having a version that we could push into more stable channels. For the latest and greatest libertine:</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='bash'><span class='line'><span class="nv">$ </span>sudo snap install --edge libertine
</span><span class='line'><span class="nv">$ </span>sudo snap connect libertine:libertined-client libertine:libertined
</span></code></pre></td></tr></table></div></figure>


<p>If we want libertine to work fully, we need to jump through a couple of hoops. For starters, dbus-activation is not fully functional at this time for snaps. Lucky for us, we can fake this by either running the d-bus service manually (<code>/snap/bin/libertined</code>), or by adding this file to <code>/usr/share/dbus-1/services/com.canonical.libertine.Service.service</code></p>

<figure class='code'><figcaption><span>/usr/share/dbus-1/services/com.canonical.libertine.Service.service</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='bash'><span class='line'><span class="o">[</span>D-BUS Service<span class="o">]</span>
</span><span class='line'><span class="nv">Name</span><span class="o">=</span>com.canonical.libertine.Service
</span><span class='line'><span class="nv">Exec</span><span class="o">=</span>/snap/bin/libertine.libertined --cache-output
</span></code></pre></td></tr></table></div></figure>


<p>Personally, I always create the file, which will allow libertined to start automatically on the session bus whenever a user calls it. Hopefully d-bus activation will be fixed sooner rather than later, but this works fine for now.</p>

<p>Another issue is that existing deb-based libertine binaries may conflict with the snap binaries. We can fix this by adjusting <code>PATH</code> in our <code>.bashrc</code> file:</p>

<figure class='code'><figcaption><span>$HOME/.bashrc</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='bash'><span class='line'><span class="c"># ...</span>
</span><span class='line'><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span>/snap/bin:<span class="nv">$PATH</span>
</span></code></pre></td></tr></table></div></figure>


<p>This will give higher priority to snap binaries (which should be the default, IMO). One more thing to fix before running full-force is to add an environment variable to <code>/etc/environment</code> such that the correct libertine binary is picked up in Unity 8:</p>

<figure class='code'><figcaption><span>/etc/environment</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='bash'><span class='line'><span class="c"># ...</span>
</span><span class='line'><span class="nv">UBUNTU_APP_LAUNCH_LIBERTINE_LAUNCH</span><span class="o">=</span>/snap/bin/libertine-launch
</span></code></pre></td></tr></table></div></figure>


<p>OK! Now we&rsquo;re finally ready to start creating containers and installing packages:</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='bash'><span class='line'><span class="nv">$ </span>libertine-container-manager create -i my-container
</span><span class='line'><span class="c"># ... (this could take a few minutes)</span>
</span><span class='line'><span class="nv">$ </span>libertine-container-manager install-package -i my-container -p xterm
</span><span class='line'><span class="c"># ... (and any other packages you may want)</span>
</span></code></pre></td></tr></table></div></figure>


<p>If you want to launch your apps in Unity 7 (why not?):</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='bash'><span class='line'><span class="nv">$ </span>libertine-launch -i my-container xterm
</span><span class='line'><span class="c"># ... (lots of ourput, hopefully an open window!)</span>
</span></code></pre></td></tr></table></div></figure>


<p>When running Unity 8, your apps should show up in the app drawer with all the other applications. This will all depend on libertined running, so make sure that it runs at startup!</p>

<p>I&rsquo;ve been making a lot of improvements on the snap lately, especially as the ecosystem continues to mature. One day we plan for a much smoother experience, but this current setup will let us work out some of the kinks and find issues. If you want to switch back the deb-based libertine, you can just install it through <code>apt</code> and remove the change to <code>/etc/environment</code>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[2016 Retrospective]]></title>
    <link href="https://larry-price.com/blog/2016/12/27/2016-year-in-review/"/>
    <updated>2016-12-27T13:35:56-05:00</updated>
    <id>https://larry-price.com/blog/2016/12/27/2016-year-in-review</id>
    <content type="html"><![CDATA[<p>This has been a unique year for me, and I wanted to quickly lay out what I&rsquo;ve accomplished and where I think I&rsquo;m going for the coming year. This is now officially a tradition at three posts (see: <a href="https://larry-price.com/blog/2014/12/31/2014-retrospective/">2014</a> and <a href="https://larry-price.com/blog/2016/01/03/2015-year-in-review/">2015</a>).</p>

<h3>Revisiting 2016&rsquo;s Goals</h3>

<p>These are the goals I set for myself at the start of the year and how I met or missed them:</p>

<ul>
<li>Spend Money

<ul>
<li>I wanted to become less of a miser and spend more money. Note that this is not for bragging purposes, just that I am naturally very frugal and hesitant to spend money. I think we did a pretty good job, though! For starters, I swapped out my commuter car for a tech-heavy crossover. We stayed in a really cool art-hotel in downtown Cincinnati in the Spring, drove across the country for a big Yellowstone trip in early Summer, stayed at the Indiana Dunes for a few days in the Fall, and took a brief trip to Madison, WI, shortly thereafter. I bought a nice sitting/standing desk and chair for my home office. I paid the entry fee to go to GenCon for a day. Our fridge, dishwasher, and furnace all died one weekend, and it ended with me buying upgraded, modern appliances. I&rsquo;ve also been keeping the post office busy with plenty of orders off Amazon, and I&rsquo;ve been trying to Kickstart more games that I think deserve attention. I also found a new hobby in homebrewing which has been a great use of fun-money.</li>
</ul>
</li>
<li>Back Into Web

<ul>
<li>At the start of 2016, I though I really wanted to do more web work. Turns out I&rsquo;ve done a 180 on this one, and I now work on primarily desktop/mobile with minimal web work, and I wouldn&rsquo;t have it any other way for the time being.</li>
</ul>
</li>
<li>Work With Others

<ul>
<li>In 2015, I worked alone a lot. In 2016, I joined a new company where I work remotely. Although I don&rsquo;t necessarily see my coworkers every day, I am working on projects with multiple developers and communicating constantly with my teammates (and others) through chat. Working with others again has helped me grow socially and become a better engineer.</li>
</ul>
</li>
<li>Become Part of an Open-Source Community

<ul>
<li>I really wanted to better integrate FLOSS into my life and my career, and I believe I&rsquo;ve hit the jackpot. My job is to build popular open-source operating system Ubuntu, where all the code I write is public and generally GPLv3. My job is to write open-source software, and to interact with the community. I use my own software and report/fix bugs that affect me all the time.</li>
</ul>
</li>
<li>Good Vibes

<ul>
<li>I was feeling a bit down at the end of 2015, and I wanted to be a more positive person in 2016. Although there were some depressing things going on worldwide in 2016, I am generally happier with my personal and professional life on a micro-level.</li>
</ul>
</li>
</ul>


<h3>Surprise Victories</h3>

<ul>
<li>New Job

<ul>
<li>The big one! After almost four years at SEP, I transitioned to a new role at Canonical. I get to work on Ubuntu, one of my favorite open-source projects, as my full-time job. This also means I get to work remotely, dropping my commute from 30 miles in 2012 to 3 miles in 2014 to 50 feet in 2016. I&rsquo;ve been having a great time working on software that&rsquo;s in the public spotlight, working with the community, and traveling every few months to see my coworkers. With this new job, I&rsquo;ve also had the opportunity to visit Europe for the first time this year.</li>
</ul>
</li>
<li>Less Own-Time Work

<ul>
<li>Although I&rsquo;ve hit pretty hard in the past that developers should do some learning outside of work, this year likely contained the least own-time work I&rsquo;ve ever done. I&rsquo;ve been finding joys in non-software hobbies and home maintenance, and working on Ubuntu as my full-time job has made me less needy for doing open-source work in my off-hours. I tend to respond to bugs and Github PRs at any hour, and I follow more technical people on social media than I used to. I think this stems from a satisfaction from the learning I do throughout the day, and the difficulty of separating work-life and home-life when one works at home.</li>
</ul>
</li>
<li>FOSDEM

<ul>
<li>Yesterday, I learned that I&rsquo;ll be giving a talk at <a href="https://fosdem.org/2017/">FOSDEM</a>. I&rsquo;m very excited (and nervous) to give my first-ever conference talk in Brussels this February.</li>
</ul>
</li>
<li>Homebrewing

<ul>
<li>I picked up homebrewing beer at the start of 2016, and I love it. I started with simple pre-made extract kits, but have worked my way up to creating my own all-grain recipes and labels. Brewing is a fun, tasty hobby giving me some creative, manual labor to break the mold of always doing computer work.</li>
</ul>
</li>
<li>Books

<ul>
<li>I read a significant amount of non-software books this year. Some of my favorites (disclosure: referral links): <a href="https://www.amazon.com/gp/product/0385333781/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=larpriandthee-20&amp;camp=1789&amp;creative=9325&amp;linkCode=as2&amp;creativeASIN=0385333781&amp;linkId=4dfaf23d21ba24414455e3e63b13fb26"><em>Player Piano</em> by Kurt Vonnegut</a>, <a href="https://www.amazon.com/gp/product/0143128221/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=larpriandthee-20&amp;camp=1789&amp;creative=9325&amp;linkCode=as2&amp;creativeASIN=0143128221&amp;linkId=fa499fb309ea38b089e65cf5f76280ab"><em>Where Am I Now?</em> by Mara Wilson</a>, <a href="https://www.amazon.com/gp/product/0385722192/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=larpriandthee-20&amp;camp=1789&amp;creative=9325&amp;linkCode=as2&amp;creativeASIN=0385722192&amp;linkId=e5f40fba83539802415a677829b41295"><em>Lullaby</em> by Chuck Palahniuk</a>, <a href="https://www.amazon.com/gp/product/1846973449/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=larpriandthee-20&amp;camp=1789&amp;creative=9325&amp;linkCode=as2&amp;creativeASIN=1846973449&amp;linkId=09907a1df99eac78c9badfa88e1f57d8"><em>Embed with Games</em> by Cara Ellison</a>, and <a href="https://www.amazon.com/gp/product/1632153661/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=larpriandthee-20&amp;camp=1789&amp;creative=9325&amp;linkCode=as2&amp;creativeASIN=1632153661&amp;linkId=c1a87961a757bba8891aeba4958c71c5"><em>Bitch Planet Volume 1</em> by Kelly Sue Deconnick</a>.</li>
</ul>
</li>
<li>Spotify

<ul>
<li>Spotify is very good for listening to whatever music I want anytime, especially now that I work at home. If you really like a band, you should still buy their music or merch through their website to make sure they get paid to keep existing.</li>
</ul>
</li>
</ul>


<h3>2017 Goals</h3>

<ul>
<li>Local

<ul>
<li>I&rsquo;d like to make sure I stay involved locally, especially as I continue to work from home. I&rsquo;ve let my Golang group dwindle over the past few months, and I&rsquo;d like to see us back up to our numbers at the start of 2016. If possible, I&rsquo;d also like to attend other meetups and meet more local devs.</li>
</ul>
</li>
<li>Linux Greybeard

<ul>
<li>This is a slow process, but I want to get better at using Linux in general. I&rsquo;ve been surprised at how much I&rsquo;ve learned about the low-level workings of Ubuntu over the past 9 months. I&rsquo;m excited to see what I can learn over the next year, especially as I&rsquo;ll likely move into a different codebase at some point this year.</li>
</ul>
</li>
<li>More talking

<ul>
<li>I&rsquo;m very excited to be giving a talk at FOSDEM this year, but I would enjoy doing such things more regularly. It doesn&rsquo;t necessarily have to be at conferences, as I could do meetups much more easily. I need to try to get back into blogging more regularly. Additionally, I&rsquo;ve recently been kicking around ideas for a discussion-based podcast on the worst parts of software development, although that may have already been done to death. Contact if interested.</li>
</ul>
</li>
<li>Transition Web Tooling

<ul>
<li>I would like to switch over my analytics systems to use a personal Piwik instance, and I would love to replace the (hopefully unobtrusive) ads on this site with some kind of tip jar system. I would also like to update this blog to use a Let&rsquo;s Encrypt certificate, as well as <a href="https://ollertapp.com">Ollert</a> once I&rsquo;ve been given full control.</li>
</ul>
</li>
<li>Kegging

<ul>
<li>In my homebrewing, I&rsquo;ve been bottling my beers. This is generally ok, but I think the beer would be consumed faster if I kegged it and could fill growlers for my friends and family. Getting started with kegging is expensive, requiring the purchase of kegs, tanks, parts, and some sort of refrigeration unit. By the end of the year, I intend to have a kegerator-style setup with the ability to stow and distribute from two kegs.</li>
</ul>
</li>
<li>Moving

<ul>
<li>My wife is looking into graduate schools for Fall 2017, and has already been accepted by one. I&rsquo;m currently assuming a big part of my life this Spring/Summer will be finding and adjusting to a new home.</li>
</ul>
</li>
<li>Active Activism

<ul>
<li>I&rsquo;ve complained a lot about our government and the way the world works on social media, at the &ldquo;water cooler&rdquo;, and privately to my wife, but it&rsquo;s become obvious that passive activism isn&rsquo;t good enough. Signing petitions and <a href="http://neveragain.tech">pledges</a> are nice gestures, but are more meaningful when backed up by real action. I&rsquo;d like to do something, though I&rsquo;m not sure what at the moment. By the end of 2017, I would like to, at minimum, have a plan to donate, join, create, or generally be more involved.</li>
</ul>
</li>
</ul>


<h3>Adieu, 2016</h3>

<p>Major changes in my life, career, and the world at large have made 2016 a memorable year for me. I highly encourage you to reflect on the year you&rsquo;ve had and think about what you can do to make 2017 great. Happy new year!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Confining a Snapped X11 Application]]></title>
    <link href="https://larry-price.com/blog/2016/12/10/confining-a-snapped-x11-application/"/>
    <updated>2016-12-10T17:30:38-05:00</updated>
    <id>https://larry-price.com/blog/2016/12/10/confining-a-snapped-x11-application</id>
    <content type="html"><![CDATA[<p><em>Looking for the code? Look no further: <a href="https://github.com/larryprice/pingus-snap">https://github.com/larryprice/pingus-snap</a></em></p>

<p>In my <a href="https://larry-price.com/blog/2016/12/07/creating-a-snap-from-existing-deb-packages/">last post</a>, I demonstrated creating a snap package for an application available in the archive. I left that application unconfined, which is taboo in the long run if we want our system to be secure. In a few steps, we can add the necessary components to confine our <code>pingus</code> snap.</p>

<p>For reference, this is the original <code>snapcraft.yaml</code> file for creating a <code>pingus</code> snap, except that we&rsquo;ve updated the <code>confinement</code> property to <code>strict</code>:</p>

<figure class='code'><figcaption><span>snapcraft.yaml</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>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="l-Scalar-Plain">name</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">pingus</span>
</span><span class='line'><span class="l-Scalar-Plain">version</span><span class="p-Indicator">:</span> <span class="s">&#39;0.1&#39;</span>
</span><span class='line'><span class="l-Scalar-Plain">summary</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Free Lemmings(TM) clone</span>
</span><span class='line'><span class="l-Scalar-Plain">description</span><span class="p-Indicator">:</span> <span class="p-Indicator">|</span>
</span><span class='line'>    <span class="no">Pingus is a free clone of the popular Lemmings game.</span>
</span><span class='line'>    <span class="no">|</span>
</span><span class='line'>    <span class="no">Your goal is to guide a horde of penguins through a world full of obstacles</span>
</span><span class='line'>    <span class="no">and penguin traps to safety. Although penguins (unlike lemmings) are rather</span>
</span><span class='line'>    <span class="no">smart, they sometimes lack the necessary overview and now rely on you to</span>
</span><span class='line'>    <span class="no">save them.</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">grade</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">devel</span>
</span><span class='line'><span class="l-Scalar-Plain">confinement</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">strict</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">parts</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">archives</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">plugin</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">nil</span>
</span><span class='line'>    <span class="l-Scalar-Plain">stage-packages</span><span class="p-Indicator">:</span>
</span><span class='line'>      <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">pingus</span>
</span><span class='line'>  <span class="l-Scalar-Plain">env</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">plugin</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">dump</span>
</span><span class='line'>    <span class="l-Scalar-Plain">organize</span><span class="p-Indicator">:</span>
</span><span class='line'>      <span class="l-Scalar-Plain">pingus.wrapper</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">usr/bin/pingus</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">apps</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">pingus</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">command</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">pingus</span>
</span></code></pre></td></tr></table></div></figure>


<p>If you&rsquo;re feeling bold, you can build and install the snap from here, but be warned that this led me into an ncurses nightmare that I had to forcibly kill. That&rsquo;s largely because <code>pingus</code> depends on X11, which is not available out-of-the-box once we&rsquo;ve confined our snap. If we want to use X11, we&rsquo;re going to need to connect to it using the snap-land concept of <a href="http://snapcraft.io/docs/core/interfaces">interfaces</a>. Interfaces allow us to access shared resources and connections provided by the system or other snaps. There&rsquo;s some terminology to grapple with here, but the bottom line is that a &ldquo;slot&rdquo; provides an interface which a &ldquo;plug&rdquo; connects to. You can see a big list of available interfaces with descriptions <a href="http://snapcraft.io/docs/reference/interfaces">on the wiki</a>. Our <code>pingus</code> app will &ldquo;plug&rdquo; into the X11 interface&rsquo;s &ldquo;slot&rdquo;:</p>

<figure class='code'><figcaption><span>snapcraft.yaml</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='yaml'><span class='line'><span class="c1"># ...</span>
</span><span class='line'><span class="l-Scalar-Plain">apps</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">pingus</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">command</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">pingus</span>
</span><span class='line'>    <span class="l-Scalar-Plain">plugs</span><span class="p-Indicator">:</span>
</span><span class='line'>      <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">x11</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can build and install the new snap with the <code>--dangerous</code> flag for your local confined snap. After that, you can verify the interface connection with the <code>snap interfaces</code> command:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>snapcraft
</span><span class='line'><span class="nv">$ </span>sudo snap install --dangerous pingus_0.1_amd64.snap
</span><span class='line'>pingus 0.1 installed
</span><span class='line'><span class="nv">$ </span>snap interfaces
</span><span class='line'>Slot                     Plug
</span><span class='line'>:alsa                    -
</span><span class='line'><span class="c"># ...</span>
</span><span class='line'>:upower-observe          -
</span><span class='line'>:x11                     pingus
</span></code></pre></td></tr></table></div></figure>


<p>Now, when we run <code>pingus</code>&hellip; it works! Well, video works. If you want sound, we&rsquo;ll also need the <code>pulseaudio</code> interface:</p>

<figure class='code'><figcaption><span>snapcraft.yaml</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>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="c1"># ...</span>
</span><span class='line'><span class="l-Scalar-Plain">apps</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">pingus</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">command</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">pingus</span>
</span><span class='line'>    <span class="l-Scalar-Plain">plugs</span><span class="p-Indicator">:</span>
</span><span class='line'>      <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">x11</span>
</span><span class='line'>      <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">pulseaudio</span>
</span></code></pre></td></tr></table></div></figure>


<p>Once again: build, install, and run&hellip; et voilà! Is it just me, or was that surprisingly painless? Of course, not all applications live such isolated lives. Make note that the x11 interface is supposed to be a transitional interface, meaning that we would rather our app fully transition to Mir or some alternative. To go a step further with this snap, we could create a <code>snapcraft.yaml</code> to build from source to get the absolute latest version of our app. At this point, we can change our <code>grade</code> property to <code>stable</code> and feel good about something that we could push to the store for review.</p>

<p><em>Any code you see here is free software. Find the project here: <a href="https://github.com/larryprice/pingus-snap">https://github.com/larryprice/pingus-snap</a></em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Building Snaps From Archived Packages]]></title>
    <link href="https://larry-price.com/blog/2016/12/07/creating-a-snap-from-existing-deb-packages/"/>
    <updated>2016-12-07T22:10:08-05:00</updated>
    <id>https://larry-price.com/blog/2016/12/07/creating-a-snap-from-existing-deb-packages</id>
    <content type="html"><![CDATA[<p>If you haven&rsquo;t heard, <a href="//snapcraft.io">snaps</a> are a new, modern packaging format made by the guys at Ubuntu. Snaps give every app a confined environment to live in, making desktops more secure and dependencies less of a hassle. One common way to create a snap is to simply use existing packages from the Ubuntu archives.</p>

<p>Let&rsquo;s try to create a snap for the game <a href="https://lgdb.org/game/pingus">pingus</a>. <code>pingus</code> is a great little Lemmings clone that we can easily convert to a snap. We&rsquo;ll start by installing the necessary dependencies for snap building (see <a href="//snapcraft.io/create/">the snapcraft website</a> for more):</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'><span class="nv">$ </span>sudo apt install snapcraft
</span></code></pre></td></tr></table></div></figure>


<p>Now we can initialize a project directory with snapcraft:</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='bash'><span class='line'><span class="nv">$ </span>mkdir -p pingus-snap <span class="o">&amp;&amp;</span> <span class="nb">cd </span>pingus-snap
</span><span class='line'><span class="nv">$ </span>snapcraft init
</span></code></pre></td></tr></table></div></figure>


<p><code>snapcraft init</code> creates the following sample file to give us an idea of what we&rsquo;ll need to provide.</p>

<figure class='code'><figcaption><span>snapcraft.yaml</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>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="l-Scalar-Plain">name</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">my-snap-name</span> <span class="c1"># you probably want to &#39;snapcraft register &lt;name&gt;&#39;</span>
</span><span class='line'><span class="l-Scalar-Plain">version</span><span class="p-Indicator">:</span> <span class="s">&#39;0.1&#39;</span> <span class="c1"># just for humans, typically &#39;1.2+git&#39; or &#39;1.3.2&#39;</span>
</span><span class='line'><span class="l-Scalar-Plain">summary</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Single-line elevator pitch for your amazing snap</span> <span class="c1"># 79 char long summary</span>
</span><span class='line'><span class="l-Scalar-Plain">description</span><span class="p-Indicator">:</span> <span class="p-Indicator">|</span>
</span><span class='line'>  <span class="no">This is my-snap&#39;s description. You have a paragraph or two to tell the</span>
</span><span class='line'>  <span class="no">most important story about your snap. Keep it under 100 words though,</span>
</span><span class='line'>  <span class="no">we live in tweetspace and your description wants to look good in the snap</span>
</span><span class='line'>  <span class="no">store.</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">grade</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">devel</span> <span class="c1"># must be &#39;stable&#39; to release into candidate/stable channels</span>
</span><span class='line'><span class="l-Scalar-Plain">confinement</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">devmode</span> <span class="c1"># use &#39;strict&#39; once you have the right plugs and slots</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">parts</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">my-part</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="c1"># See &#39;snapcraft plugins&#39;</span>
</span><span class='line'>    <span class="l-Scalar-Plain">plugin</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">nil</span>
</span></code></pre></td></tr></table></div></figure>


<p>Most of these values for our <code>pingus</code> snap should be obvious. The interesting markup here is in <code>parts</code>, which is where we&rsquo;ll describe how to build our snap. We&rsquo;ll start by taking advantage of the <code>nil</code> plugin to simply unpack the <code>pingus</code> deb from the archive. We define our list of debs to install in a list called <code>stage-packages</code>. We&rsquo;ll also define another section, <code>apps</code>, to tell <code>snapcraft</code> what binaries we want to be able to execute. In our case, this will just be the <code>pingus</code> command. Here&rsquo;s what my first draft looks like:</p>

<figure class='code'><figcaption><span>snapcraft.yaml</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>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="l-Scalar-Plain">name</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">pingus</span>
</span><span class='line'><span class="l-Scalar-Plain">version</span><span class="p-Indicator">:</span> <span class="s">&#39;0.1&#39;</span>
</span><span class='line'><span class="l-Scalar-Plain">summary</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Free Lemmings(TM) clone</span>
</span><span class='line'><span class="l-Scalar-Plain">description</span><span class="p-Indicator">:</span> <span class="p-Indicator">|</span>
</span><span class='line'>    <span class="no">Pingus is a free clone of the popular Lemmings game.</span>
</span><span class='line'>    <span class="no">|</span>
</span><span class='line'>    <span class="no">Your goal is to guide a horde of penguins through a world full of obstacles</span>
</span><span class='line'>    <span class="no">and penguin traps to safety. Although penguins (unlike lemmings) are rather</span>
</span><span class='line'>    <span class="no">smart, they sometimes lack the necessary overview and now rely on you to</span>
</span><span class='line'>    <span class="no">save them.</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">grade</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">devel</span>
</span><span class='line'><span class="l-Scalar-Plain">confinement</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">devmode</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">parts</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">archives</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">plugin</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">nil</span>
</span><span class='line'>    <span class="l-Scalar-Plain">stage-packages</span><span class="p-Indicator">:</span>
</span><span class='line'>      <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">pingus</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">apps</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">pingus</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">command</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">usr/games/pingus</span>
</span></code></pre></td></tr></table></div></figure>


<p>Nice, right? Building and installing our snap is easy:</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='bash'><span class='line'><span class="nv">$ </span>snapcraft
</span><span class='line'><span class="nv">$ </span>sudo snap install --devmode pingus_0.1_amd64.snap
</span><span class='line'>pingus 0.1 installed
</span></code></pre></td></tr></table></div></figure>


<p>We used <code>devmode</code> here because our app will be running unconfined (a topic for another blog post). Now, for the moment of truth! The snap tools automatically put our new app in <code>PATH</code>, so we can just run <code>pingus</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>pingus
</span><span class='line'>/snap/pingus/x2/usr/games/pingus: 2: <span class="nb">exec</span>: /usr/lib/games/pingus/pingus: not found
</span></code></pre></td></tr></table></div></figure>


<p>¡Ay, caramba! We&rsquo;ve run into a fairly common issue while snapping legacy software: <strong>hardcoded paths</strong>. Fortunately, the corresponding <code>pingus</code> executable is very simple. It&rsquo;s trying to execute a command living in <code>/usr/lib/games/pingus</code>, which is not in our snap&rsquo;s <code>PATH</code>. The easiest way to fix this is to fix the <code>pingus</code> executable. Since we don&rsquo;t want to spend time modifying the upstream to use a relative path, we can create our own version of the <code>pingus</code> wrapper locally and copy it into our snap. The only change to this new wrapper will be prepending the snap&rsquo;s install path <code>$SNAP</code> to the absolute paths:</p>

<figure class='code'><figcaption><span>pingus.wrapper</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='bash'><span class='line'><span class="c">#!/bin/sh</span>
</span><span class='line'><span class="nb">exec</span> <span class="nv">$SNAP</span>/usr/lib/games/pingus/pingus --datadir <span class="nv">$SNAP</span>/usr/share/games/pingus/data <span class="nv">$@</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we can update our yaml file with a new part called <code>env</code> which will use the <code>dump</code> plugin to copy our wrapper file into the snap. We&rsquo;ll also update our command to call the wrapper:</p>

<figure class='code'><figcaption><span>snapcraft.yaml</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>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="c1"># ...</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">parts</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">archives</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">plugin</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">nil</span>
</span><span class='line'>    <span class="l-Scalar-Plain">stage-packages</span><span class="p-Indicator">:</span>
</span><span class='line'>      <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">pingus</span>
</span><span class='line'>  <span class="l-Scalar-Plain">env</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">plugin</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">dump</span>
</span><span class='line'>    <span class="l-Scalar-Plain">organize</span><span class="p-Indicator">:</span>
</span><span class='line'>      <span class="l-Scalar-Plain">pingus.wrapper</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">usr/bin/pingus</span>
</span><span class='line'>
</span><span class='line'><span class="l-Scalar-Plain">apps</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">pingus</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="l-Scalar-Plain">command</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">pingus</span>
</span></code></pre></td></tr></table></div></figure>


<p>When you run <code>snapcraft</code> this time, the <code>env</code> part will be built. After performing another install, you can run <code>pingus</code>, and you should be greeted with one of the best Lemmings clones available! Because we&rsquo;re running unconfined in devmode, this all just works without any issues. I intend to write another blog post in the near future with the details on confining <code>pingus</code>, so look out for that soon. I may also go into detail on building more complex cases, such as building snaps from source and building custom plugins, or reviewing a case study such as the <code>libertine</code> snap.</p>

<p>For much, much more on snaps, be sure to visit <a href="//snapcraft.io/create/">snapcraft.io</a>. If you&rsquo;re looking for a published version of pingus as a snap, you can try <code>sudo snap install --devmode --beta pingus-game</code>, and you can run the game with <code>pingus-game.pingus</code>.</p>

<p><em>Source code available at <a href="https://github.com/larryprice/pingus-snap">https://github.com/larryprice/pingus-snap</a>.</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Clean Package Building With Pbuilder]]></title>
    <link href="https://larry-price.com/blog/2016/09/27/clean-package-building-with-pbuilder/"/>
    <updated>2016-09-27T21:50:00-04:00</updated>
    <id>https://larry-price.com/blog/2016/09/27/clean-package-building-with-pbuilder</id>
    <content type="html"><![CDATA[<p>Whether I&rsquo;m adding dependencies, updating package names, or creating new package spins, I always have issues testing my debian packages. Something will work locally, only to fail on jenkins under a clean environment. Fortunately, there&rsquo;s a nifty tool called <code>pbuilder</code> that exists to help out in these situations. <code>pbuilder</code> uses a chroot to set up a clean environment to build packages, and can even be used to build packages for systems with architectures different from your own.</p>

<p><em>Note: All code samples were originally written from a machine running Ubuntu 16.10 64-bit. Your mileage may vary.</em></p>

<h3>Clean builds for current distro</h3>

<p>Given a typical debian-packaged project with a <code>debian</code> directory (<code>control</code>, <code>rules</code>, <code>.install</code>), you can use <code>debuild</code> to build a package from your local environment:</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="nv">$ </span><span class="nb">cd </span>my-project
</span><span class='line'><span class="nv">$ </span>debuild
</span><span class='line'>...
</span><span class='line'><span class="nv">$ </span>ls ../*.deb
</span><span class='line'>my-project.deb
</span></code></pre></td></tr></table></div></figure>


<p>This works pretty well for sanity checks, but sometimes knowing your sane just isn&rsquo;t quite enough. My development environment is filled with libraries and files installed in all kinds of weird ways and in all kinds of strange places, so there&rsquo;s a good chance packages built successfully on my machine may not work on everyone&rsquo;s machine. To solve this, I can install <code>pbuilder</code> and set up my first chroot:</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='bash'><span class='line'><span class="nv">$ </span><span class="c"># install pbuilder and its dependencies</span>
</span><span class='line'><span class="nv">$ </span>sudo apt-get install pbuilder debootstrap devscripts
</span><span class='line'><span class="nv">$ </span><span class="c"># create a chroot for your current distro with build-essential pre-installed</span>
</span><span class='line'><span class="nv">$ </span>sudo pbuilder create --debootstrapopts --variant<span class="o">=</span>buildd
</span></code></pre></td></tr></table></div></figure>


<p>Since I use <code>debuild</code> pretty frequently, I also rely on <code>pdebuild</code> which performs <code>debuild</code> inside of the clean chroot environment, temporarily installing the needed dependencies listed in the <code>control</code> file.</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='bash'><span class='line'><span class="nv">$ </span><span class="nb">cd </span>my-project
</span><span class='line'><span class="nv">$ </span>pdebuild
</span><span class='line'><span class="nv">$ </span>ls /var/cache/pbuilder/result/*.deb
</span><span class='line'>my-project.deb
</span></code></pre></td></tr></table></div></figure>


<p>Alternatively, I could create the <code>.dsc</code> file and then use <code>pbuilder</code> to create the package from there:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span><span class="c"># generate a dsc file however you like</span>
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>my-project
</span><span class='line'><span class="nv">$ </span>bzr-builddeb -- -us -uc
</span><span class='line'><span class="nv">$ </span><span class="nb">cd</span> ..
</span><span class='line'><span class="nv">$ </span><span class="c"># use pbuilder to create package</span>
</span><span class='line'><span class="nv">$ </span>sudo pbuilder build my-project.dsc
</span><span class='line'><span class="nv">$ </span>ls /var/cache/pbuilder/result/*.deb
</span><span class='line'>my-project.deb
</span></code></pre></td></tr></table></div></figure>


<h3>Clean cross builds</h3>

<p>Let&rsquo;s say that you need to build for an older distribution of Ubuntu on a weird architecture. For this example, let&rsquo;s say <code>vivid</code> with <code>armhf</code>. We can use <code>pbuilder-dist</code> to verify and build our packages for other distros and architectures:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span><span class="c"># create the chroot, once again with build-essential pre-installed</span>
</span><span class='line'><span class="nv">$ </span>pbuilder-dist vivid armhf create --debootstrapopts --variant<span class="o">=</span>buildd
</span><span class='line'><span class="nv">$ </span><span class="c"># the above command could take a while, but once it&#39;s finished</span>
</span><span class='line'><span class="nv">$ </span><span class="c"># we can attempt to build our package using a .dsc file</span>
</span><span class='line'><span class="nv">$ </span>pbuilder-dist vivid armhf build my-project-dsc
</span><span class='line'><span class="nv">$ </span>ls ~/pbuilder/vivid-armhf_result/*.deb
</span><span class='line'>my-project.deb
</span></code></pre></td></tr></table></div></figure>


<h3>Custom, persistent chroot changes</h3>

<p>In some cases, you may need to enable other archives or install custom software in your chroot. In the case of our vivid-armhf chroot, let&rsquo;s add the <a href="https://launchpad.net/~ci-train-ppa-service/+archive/ubuntu/stable-phone-overlay">stable-overlay ppa</a> which updates the outdated vivid with some more modern versions of packages.</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span><span class="c"># login to our vivid-armhf chroot, and save state when we&#39;re finished</span>
</span><span class='line'><span class="nv">$ </span><span class="c"># if --save-after-login is omitted, a throwaway chroot will be used</span>
</span><span class='line'><span class="nv">$ </span>pbuilder vivid armhf login --save-after-login
</span><span class='line'><span class="o">(</span>chroot<span class="o">)</span> <span class="nv">$ </span><span class="c"># install the package container add-apt-repository for convenience</span>
</span><span class='line'><span class="o">(</span>chroot<span class="o">)</span> <span class="nv">$ </span>apt install software-properties-common
</span><span class='line'><span class="o">(</span>chroot<span class="o">)</span> <span class="nv">$ </span>add-apt-repository ppa:ci-train-ppa-service/stable-phone-overlay
</span><span class='line'><span class="o">(</span>chroot<span class="o">)</span> <span class="nv">$ </span><span class="nb">exit</span>
</span><span class='line'><span class="nv">$ </span><span class="c"># update packages in the chroot</span>
</span><span class='line'><span class="nv">$ </span>pbuilder-dist vivid armhf update
</span></code></pre></td></tr></table></div></figure>


<p><code>pbuilder</code> and chroots are powerful tools in the world of packaging and beyond. There are scripting utilities, as well as pre- and post-build hooks which can customize your builds. There are ways to speed up clean builds using local caches or other &ldquo;cheats&rdquo;. You could use the throwaway terminal abilities to create and destroy tiny worlds as you please. All of this is very similar to the utility which comes from using docker and lxc, though the underlying &ldquo;container&rdquo; is quite a bit different. Using <code>pbuilder</code> seems to have a much lower threshold for setup, so I prefer it over docker for clean build environments, but I believe docker/lxc to be the better tool for managing the creation of consistent virtual environments.</p>

<p><em>Further reading:</em></p>

<p><a href="https://wiki.ubuntu.com/PbuilderHowto">Pbuilder HowTo on the Ubuntu wiki</a>
<a href="https://wiki.debian.org/PbuilderTricks">Pbuilder tricks from the debian wiki</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Getting Started With Python Mocking and Patching]]></title>
    <link href="https://larry-price.com/blog/2016/09/07/getting-started-with-python-mocks-from-a-c-plus-plus-perspective/"/>
    <updated>2016-09-07T23:00:09-04:00</updated>
    <id>https://larry-price.com/blog/2016/09/07/getting-started-with-python-mocks-from-a-c-plus-plus-perspective</id>
    <content type="html"><![CDATA[<p>I currently write a lot of python and C++. Although I religiously unit test my C++ code, I&rsquo;m a bit ashamed to say that I haven&rsquo;t had much experience with python unit testing until recently. You know how it is - python is one of those interpreted languages, you mostly use it to do quick hacks, it doesn&rsquo;t <em>need</em> tests. Until you&rsquo;ve written your entire D-Bus service using python, and every time you make a code change <em>a literal python</em> appears on the screen to crash your computer. So I&rsquo;ve started writing a bunch of tests and found (as expected) a tangled mess of dependencies and system calls.</p>

<p>In many C-like languages, you can fix most of your dependency problems with <a href="https://stackoverflow.com/questions/346372/whats-the-difference-between-faking-mocking-and-stubbing#answer-346440">The Big Three</a>: mocks, fakes, and stubs. A fake is an actual implementation of an interface used for non-production environments, a stub is an implementation of an interface returning a pre-conceived result, and a mock is a wrapper around an interface allowing a programmer to accurately map what actions were performed on the object. In C-like languages, you use <a href="https://en.wikipedia.org/wiki/Dependency_injection">dependency injection</a> to give our classes fakes, mocks, or stubs instead of real objects during testing.</p>

<p>The good news is that we can also use dependency injection in python! However, I found that relying solely on dependency injection would pile on more dependencies than I wanted and was not going to work to cover all my system calls. But python is a dynamic language. In python, you can literally change the definition of a class inside of another class. We call this operation <strong>patch</strong> and you can use it extensively in testing to do some pretty cool stuff.</p>

<h3>Code Under Test</h3>

<p>Let&rsquo;s define some code to test. For all of these examples, I&rsquo;ll be using python3.5.2 with the <a href="https://docs.python.org/3/library/unittest.html">unittest</a> and <a href="https://docs.python.org/3/library/unittest.mock.html">unittest.mock</a> libs on Ubuntu 16.10. You can the final versions of these code samples <a href="https://github.com/larryprice/python-mocks-blog-post">on github</a>.</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>
<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>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">randint</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">WorkerStrikeException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
</span><span class='line'>    <span class="k">pass</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Worker</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span><span class='line'>    <span class="sd">&quot;&quot;&quot;</span>
</span><span class='line'><span class="sd">    A Worker will work a full 40 hour week and then go on strike. Each time</span>
</span><span class='line'><span class="sd">    a Worker works, they work a random amount of time between 1 and 40.</span>
</span><span class='line'><span class="sd">    &quot;&quot;&quot;</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">hours_worked</span> <span class="o">=</span> <span class="mi">0</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">work</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'>        <span class="n">timesheet</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">hours_worked</span> <span class="o">+=</span> <span class="n">timesheet</span>
</span><span class='line'>        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">hours_worked</span> <span class="o">&gt;</span> <span class="mi">40</span><span class="p">:</span>
</span><span class='line'>            <span class="k">raise</span> <span class="n">WorkerStrikeException</span><span class="p">(</span><span class="s">&quot;This worker is picketing&quot;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="n">timesheet</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Boss</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
</span><span class='line'>    <span class="sd">&quot;&quot;&quot;</span>
</span><span class='line'><span class="sd">    A Boss makes profit using workers. Bosses squeeze 1000 monies out of a</span>
</span><span class='line'><span class="sd">    Worker for each hour worked. Workers on strike are instantly replaced.</span>
</span><span class='line'><span class="sd">    &quot;&quot;&quot;</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">worker</span><span class="p">):</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">worker</span> <span class="o">=</span> <span class="n">worker</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">profit</span> <span class="o">=</span> <span class="mi">0</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">def</span> <span class="nf">make_profit</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'>        <span class="k">try</span><span class="p">:</span>
</span><span class='line'>            <span class="bp">self</span><span class="o">.</span><span class="n">profit</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">worker</span><span class="o">.</span><span class="n">work</span><span class="p">()</span><span class="o">*</span><span class="mi">1000</span>
</span><span class='line'>        <span class="k">except</span> <span class="n">WorkerStrikeException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span class='line'>            <span class="k">print</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">e</span><span class="p">)</span>
</span><span class='line'>            <span class="bp">self</span><span class="o">.</span><span class="n">worker</span> <span class="o">=</span> <span class="n">Worker</span><span class="p">()</span>
</span><span class='line'>            <span class="bp">self</span><span class="o">.</span><span class="n">profit</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">worker</span><span class="o">.</span><span class="n">work</span><span class="p">()</span><span class="o">*</span><span class="mi">1000</span>
</span><span class='line'>        <span class="k">finally</span><span class="p">:</span>
</span><span class='line'>            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">profit</span>
</span></code></pre></td></tr></table></div></figure>


<p>These are two simple classes (and a custom <code>Exception</code>) that we&rsquo;ll use to demonstrate unit testing in python. The first class, <code>Worker</code>, will work a maximum of 40 hours per week before picketing it&rsquo;s corporation. Each time <code>work</code> is called, the <code>Worker</code> will work a random number of hours. The <code>Boss</code> class takes in a <code>Worker</code> object, which it uses as it performs <code>make_profit</code>. The profit is determined by the number of hours worked multiplied by 1000. When the worker starts picketing, the <code>Boss</code> will hire a new <code>Worker</code> to take their place. So it goes.</p>

<h3>Mocking the Worker Class</h3>

<p>Our goal is to fully test the <code>Boss</code> class. We&rsquo;ve left ourselves a dependency to inject in the <code>__init__</code> method, so we could start there. We&rsquo;ll mock the <code>Worker</code> and pass it into the <code>Boss</code> initializer. We&rsquo;ll then set up the <code>Worker.work</code> method to always return a known number so we can test the functionality of <code>make_profit</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>
<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='python'><span class='line'><span class="kn">import</span> <span class="nn">unittest.mock</span>
</span><span class='line'><span class="kn">from</span> <span class="nn">unittest</span> <span class="kn">import</span> <span class="n">TestCase</span>
</span><span class='line'>
</span><span class='line'><span class="kn">from</span> <span class="nn">corp</span> <span class="kn">import</span> <span class="n">work</span>  <span class="c"># your impl file</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">BossTest</span><span class="p">(</span><span class="n">TestCase</span><span class="p">):</span>
</span><span class='line'>    <span class="k">def</span> <span class="nf">test_profit_adds_up</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'>        <span class="n">worker</span> <span class="o">=</span> <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">create_autospec</span><span class="p">(</span><span class="n">work</span><span class="o">.</span><span class="n">Worker</span><span class="p">)</span>
</span><span class='line'>        <span class="n">worker</span><span class="o">.</span><span class="n">work</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">8</span>
</span><span class='line'>        <span class="n">boss</span> <span class="o">=</span> <span class="n">work</span><span class="o">.</span><span class="n">Boss</span><span class="p">(</span><span class="n">worker</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">8000</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">16000</span><span class="p">)</span>
</span><span class='line'>        <span class="n">worker</span><span class="o">.</span><span class="n">work</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">10</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">26000</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">worker</span><span class="o">.</span><span class="n">work</span><span class="o">.</span><span class="n">assert_has_calls</span><span class="p">([</span>
</span><span class='line'>            <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">(),</span>
</span><span class='line'>            <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">(),</span>
</span><span class='line'>            <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">()</span>
</span><span class='line'>        <span class="p">])</span>
</span><span class='line'>
</span><span class='line'><span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
</span><span class='line'>    <span class="n">unittest</span><span class="o">.</span><span class="n">main</span><span class="p">()</span>
</span></code></pre></td></tr></table></div></figure>


<p>To run this test, use the command <code>python3 -m testtools.run test</code>, where <code>test</code> is the name of your test file without the <code>.py</code>.</p>

<p>One curiosity here is <code>unittest.mock.create_autospec</code>. Python will also let you directly create a <code>Mock</code>, which will absorb all attribute calls regardless of whether they are defined, and <code>MagicMock</code>, which is like <code>Mock</code> except it also mocks magic methods. <code>create_autospec</code> will create a mock with all of the defined attributes of the given class (in our case <code>work.Worker</code>), and raise an Exception when the attribute is not defined on the specced class. This is really handy, and eliminates the possibility of tests &ldquo;accidentally passing&rdquo; because they are calling default attributes defined by the generic <code>Mock</code> or <code>MagicMock</code> initializers.</p>

<p>We set the return value of the <code>work</code> function with <code>return_value</code>, and we can change it on a whim if we so desire. We then use <code>assertEqual</code> to verify the numbers are crunching as expected. One further thing I&rsquo;ve shown here is <code>assert_has_calls</code>, a mock assertion to verify that <code>work</code> was called 3 times on our mock method.</p>

<p>You may also note that we subclassed <code>TestCase</code> to enable running this class as part of our unit testing framework with the special <code>__main__</code> method definition at the bottom of the file.</p>

<h3>Patching the Worker Class</h3>

<p>Although our first test demonstrates how to <code>make_profit</code> with a happy worker, we also need to verify how the <code>Boss</code> handles workers on strike. Unforunately, the <code>Boss</code> class creates his own <code>Worker</code> internally after learning they can&rsquo;t trust the <code>Worker</code> we gave them in the initializer. We want to create consistent tests, so we can&rsquo;t rely on the random numbers generated by <code>randint</code> in <code>Worker.work</code>. This means we can&rsquo;t just depend on dependency injection to make these tests pass!</p>

<p>At this point we have two options: we can patch the <code>Worker</code> class or we can patch the <code>randint</code> function. Why not both! As luck would have it, there are a few ways to use <a href="https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch"><code>patch</code></a>, and we can explore a couple of these ways in our two example tests.</p>

<p>We&rsquo;ll patch the <code>randint</code> function using a method decorator. Our intent is to make <code>randint</code> return a static number every time, and then verify that profits keep booming even as we push workers past their limit.</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='python'><span class='line'><span class="nd">@unittest.mock.patch</span><span class="p">(</span><span class="s">&#39;corp.work.randint&#39;</span><span class="p">,</span> <span class="n">return_value</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>
</span><span class='line'><span class="k">def</span> <span class="nf">test_profit_adds_up_despite_turnover</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">randint</span><span class="p">):</span>
</span><span class='line'>    <span class="n">boss</span> <span class="o">=</span> <span class="n">work</span><span class="o">.</span><span class="n">Boss</span><span class="p">(</span><span class="n">work</span><span class="o">.</span><span class="n">Worker</span><span class="p">())</span>
</span><span class='line'>    <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">20000</span><span class="p">)</span>
</span><span class='line'>    <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">40000</span><span class="p">)</span>
</span><span class='line'>    <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">60000</span><span class="p">)</span>
</span><span class='line'>    <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">80000</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">randint</span><span class="o">.</span><span class="n">assert_has_calls</span><span class="p">([</span>
</span><span class='line'>        <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">40</span><span class="p">),</span> <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">40</span><span class="p">),</span>
</span><span class='line'>        <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">40</span><span class="p">),</span> <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
</span><span class='line'>    <span class="p">])</span>
</span></code></pre></td></tr></table></div></figure>


<p>When calling <code>patch</code>, you must describe the namespace relative to the module you&rsquo;re importing. In our case, we&rsquo;re using <code>randint</code> in the <code>corp.work</code> module, so we use <code>corp.work.randint</code>. We define the <code>return_value</code> of <code>randint</code> to simply be 20. A fine number of hours per day to work an employee, according to the <code>Boss</code>. <code>patch</code> will inject a parameter into the test representing an automatically created mock that will be used in the patch, and we use that to assert that our calls were all made the way we expected.</p>

<p>Since we know the inner workings of the <code>Worker</code> class, we know that this test exercised our code by surpassing a 40-hour work week for our poor <code>Worker</code> and causing the <code>WorkerStrikeException</code> to be raised. In doing so, we&rsquo;re depending on the <code>Worker</code>/<code>Boss</code> implementation to stay in-sync, which is a dangerous assumption. Let&rsquo;s explore patching the <code>Worker</code> class instead.</p>

<p>To spice things up, we&rsquo;ll use the <code>ContextManager</code> syntax when we patch the <code>Worker</code> class. We&rsquo;ll create one mock <code>Worker</code> outside of the context to use for dependency injection, and we&rsquo;ll use this mock to <code>raise</code> the <code>WorkerStrikeException</code> as a side effect of <code>work</code> being called too many times. Then we&rsquo;ll patch the <code>Worker</code> class for newly created instances to return a known timesheet.</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>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="k">def</span> <span class="nf">test_profit_adds_up_despite_strikes</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span class='line'>    <span class="n">worker</span> <span class="o">=</span> <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">create_autospec</span><span class="p">(</span><span class="n">work</span><span class="o">.</span><span class="n">Worker</span><span class="p">)</span>
</span><span class='line'>    <span class="n">worker</span><span class="o">.</span><span class="n">work</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">12</span>
</span><span class='line'>    <span class="n">boss</span> <span class="o">=</span> <span class="n">work</span><span class="o">.</span><span class="n">Boss</span><span class="p">(</span><span class="n">worker</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">with</span> <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">patch</span><span class="p">(</span><span class="s">&#39;corp.work.Worker&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">MockWorker</span><span class="p">:</span>
</span><span class='line'>        <span class="n">scrub</span> <span class="o">=</span> <span class="n">MockWorker</span><span class="o">.</span><span class="n">return_value</span>
</span><span class='line'>        <span class="n">scrub</span><span class="o">.</span><span class="n">work</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">4</span>
</span><span class='line'>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">12000</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">24000</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">worker</span><span class="o">.</span><span class="n">work</span><span class="o">.</span><span class="n">side_effect</span> <span class="o">=</span> <span class="n">work</span><span class="o">.</span><span class="n">WorkerStrikeException</span><span class="p">(</span><span class="s">&#39;Faking a strike!&#39;</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">28000</span><span class="p">)</span>
</span><span class='line'>        <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">boss</span><span class="o">.</span><span class="n">make_profit</span><span class="p">(),</span> <span class="mi">32000</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">worker</span><span class="o">.</span><span class="n">work</span><span class="o">.</span><span class="n">assert_has_calls</span><span class="p">([</span>
</span><span class='line'>            <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">(),</span> <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">(),</span> <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">()</span>
</span><span class='line'>        <span class="p">])</span>
</span><span class='line'>        <span class="n">scrub</span><span class="o">.</span><span class="n">work</span><span class="o">.</span><span class="n">assert_has_calls</span><span class="p">([</span>
</span><span class='line'>            <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">(),</span> <span class="n">unittest</span><span class="o">.</span><span class="n">mock</span><span class="o">.</span><span class="n">call</span><span class="p">()</span>
</span><span class='line'>        <span class="p">])</span>
</span></code></pre></td></tr></table></div></figure>


<p>After the first <code>Worker</code> throws a <code>WorkerStrikeException</code>, the second <code>Worker</code> (scrub) comes in to replace them. In patching the <code>Worker</code>, we are able to more accurately describe the behavior of <code>Boss</code> regardless of the implementation details behind <code>Worker</code>.</p>

<h3>A Non-Political Conclusion</h3>

<p>I&rsquo;m not saying this is the best way to go about unit testing in python, but it is an option that should help you get started unit testing legacy code. There are certainly those who see this level of micromanaging mocks and objects as tedious, but there is be benefit to defining the way a class acts under exact circumstances. This was a contrived example, and your code may be a little bit harder to wrap with tests.</p>

<p>Now you can go get Hooked on Pythonics!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Maintaining X Applications in Unity 8]]></title>
    <link href="https://larry-price.com/blog/2016/08/24/running-x-applications-in-unity-8/"/>
    <updated>2016-08-24T17:29:59-04:00</updated>
    <id>https://larry-price.com/blog/2016/08/24/running-x-applications-in-unity-8</id>
    <content type="html"><![CDATA[<p>The release of Ubuntu 16.10 Yakkety Yak in the coming months will bring about the public release of Unity 8 as a pre-installed desktop session (though not as the default session). It&rsquo;s been a long time coming, and there&rsquo;s a lot of new features which will break older applications. Canonical has unveiled <a href="http://snapcraft.io">snappy</a> as the preferred packaging system for Unity 8, but what about all those old deb packages?</p>

<p>There have been a few other good posts about X applications on Unity 8 including <a href="http://mhall119.com/2016/05/dogfooding-unity-8/">this one on dogfooding</a>, <a href="https://kylenubuntu.blogspot.no/2016/07/running-x-apps-on-ubuntu-devices.html">this one on Ubuntu Touch</a>, and <a href="https://bregmatter.wordpress.com/2016/07/04/x11-applications-and-unity-8/">this one on how it works under the covers</a>. This blog post is explicitly about Unity 8 on desktop using the Libertine CLI, though can be applied to most devices running Ubuntu Touch.</p>

<p><em>Disclaimer: I work for Canonical on one of the teams making all of this fancy stuff work.</em></p>

<h3>A (Very) Brief Explanation</h3>

<p>The toolchain we&rsquo;ll be relying on is called <code>libertine</code>, and it&rsquo;s essentially a wrapper around unprivileged LXC and chroot-based containers. We prefer to use LXC containers on newer OSes, but we must continue supporting chroot containers on many devices due to kernel limitations.</p>

<h3>What You&rsquo;ll Need</h3>

<p>For desktop Unity 8, you&rsquo;ll need the packages for <code>libertine</code>, <code>libertine-tools</code>, and <code>lxc</code> to get started. This will install a CLI and GUI for maintaining Libertine containers and applications.</p>

<p>If you&rsquo;re running Wily or newer, you can just run the following in your terminal:</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'><span class="nv">$ </span>sudo apt install libertine
</span></code></pre></td></tr></table></div></figure>


<p>Otherwise, you&rsquo;ll need to add the stable overlay PPA first:</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='bash'><span class='line'><span class="nv">$ </span>sudo add-apt-repository ppa:ci-train-ppa-service/stable-phone-overlay
</span><span class='line'><span class="nv">$ </span>sudo apt-get update
</span><span class='line'><span class="nv">$ </span>sudo apt-get install libertine
</span></code></pre></td></tr></table></div></figure>


<h3>The GUI</h3>

<p>At this point, if you&rsquo;re on desktop you can open up the GUI which will guide you through creating a new container and installing applications. Search the Dash (or Apps scope) for <code>libertine</code> and, given that we haven&rsquo;t pushed a buggy version recently, you&rsquo;ll be presented with a Qt application for maintaining containers. I highly recommend using the GUI, because then you are guaranteed not to be following out-of-date console commands.</p>

<p>&hellip;But maybe you prefer the terminal. Or maybe you&rsquo;re secretly SSH&rsquo;d into the target machine or Ubuntu Touch device and need to use the terminal. If so&hellip;</p>

<h3>The CLI</h3>

<p>The CLI we&rsquo;ll be using is <code>libertine-container-manager</code>. It has a <code>manpage</code>, a <code>--help</code> option, and autocomplete to help you out in a jam.</p>

<p>The first thing you&rsquo;ll want to do is create a container. There are a lot of options, but to create an optimal container for your current machine you only need to specify the <code>id</code> and <code>name</code> parameters:</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'><span class="nv">$ </span>libertine-container-manager create --id desktopapps --name <span class="s2">&quot;Desktop Applications&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>A couple of things to note here: Your <code>id</code> must be unique and conform to the simple click name regex - this is what will identify your container on a system level. The <code>name</code> should be human-readable so you can easily identify what might be inside your container. If you don&rsquo;t specify a <code>name</code>, your <code>id</code> will be used. The CLI will likely ask you for a password to use in the container in case you ever need it. You can leave this blank if you&rsquo;re not concerned with that kind of thing.</p>

<p>At this point, a bunch of things should be happening in your terminal. This will pull a container image for your current distro and install all the requirements to get started maintaining and running X apps. This could take anywhere from a few minutes to the next hour depending on your network and disk speeds. Once you&rsquo;re done, you can use the <code>list</code> subcommand to list all installed containers (note you probably just have one at this point). If you ever want to delete your container, you can run <code>libertine-container-manager destroy -i desktopapps</code>.</p>

<p>Once that&rsquo;s finished, we can start installing apps. To find apps available, you can use the <code>search-cache</code> subcommand:</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'><span class="nv">$ </span>libertine-container-manager search-cache --id desktopapps --search-string <span class="s2">&quot;office&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This will return a few strings from the apt-cache of the container with <code>id</code> &ldquo;desktopapps&rdquo; that match &ldquo;office&rdquo;. Now, if you want to install &ldquo;libreoffice&rdquo;:</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'><span class="nv">$ </span>libertine-container-manager install-package --id desktopapps --package libreoffice
</span></code></pre></td></tr></table></div></figure>


<p>This will install the full libreoffice suite. Nice! Similarly, you can use the <code>remove-package</code> subcommand to remove applications. Don&rsquo;t remember what apps you&rsquo;ve installed? Use the <code>list-apps</code> command:</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'><span class="nv">$ </span>libertine-container-manager list-apps --id desktopapps
</span></code></pre></td></tr></table></div></figure>


<p>Maybe you&rsquo;re an avid Steam for Linux gamer and want to try to get some games working. Since Steam still only comes in a 32-bit binary, you&rsquo;ll need to enable the multiarch repos, and then you can just install Steam like any other app:</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='bash'><span class='line'><span class="nv">$ </span>libertine-container-manager configure --id desktopapps --multiarch <span class="nb">enable</span>
</span><span class='line'>...
</span><span class='line'><span class="nv">$ </span>libertine-container-manager install-package --id desktopapps --package steam
</span></code></pre></td></tr></table></div></figure>


<p>Steam will ask you to agree to their user agreement from the command line, which you should be able to do easily. If you need to use the <code>readline</code> frontend for dpkg, you can append <code>--readline</code> to the <code>install-package</code> command to enable it.</p>

<p>There are many other commands to explore to maintain your container, but for now I&rsquo;ll let you check the manpage or open the GUI to explore further.</p>

<h3>Running Apps</h3>

<p>Now that you&rsquo;ve installed some apps, you probably want to run them. You can install the Libertine Scope, which will allow you to peruse your installed apps in a Unity 8 session. You can either install it from the App Store on a device (search for &ldquo;Desktop Apps Scope&rdquo;) or through <code>apt</code> on desktop 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='bash'><span class='line'><span class="nv">$ </span>sudo apt install libertine-scope
</span></code></pre></td></tr></table></div></figure>


<p>In a Unity 8 session, you can now find the scope and click on apps to run them. Note that there are many apps which still don&rsquo;t work, such as those requiring a terminal or <code>sudo</code>; consider these a work in progress.</p>

<h3>The Future</h3>

<p>I&rsquo;ve been toiling away the past few weeks getting a scope ready which can be used explicitly to install/remove X apps in Unity 8, like the current Ubuntu Software Center (or app store on Touch devices). This scope should be available anywhere the libertine scope is available, meaning that it will alleviate a lot of the pain associated with installing/removing apps for a large chunk of users. Using the Libertine GUI or Libertine CLI will still allow for much more customization, but those tools are largely designed with power users in mind.</p>

<p>Are you able to get libertine working on your system? Can you launch X applications to your heart&rsquo;s content? Let me know in the comments!</p>
]]></content>
  </entry>
  
</feed>