<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2025-09-15T08:08:26+00:00</updated><id>/feed.xml</id><title type="html">Samuel’s blog</title><subtitle>Samuel Orji&apos;s blog - Nerd that writes about programming and things he has learnt or is learning. All things #Scala and #Rust</subtitle><entry><title type="html">Properly format your strings in rust</title><link href="/2025/09/12/properly-format-your-strings.html" rel="alternate" type="text/html" title="Properly format your strings in rust" /><published>2025-09-12T06:37:00+00:00</published><updated>2025-09-12T06:37:00+00:00</updated><id>/2025/09/12/properly-format-your-strings</id><content type="html" xml:base="/2025/09/12/properly-format-your-strings.html"><![CDATA[<p>Rust, like any other language has string formatting/interpolation abilities similar to C’s <code class="language-plaintext highlighter-rouge">printf</code> or <code class="language-plaintext highlighter-rouge">fprintf</code> functions, provided by the <a href="https://doc.rust-lang.org/std/fmt/">fmt module</a>. But it’s not that simple as we will see below.</p>

<p>As an example, Here’s an example of <a href="https://doc.rust-lang.org/alloc/fmt/index.html#fillalignment">filling and aligning</a> text.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">println!</span><span class="p">(</span><span class="s">"|{:-&lt;9}|"</span><span class="p">,</span> <span class="s">"Hello"</span><span class="p">)</span>
</code></pre></div></div>
<p>By using this format <code class="language-plaintext highlighter-rouge">{:-&lt;9}</code>, we’re saying that we want the string “Hello” to be left aligned to a width of 9. From the docs, if the length of the string to be formatted (hello) is less than the width (9), then the remaining spaces should be filled with the filler ‘-‘</p>

<p>Here’s the output:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>|Hello----|
</code></pre></div></div>

<p>It all looks good and everything works as expected, until we run into a subtle issue.</p>

<p>Here’s an example of printing or “displaying” an enum in rust.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="n">fmt</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">fmt</span><span class="p">::{</span><span class="n">format</span><span class="p">,</span> <span class="n">Display</span><span class="p">};</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">(){</span>
    <span class="k">enum</span> <span class="n">IPVersion</span> <span class="p">{</span>
        <span class="n">IPV4</span><span class="p">,</span>
        <span class="n">IPV6</span>
    <span class="p">}</span>
    <span class="k">impl</span> <span class="n">Display</span> <span class="k">for</span> <span class="n">IPVersion</span> <span class="p">{</span>
        <span class="k">fn</span> <span class="nf">fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">f</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="nn">fmt</span><span class="p">::</span><span class="n">Formatter</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nn">fmt</span><span class="p">::</span><span class="nb">Result</span> <span class="p">{</span>
            <span class="k">match</span> <span class="k">self</span> <span class="p">{</span>
                <span class="nn">IPVersion</span><span class="p">::</span><span class="n">IPV4</span> <span class="k">=&gt;</span> <span class="nd">write!</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s">"IPV4"</span><span class="p">),</span>
                <span class="nn">IPVersion</span><span class="p">::</span><span class="n">IPV6</span> <span class="k">=&gt;</span> <span class="nd">write!</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s">"IPV6"</span><span class="p">),</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">let</span> <span class="n">ipv4</span> <span class="p">:</span> <span class="n">IPVersion</span> <span class="o">=</span> <span class="nn">IPVersion</span><span class="p">::</span><span class="n">IPV4</span><span class="p">;</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"|{:-&lt;9}|"</span><span class="p">,</span> <span class="n">ipv4</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>We defined our enum, implemented the <code class="language-plaintext highlighter-rouge">Display</code> trait for it so we can use it in the <code class="language-plaintext highlighter-rouge">println</code> statement with the same formatting as before, but for some weird reason, here’s the output.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>|IPV4|
</code></pre></div></div>

<p>What? where’s the filler, why didn’t that format as expected ?</p>

<p>The answer lies in a not so obvious statement in the <code class="language-plaintext highlighter-rouge">fmt</code> module</p>

<blockquote>
  <p>Note that alignment might not be implemented by some types.</p>
</blockquote>

<p>That initially didn’t make much sense to me as there is no <code class="language-plaintext highlighter-rouge">Alignment</code> trait that needs to be implemented, why did the string (or str in rust)  <code class="language-plaintext highlighter-rouge">Hello</code> work, but an enum that had its <code class="language-plaintext highlighter-rouge">Display</code> trait implemented as a string didn’t.</p>

<p>To further understand why, I decided to take a look at the implementation of <code class="language-plaintext highlighter-rouge">Display</code> for <code class="language-plaintext highlighter-rouge">str</code> and <a href="https://github.com/rust-lang/rust/blob/52618eb338609df44978b0ca4451ab7941fd1c7a/library/core/src/fmt/mod.rs#L2751">here it is</a>.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Display</span> <span class="k">for</span> <span class="nb">str</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">f</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">Formatter</span><span class="o">&lt;</span><span class="nv">'_</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Result</span> <span class="p">{</span>
        <span class="n">f</span><span class="nf">.pad</span><span class="p">(</span><span class="k">self</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The implementation caught my attention.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">f</span><span class="nf">.pad</span><span class="p">(</span><span class="k">self</span><span class="p">)</span>
</code></pre></div></div>
<p>Why the call to <code class="language-plaintext highlighter-rouge">pad</code>, and I checked the <a href="https://doc.rust-lang.org/core/fmt/struct.Formatter.html#method.pad">docs for <code class="language-plaintext highlighter-rouge">pad</code></a> and here’s an excerpt.</p>

<blockquote>
  <p>Takes a string slice and emits it to the internal buffer after applying the relevant formatting flags specified.</p>
</blockquote>

<p>So, as expected, I decided to change my <code class="language-plaintext highlighter-rouge">Display</code> implementation.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Display</span> <span class="k">for</span> <span class="n">IPVersion</span> <span class="p">{</span>
        <span class="k">fn</span> <span class="nf">fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">f</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="nn">fmt</span><span class="p">::</span><span class="n">Formatter</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nn">fmt</span><span class="p">::</span><span class="nb">Result</span> <span class="p">{</span>
            <span class="k">let</span> <span class="n">rep</span> <span class="o">=</span> <span class="k">match</span> <span class="k">self</span> <span class="p">{</span>
                <span class="nn">IPVersion</span><span class="p">::</span><span class="n">IPV4</span> <span class="k">=&gt;</span> <span class="s">"IPV4"</span><span class="p">,</span>
                <span class="nn">IPVersion</span><span class="p">::</span><span class="n">IPV6</span> <span class="k">=&gt;</span> <span class="s">"IPV6"</span>
            <span class="p">};</span>
            <span class="n">f</span><span class="nf">.pad</span><span class="p">(</span><span class="n">rep</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
</code></pre></div></div>

<p>and that seemed to work, here’s my output.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>|IPV4-----|
</code></pre></div></div>
<hr />
<p>So what is this <code class="language-plaintext highlighter-rouge">fmt::Formatter</code> and  why did calling <code class="language-plaintext highlighter-rouge">pad</code> on it seem to work.</p>

<h3 id="why-it-works">Why it works.</h3>

<p>Very simply put, when we call <code class="language-plaintext highlighter-rouge">println</code> with the formatting options like <code class="language-plaintext highlighter-rouge">{:-&lt;9}</code> in our case, it creates a <a href="https://github.com/rust-lang/rust/blob/52618eb338609df44978b0ca4451ab7941fd1c7a/library/core/src/fmt/mod.rs#L1451">formatter</a> <code class="language-plaintext highlighter-rouge">f</code> of type <code class="language-plaintext highlighter-rouge">fmt::Formatter</code> with our formatting options and passes it as an argument to our <code class="language-plaintext highlighter-rouge">fmt</code> method in our <code class="language-plaintext highlighter-rouge">Display</code> trait implementation. <a href="https://github.com/rust-lang/rust/blob/52618eb338609df44978b0ca4451ab7941fd1c7a/library/alloc/src/string.rs#L2820C9-L2820C26">Here’s an example of how that is called</a>.</p>

<p><strong>It is weirdly now up to us to use the formatting options via the <code class="language-plaintext highlighter-rouge">pad</code> function or some other method I don’t know about.</strong></p>

<p>If we look back at our first implementation that didn’t get formatted correctly, we had our formatter <code class="language-plaintext highlighter-rouge">f</code>, but we simply wrote to it via the <code class="language-plaintext highlighter-rouge">write!</code> macro and it didn’t apply our formatting flags.</p>

<p>But by now explicitly applying our formatting flags from the formatter via the <code class="language-plaintext highlighter-rouge">pad</code> method. It seemed to work.</p>

<p>Now, does it make sense to have to explicitly call <code class="language-plaintext highlighter-rouge">pad</code> ourselves ?. Shouldn’t that be implicitly called or added by the compiler ?.</p>

<p>That’s for the really smart folks over at rustomania to figure out.</p>

<h3 id="deeper-look-demo">Deeper look (Demo)</h3>
<p>If you’re still here, great, let’s try to go a little deeper to see what’s going on.</p>

<p>Let’s add a <code class="language-plaintext highlighter-rouge">println</code> statement to see what the formatting options are when we try to format our string with <code class="language-plaintext highlighter-rouge">{:-&lt;9}</code>.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Display</span> <span class="k">for</span> <span class="n">IPVersion</span> <span class="p">{</span>
        <span class="k">fn</span> <span class="nf">fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">f</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="nn">fmt</span><span class="p">::</span><span class="n">Formatter</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nn">fmt</span><span class="p">::</span><span class="nb">Result</span> <span class="p">{</span>
            <span class="c1">// try to print formatting options that were supplied</span>
            <span class="nd">println!</span><span class="p">(</span><span class="s">"Formatting Options, alignment: {:?}, Fill: {:?}, width: {:?}"</span><span class="p">,</span> <span class="n">f</span><span class="nf">.align</span><span class="p">(),</span> <span class="n">f</span><span class="nf">.fill</span><span class="p">(),</span> <span class="n">f</span><span class="nf">.width</span><span class="p">());</span>
            <span class="k">let</span> <span class="n">rep</span> <span class="o">=</span> <span class="k">match</span> <span class="k">self</span> <span class="p">{</span>
                <span class="nn">IPVersion</span><span class="p">::</span><span class="n">IPV4</span> <span class="k">=&gt;</span> <span class="s">"IPV4"</span><span class="p">,</span>
                <span class="nn">IPVersion</span><span class="p">::</span><span class="n">IPV6</span> <span class="k">=&gt;</span> <span class="s">"IPV6"</span>
            <span class="p">};</span>
            <span class="n">f</span><span class="nf">.pad</span><span class="p">(</span><span class="n">rep</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
</code></pre></div></div>

<p>We get this output.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Formatting Options, alignment: Some<span class="o">(</span>Left<span class="o">)</span>, Fill: <span class="s1">'-'</span>, width: Some<span class="o">(</span>9<span class="o">)</span>
</code></pre></div></div>

<p>This makes sense, as we want our text “Left” aligned, with a width of “9” the empty spaces filled with “-“.</p>

<p>So it proves our point that the formatting options are gotten from the <code class="language-plaintext highlighter-rouge">println!</code> statement and passed to the formatter <code class="language-plaintext highlighter-rouge">f</code> that’s used in the the <code class="language-plaintext highlighter-rouge">fmt</code> method of the <code class="language-plaintext highlighter-rouge">Display</code> trait.</p>

<p>You can try using a new formatter as is done when <code class="language-plaintext highlighter-rouge">to_string</code> is called <a href="https://github.com/rust-lang/rust/blob/52618eb338609df44978b0ca4451ab7941fd1c7a/library/alloc/src/string.rs#L2817">here</a> and you’ll see that formatting will not work as expected as your new formatter doesn’t have any formatting options.</p>]]></content><author><name></name></author><category term="rust" /><category term="string" /><summary type="html"><![CDATA[Rust, like any other language has string formatting/interpolation abilities similar to C’s printf or fprintf functions, provided by the fmt module. But it’s not that simple as we will see below.]]></summary></entry><entry><title type="html">Coordinating threads with Condvar in Rust</title><link href="/2025/09/11/Condvars-to-the-rescue.html" rel="alternate" type="text/html" title="Coordinating threads with Condvar in Rust" /><published>2025-09-11T06:37:00+00:00</published><updated>2025-09-11T06:37:00+00:00</updated><id>/2025/09/11/Condvars-to-the-rescue</id><content type="html" xml:base="/2025/09/11/Condvars-to-the-rescue.html"><![CDATA[<p>I recently worked on a rust project where I had to coordinate state between two threads, and with my Scala background, it wasn’t the easiest to implement in rust which does things a little differently.</p>

<p>I decided to write this to help rust developers get a good intuition of what <a href="https://doc.rust-lang.org/std/sync/struct.Condvar.html">Condvar</a> is, how it works and why it can be used for state coordination.</p>

<p>To drive our point home, we will be designing a very simple cli application that starts and prints a counter on a thread, and takes input from the main thread to either pause or resume that counter. We will start from a basic inefficient solution and then introduce how using a Condvar will make our system a little more efficient.</p>

<blockquote>
  <p>The solution is pretty straight forward. We have some atomic variable that’s shared between the two threads that will serve as a signal to pause or resume counting, in rust, shared atomic variable immediately implies <code class="language-plaintext highlighter-rouge">Arc&lt;Mutex&lt;T&gt;&gt;</code> which we will be using.</p>
</blockquote>

<p>Let’s start by defining our mutex that will be used by both threads</p>
<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="n">io</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">sync</span><span class="p">::{</span><span class="nb">Arc</span><span class="p">,</span> <span class="n">Mutex</span><span class="p">};</span>
<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// signal to be shared by both threads</span>
    <span class="k">let</span> <span class="n">signal</span> <span class="p">:</span> <span class="nb">Arc</span><span class="o">&lt;</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;&gt;</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">Mutex</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="k">false</span><span class="p">));</span>
    <span class="c1">// cloned signal that will be used by the main thread</span>
    <span class="k">let</span> <span class="n">input_arc</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signal</span><span class="p">);</span>
    <span class="c1">// cloned signal that will be used by the counter thread</span>
    <span class="k">let</span> <span class="n">counter_arc</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signal</span><span class="p">);</span>
<span class="p">}</span>

</code></pre></div></div>

<p>Now, let’s see our counter thread:</p>
<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">counter_thread</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">thread</span><span class="p">::</span><span class="nf">spawn</span><span class="p">(</span><span class="k">move</span> <span class="p">||</span> <span class="p">{</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="k">loop</span> <span class="p">{</span>
            <span class="c1">// check the mutex if program should be paused</span>
            <span class="k">let</span> <span class="n">paused</span> <span class="p">:</span> <span class="n">MutexGuard</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span>  <span class="o">=</span> <span class="n">counter_arc</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
            <span class="k">if</span> <span class="o">*</span><span class="n">paused</span> <span class="p">{</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Program is paused"</span><span class="p">)</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter: {}"</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">count</span><span class="p">);</span>
            <span class="p">}</span>

            <span class="nf">drop</span><span class="p">(</span><span class="n">paused</span><span class="p">);</span>

            <span class="c1">// a thread sleep so we can slow down terminal output</span>
            <span class="nn">std</span><span class="p">::</span><span class="nn">thread</span><span class="p">::</span><span class="nf">sleep</span><span class="p">(</span><span class="nn">std</span><span class="p">::</span><span class="nn">time</span><span class="p">::</span><span class="nn">Duration</span><span class="p">::</span><span class="nf">from_secs</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span>
        <span class="p">}</span>
    <span class="p">});</span>

</code></pre></div></div>
<p>In the code snippet above, we simply start a thread and define a local variable called count. In a loop, we first try to acquire / lock the mutex, checking the value. If it’s true (paused), we simply print “Program is Paused”, if not, we increment the counter and print it to the console. We also drop the mutex so it can be used/acquired by other threads.</p>

<blockquote>
  <p>We’ve added a thread::sleep so we can see slow down the counter and see it incrementing each second,</p>
</blockquote>

<p>Now, let’s write code in our main thread that will listen to input from the terminal to either pause or resume the counter above.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="k">loop</span> <span class="p">{</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">user_input</span> <span class="o">=</span> <span class="nn">String</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>
        <span class="nn">io</span><span class="p">::</span><span class="nf">stdin</span><span class="p">()</span><span class="nf">.read_line</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">user_input</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
        <span class="k">match</span> <span class="n">user_input</span><span class="nf">.trim</span><span class="p">()</span> <span class="p">{</span>
            <span class="s">"p"</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">let</span> <span class="k">mut</span> <span class="n">pause</span><span class="p">:</span> <span class="n">MutexGuard</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">input_arc</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
                <span class="o">*</span><span class="n">pause</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
                <span class="nf">drop</span><span class="p">(</span><span class="n">pause</span><span class="p">);</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter Paused"</span><span class="p">)</span>
            <span class="p">},</span>
            <span class="s">"r"</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">let</span> <span class="k">mut</span> <span class="n">pause</span><span class="p">:</span> <span class="n">MutexGuard</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">input_arc</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
                <span class="o">*</span><span class="n">pause</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
                <span class="nf">drop</span><span class="p">(</span><span class="n">pause</span><span class="p">);</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter Resumed"</span><span class="p">)</span>
            <span class="p">},</span>
            <span class="n">x</span> <span class="k">=&gt;</span>  <span class="p">{</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"unknown command: '{}'"</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

</code></pre></div></div>

<p>Here, we basically wrap getting user input in a loop and acting on the user input, if the user types ‘p’, we try to pause the counter by acquiring the lock on the mutex and setting its value to true. If the user types ‘r’, we resume the counter by acquiring the lock on the mutex and setting it to false.</p>
<details>

  <summary>Here’s the full code</summary>

  <div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="n">io</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">sync</span><span class="p">::{</span><span class="nb">Arc</span><span class="p">,</span> <span class="n">Mutex</span><span class="p">,</span> <span class="n">MutexGuard</span><span class="p">};</span>
<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">signal</span><span class="p">:</span> <span class="nb">Arc</span><span class="o">&lt;</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;&gt;</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">Mutex</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="k">false</span><span class="p">));</span>
    <span class="k">let</span> <span class="n">input_arc</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signal</span><span class="p">);</span>
    <span class="k">let</span> <span class="n">counter_arc</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signal</span><span class="p">);</span>

    <span class="c1">// thread that handles counting and printing to stdout</span>
    <span class="k">let</span> <span class="n">counter_thread</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">thread</span><span class="p">::</span><span class="nf">spawn</span><span class="p">(</span><span class="k">move</span> <span class="p">||</span> <span class="p">{</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="k">loop</span> <span class="p">{</span>
            <span class="c1">// check the mutex if program should be paused</span>
            <span class="k">let</span> <span class="n">paused</span><span class="p">:</span> <span class="n">MutexGuard</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">counter_arc</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
            <span class="k">if</span> <span class="o">*</span><span class="n">paused</span> <span class="p">{</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Program is paused"</span><span class="p">)</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter: {}"</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">count</span><span class="p">);</span>
            <span class="p">}</span>

            <span class="nf">drop</span><span class="p">(</span><span class="n">paused</span><span class="p">);</span>

            <span class="c1">// a thread sleep so we can slow down terminal output</span>
            <span class="nn">std</span><span class="p">::</span><span class="nn">thread</span><span class="p">::</span><span class="nf">sleep</span><span class="p">(</span><span class="nn">std</span><span class="p">::</span><span class="nn">time</span><span class="p">::</span><span class="nn">Duration</span><span class="p">::</span><span class="nf">from_secs</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span>
        <span class="p">}</span>
    <span class="p">});</span>


    <span class="c1">// main thread that takes user input to either pause or resume the counter</span>
    <span class="k">loop</span> <span class="p">{</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">user_input</span> <span class="o">=</span> <span class="nn">String</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>
        <span class="nn">io</span><span class="p">::</span><span class="nf">stdin</span><span class="p">()</span><span class="nf">.read_line</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">user_input</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
        <span class="k">match</span> <span class="n">user_input</span><span class="nf">.trim</span><span class="p">()</span> <span class="p">{</span>
            <span class="s">"p"</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">let</span> <span class="k">mut</span> <span class="n">pause</span><span class="p">:</span> <span class="n">MutexGuard</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">input_arc</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
                <span class="o">*</span><span class="n">pause</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
                <span class="nf">drop</span><span class="p">(</span><span class="n">pause</span><span class="p">);</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter Paused"</span><span class="p">)</span>
            <span class="p">},</span>
            <span class="s">"r"</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">let</span> <span class="k">mut</span> <span class="n">pause</span><span class="p">:</span> <span class="n">MutexGuard</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">input_arc</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
                <span class="o">*</span><span class="n">pause</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
                <span class="nf">drop</span><span class="p">(</span><span class="n">pause</span><span class="p">);</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter Resumed"</span><span class="p">)</span>
            <span class="p">},</span>
            <span class="n">x</span> <span class="k">=&gt;</span>  <span class="p">{</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"unknown command: '{}'"</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

</code></pre></div>  </div>

</details>

<p>If we run this code with <code class="language-plaintext highlighter-rouge">cargo run</code>, wait a little bit, try to pause by typing ‘p’, and resume by typing ‘r’. We see that that the program works as expected?.</p>

<h2 id="but-">But …..</h2>

<p>When you try to pause with ‘p’, you may notice that the program keeps printing “Program is paused” which is kinda inefficient.</p>

<p>Here’s an example of an output from my machine:</p>

<details>

  <summary>Console Output</summary>

  <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Counter: 1
Counter: 2
Counter: 3
Counter: 4
Counter: 5
Counter: 6
p
Counter Paused
Program is paused
Program is paused
Program is paused
Program is paused
Program is paused
Program is paused
Program is paused
Program is paused
r
Counter Resumed
Counter: 7
Counter: 8
Counter: 9
Counter: 10
Counter: 1
</code></pre></div>  </div>
</details>

<p>When the program is paused, we see that the thread just keeps going on and on, wasting ‘precious’ cpu cycles.</p>

<p>Now, we can remove that code that prints to the console, and just pretend like nothing is happening, but deep down, we know that we just have a thread that’s actively doing nothing and taking resources from other threads (if they exist). There must be a better way to do this where we put the counter thread to sleep and wake it only signalled by user input from another thread.</p>

<p>If only we had something similar to <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#wait--">wait</a> in Java.</p>

<h2 id="enter-condvar">Enter <code class="language-plaintext highlighter-rouge">Condvar</code>.</h2>

<p><code class="language-plaintext highlighter-rouge">Condvar</code> or “Conditional Variable” represents the ability to block a thread such that it consumes no CPU time while waiting for an event to occur. <a href="https://doc.rust-lang.org/std/sync/struct.Condvar.html">See more here</a></p>

<p>This looks like something that will work for us, we will block the counter thread, preventing it from consuming CPU until the user presses ‘r’ to resume. Let’s see what that will look like.</p>

<p>First, we define our signal that now includes a <code class="language-plaintext highlighter-rouge">Condvar</code> and use it in the counter thread.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="n">io</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">sync</span><span class="p">::{</span><span class="nb">Arc</span><span class="p">,</span> <span class="n">Condvar</span><span class="p">,</span> <span class="n">Mutex</span><span class="p">,</span> <span class="n">MutexGuard</span><span class="p">};</span>
<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">signal</span><span class="p">:</span> <span class="nb">Arc</span><span class="o">&lt;</span><span class="p">(</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">Condvar</span><span class="p">)</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">new</span><span class="p">((</span><span class="nn">Mutex</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="k">false</span><span class="p">),</span> <span class="nn">Condvar</span><span class="p">::</span><span class="nf">new</span><span class="p">()));</span>
    <span class="k">let</span> <span class="n">input_arc</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signal</span><span class="p">);</span>
    <span class="k">let</span> <span class="n">counter_arc</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signal</span><span class="p">);</span>

    <span class="c1">//thread that handles counting and printing to stdout</span>
    <span class="k">let</span> <span class="n">counter_thread</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">thread</span><span class="p">::</span><span class="nf">spawn</span><span class="p">(</span><span class="k">move</span> <span class="p">||</span> <span class="p">{</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="k">loop</span> <span class="p">{</span>
            <span class="c1">// check that the program is not paused</span>
            <span class="k">let</span> <span class="p">(</span><span class="n">lock</span><span class="p">,</span> <span class="n">cvar</span><span class="p">)</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="n">counter_arc</span><span class="p">;</span>

            <span class="c1">// check the mutex if program is paused</span>
            <span class="k">let</span> <span class="k">mut</span> <span class="n">paused</span><span class="p">:</span> <span class="n">MutexGuard</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
            <span class="k">if</span> <span class="o">*</span><span class="n">paused</span> <span class="p">{</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Program is paused"</span><span class="p">);</span>
                <span class="c1">// block / pause this thread until someone calls cvar.notify() or cvar.notify_all() on the cvar</span>
                <span class="n">paused</span> <span class="o">=</span> <span class="n">cvar</span><span class="nf">.wait</span><span class="p">(</span><span class="n">paused</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter: {}"</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">count</span><span class="p">);</span>
            <span class="p">}</span>

            <span class="nf">drop</span><span class="p">(</span><span class="n">paused</span><span class="p">);</span>

            <span class="c1">// a thread sleep so we can slow down terminal output</span>
            <span class="nn">std</span><span class="p">::</span><span class="nn">thread</span><span class="p">::</span><span class="nf">sleep</span><span class="p">(</span><span class="nn">std</span><span class="p">::</span><span class="nn">time</span><span class="p">::</span><span class="nn">Duration</span><span class="p">::</span><span class="nf">from_secs</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span>
        <span class="p">}</span>
    <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Not much has changed, instead of our signal just containing a mutex, it’s now a tuple that contains a mutex and a Condvar.</p>

<p>In the counter loop, we do the same as before, we acquire the mutex, check the boolean value to confirm if the program is paused or not.</p>

<p>The new thing we introduced is this line:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">paused</span> <span class="o">=</span> <span class="n">cvar</span><span class="nf">.wait</span><span class="p">(</span><span class="n">paused</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
</code></pre></div></div>

<p>Now, this bit is crucial to understand. First, we call <code class="language-plaintext highlighter-rouge">wait</code> on the <code class="language-plaintext highlighter-rouge">Condvar</code>, passing the mutex (<code class="language-plaintext highlighter-rouge">paused</code>) as an argument. What happens here is that calling <code class="language-plaintext highlighter-rouge">wait</code> blocks or pauses the thread (counter thread) and in the process, releases the lock on the mutex that was passed as an argument (<code class="language-plaintext highlighter-rouge">paused</code>).</p>

<p>So now, we have a blocked/paused thread and a free/unlocked mutex. The return value of the <code class="language-plaintext highlighter-rouge">wait</code> method is the mutex that was passed as an argument which represents the acquired state of the mutex once the thread wakes up.</p>

<p>Here’s an excerpt from the <code class="language-plaintext highlighter-rouge">wait</code> method on Condvar</p>

<blockquote>
  <p>Blocks the current thread until this condition variable receives a notification.
This function will atomically unlock the mutex specified (represented by guard) and block the current thread. This means that any calls to notify_one or notify_all which happen logically after the mutex is unlocked are candidates to wake this thread up. When this function call returns, the lock specified will have been re-acquired.</p>
</blockquote>

<p>It’s important to understand why the mutex has to be released, because if the mutex is not released, then we have a situation where the blocked thread holds on to the mutex, preventing any other thread from using it to signal anything, resulting in a deadlock.</p>

<p>Now let’s see the main thread’s input loop:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">loop</span> <span class="p">{</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">user_input</span> <span class="o">=</span> <span class="nn">String</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>
        <span class="nn">io</span><span class="p">::</span><span class="nf">stdin</span><span class="p">()</span><span class="nf">.read_line</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">user_input</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
        <span class="k">match</span> <span class="n">user_input</span><span class="nf">.trim</span><span class="p">()</span> <span class="p">{</span>
            <span class="s">"p"</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">let</span> <span class="p">(</span><span class="n">lock</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="n">input_arc</span><span class="p">;</span>
                <span class="k">let</span> <span class="k">mut</span> <span class="n">is_paused</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
                <span class="o">*</span><span class="n">is_paused</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
                <span class="nf">drop</span><span class="p">(</span><span class="n">is_paused</span><span class="p">);</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter Paused"</span><span class="p">)</span>
            <span class="p">},</span>
            <span class="s">"r"</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">let</span> <span class="p">(</span><span class="n">lock</span><span class="p">,</span> <span class="n">cvar</span><span class="p">)</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="n">input_arc</span><span class="p">;</span>
                <span class="k">let</span> <span class="k">mut</span> <span class="n">is_paused</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
                <span class="o">*</span><span class="n">is_paused</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
                <span class="nf">drop</span><span class="p">(</span><span class="n">is_paused</span><span class="p">);</span>
                <span class="c1">// notify / wake up whoever is waiting on this conditional variable</span>
                <span class="n">cvar</span><span class="nf">.notify_one</span><span class="p">();</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter Resumed"</span><span class="p">)</span>
            <span class="p">},</span>
            <span class="n">x</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"unknown command: '{}'"</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
</code></pre></div></div>
<p>The only major thing that has changed here is in the ‘r’ resume block:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">cvar</span><span class="nf">.notify_one</span><span class="p">();</span>
</code></pre></div></div>

<blockquote>
  <p>This basically says, “Hey, to whoever that is ‘waiting’ on this variable, WAKE UP !!!!”.</p>
</blockquote>

<p>Once <code class="language-plaintext highlighter-rouge">notify_one</code> is called, the counter thread that was blocked by the call to <code class="language-plaintext highlighter-rouge">wait</code> on the condvar will wake up, acquire the mutex, see if the signal is now set to false and then resume its operation.</p>

<p>Here’s my console output now.</p>

<details>

  <summary> Console Output</summary>

  <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Counter: 1
Counter: 2
Counter: 3
Counter: 4
Counter: 5
Counter: 6
p
Counter Paused
Program is paused
r
Counter Resumed
Counter: 7
Counter: 8
Counter: 9
Counter: 10
p
Counter Paused
Program is paused
r
Counter Resumed
Counter: 11
Counter: 12
</code></pre></div>  </div>
</details>

<p>Now we see that when the program is paused, the thread actually stops work and is blocked until the user inputs ‘r’ to wake the thread and continue counting.</p>

<h3 id="condvar-gotchas">Condvar Gotchas.</h3>

<h4 id="1-spurious-wakeups">1. Spurious Wakeups:</h4>
<p>Condvars are susceptible to spurious wakeups, which is when the thread blocked by the call to <code class="language-plaintext highlighter-rouge">wait</code> wakes up unexpectedly (without being notified), <a href="https://en.wikipedia.org/wiki/Spurious_wakeup">see more here</a>.</p>

<p>Here’s an excerpt from the <code class="language-plaintext highlighter-rouge">wait</code> method.</p>

<blockquote>
  <p>Note that this function is susceptible to spurious wakeups. Condition variables normally have a boolean predicate associated with them, and the predicate must always be checked each time this function returns to protect against spurious wakeups.</p>
</blockquote>

<p>Looking at our code where we call the <code class="language-plaintext highlighter-rouge">wait</code> method, we can see where this may be an issue</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="k">mut</span> <span class="n">paused</span><span class="p">:</span> <span class="n">MutexGuard</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="k">if</span> <span class="o">*</span><span class="n">paused</span> <span class="p">{</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Program is paused"</span><span class="p">);</span>
    <span class="n">paused</span> <span class="o">=</span> <span class="n">cvar</span><span class="nf">.wait</span><span class="p">(</span><span class="n">paused</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>if we have a spurious wakeup, our thread will wakeup without being notified by the <code class="language-plaintext highlighter-rouge">notify_one()</code> method in the main thread, causing it to keep executing whereas it should be paused.</p>

<p>Here’s an illustration:</p>

<p>Imagine I have a piece of code that should only be run once the thread wakes up and the counter resumes:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">run_on_thread_wakeup</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// do something expensive here</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Hi, I'm about to resume counting"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>
<p>and we add this code at the end of the the if block where we expect the program to continue from once the thread wakes up</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="k">mut</span> <span class="n">paused</span><span class="p">:</span> <span class="n">MutexGuard</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="k">if</span> <span class="o">*</span><span class="n">paused</span> <span class="p">{</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Program is paused"</span><span class="p">);</span>
    <span class="n">paused</span> <span class="o">=</span> <span class="n">cvar</span><span class="nf">.wait</span><span class="p">(</span><span class="n">paused</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
    <span class="nf">run_on_thread_wakeup</span><span class="p">()</span>
<span class="p">}</span>
</code></pre></div></div>
<p>If our thread spuriously wakes up and our pause signal hasn’t been set to false by user input in the main thread, we call the <code class="language-plaintext highlighter-rouge">run_on_thread_wakeup</code> despite the fact the we are paused and shouldn’t call the function yet. Nothing guards/checks that we’re still paused leading to the invocation of the <code class="language-plaintext highlighter-rouge">run_on_thread_wakeup</code> function which is a false positive.</p>

<p>What we want instead is to guard against spurious wakeups by constantly checking that we’re still paused (mutex is set to true) and only continue execution if the mutex/signal is set to false when we wake up like so:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="k">mut</span> <span class="n">paused</span><span class="p">:</span> <span class="n">MutexGuard</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="k">if</span> <span class="o">*</span><span class="n">paused</span> <span class="p">{</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Program is paused"</span><span class="p">);</span>
    <span class="k">while</span> <span class="o">*</span><span class="n">paused</span> <span class="p">{</span>
        <span class="c1">// Whenever the thread wakes up, don't just continue execution, check and ensure that the signal is set to false.</span>
        <span class="c1">// only way we can break out of this while loop. Ensuring that even if the thread spuriously wakes up, we check our signal before moving forward.</span>
        <span class="n">paused</span> <span class="o">=</span> <span class="n">cvar</span><span class="nf">.wait</span><span class="p">(</span><span class="n">paused</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="nf">run_on_thread_wakeup</span><span class="p">()</span>
<span class="p">}</span>

</code></pre></div></div>

<details>

  <summary> Full code with Spurious wakeup guard</summary>

  <div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="n">io</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">sync</span><span class="p">::{</span><span class="nb">Arc</span><span class="p">,</span> <span class="n">Condvar</span><span class="p">,</span> <span class="n">Mutex</span><span class="p">,</span> <span class="n">MutexGuard</span><span class="p">};</span>
<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">signal</span><span class="p">:</span> <span class="nb">Arc</span><span class="o">&lt;</span><span class="p">(</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="nb">bool</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">Condvar</span><span class="p">)</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">new</span><span class="p">((</span><span class="nn">Mutex</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="k">false</span><span class="p">),</span> <span class="nn">Condvar</span><span class="p">::</span><span class="nf">new</span><span class="p">()));</span>
    <span class="k">let</span> <span class="n">input_arc</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signal</span><span class="p">);</span>
    <span class="k">let</span> <span class="n">counter_arc</span> <span class="o">=</span> <span class="nn">Arc</span><span class="p">::</span><span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">signal</span><span class="p">);</span>


    <span class="k">let</span> <span class="n">counter_thread</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">thread</span><span class="p">::</span><span class="nf">spawn</span><span class="p">(</span><span class="k">move</span> <span class="p">||</span> <span class="p">{</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="k">loop</span> <span class="p">{</span>
            <span class="c1">// check that the program is not paused</span>
            <span class="k">let</span> <span class="p">(</span><span class="n">lock</span><span class="p">,</span> <span class="n">cvar</span><span class="p">)</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="n">counter_arc</span><span class="p">;</span>

            <span class="c1">// check the mutex if program is paused</span>
            <span class="k">let</span> <span class="k">mut</span> <span class="n">paused</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
            <span class="k">if</span> <span class="o">*</span><span class="n">paused</span> <span class="p">{</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Program is paused"</span><span class="p">);</span>
                <span class="k">while</span> <span class="o">*</span><span class="n">paused</span> <span class="p">{</span>
                    <span class="n">paused</span> <span class="o">=</span> <span class="n">cvar</span><span class="nf">.wait</span><span class="p">(</span><span class="n">paused</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
                <span class="p">}</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter: {}"</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">count</span><span class="p">);</span>
            <span class="p">}</span>

            <span class="nf">drop</span><span class="p">(</span><span class="n">paused</span><span class="p">);</span>

            <span class="c1">// a thread sleep so we can slow down terminal output</span>
            <span class="nn">std</span><span class="p">::</span><span class="nn">thread</span><span class="p">::</span><span class="nf">sleep</span><span class="p">(</span><span class="nn">std</span><span class="p">::</span><span class="nn">time</span><span class="p">::</span><span class="nn">Duration</span><span class="p">::</span><span class="nf">from_secs</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span>
        <span class="p">}</span>
    <span class="p">});</span>


    <span class="c1">// main thread that takes user input to either pause or resume the counter</span>
    <span class="k">loop</span> <span class="p">{</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">user_input</span> <span class="o">=</span> <span class="nn">String</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>
        <span class="nn">io</span><span class="p">::</span><span class="nf">stdin</span><span class="p">()</span><span class="nf">.read_line</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">user_input</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
        <span class="k">match</span> <span class="n">user_input</span><span class="nf">.trim</span><span class="p">()</span> <span class="p">{</span>
            <span class="s">"p"</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">let</span> <span class="p">(</span><span class="n">lock</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="n">input_arc</span><span class="p">;</span>
                <span class="k">let</span> <span class="k">mut</span> <span class="n">is_paused</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
                <span class="o">*</span><span class="n">is_paused</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
                <span class="nf">drop</span><span class="p">(</span><span class="n">is_paused</span><span class="p">);</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter Paused"</span><span class="p">)</span>
            <span class="p">},</span>
            <span class="s">"r"</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">let</span> <span class="p">(</span><span class="n">lock</span><span class="p">,</span> <span class="n">cvar</span><span class="p">)</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="n">input_arc</span><span class="p">;</span>
                <span class="k">let</span> <span class="k">mut</span> <span class="n">is_paused</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
                <span class="o">*</span><span class="n">is_paused</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
                <span class="nf">drop</span><span class="p">(</span><span class="n">is_paused</span><span class="p">);</span>


                <span class="c1">// notify / wakeup whoever is waiting on this conditional variable</span>
                <span class="n">cvar</span><span class="nf">.notify_one</span><span class="p">();</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"Counter Resumed"</span><span class="p">)</span>
            <span class="p">},</span>
            <span class="n">x</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="nd">println!</span><span class="p">(</span><span class="s">"unknown command: '{}'"</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>  </div>
</details>

<blockquote>
  <p>Fun fact, I tried to see if i could experience any spurious wakeups and it only happened once over a span of 3 days.</p>
</blockquote>

<h4 id="2-explicitly-dropping-the-mutex">2. Explicitly Dropping the Mutex:</h4>
<p>I think this goes without saying, but ensure your mutex is only acquired when you need it and dropped immediately after use, if a mutex is held longer than needed, it can cause issues. This gets worse if your mutex is held in a loop like in our case as it will lead to a deadlock. The counter thread never lets go of the mutex and as such, the input thread can’t acquire the mutex and pause it.</p>

<p>The mutex can be dropped explicitly by calling the <code class="language-plaintext highlighter-rouge">drop</code> method, or by introducing local scopes for the mutexes that drop them once the local scope is out of scope (pun intended).</p>

<p>These are pretty much the same:</p>
<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="p">(</span><span class="n">lock</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="n">input_arc</span><span class="p">;</span>
<span class="k">let</span> <span class="k">mut</span> <span class="n">is_paused</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="o">*</span><span class="n">is_paused</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
<span class="nf">drop</span><span class="p">(</span><span class="n">is_paused</span><span class="p">);</span>
</code></pre></div></div>
<p>and</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="p">(</span><span class="n">lock</span><span class="p">,</span> <span class="n">cvar</span><span class="p">)</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="n">input_arc</span><span class="p">;</span>
<span class="p">{</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">is_paused</span> <span class="o">=</span> <span class="n">lock</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
    <span class="o">*</span><span class="n">is_paused</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// mutex is_paused dropped here</span>
</code></pre></div></div>

<p>That’s all for today, hope you enjoyed it :)</p>]]></content><author><name></name></author><category term="rust" /><category term="threads" /><summary type="html"><![CDATA[I recently worked on a rust project where I had to coordinate state between two threads, and with my Scala background, it wasn’t the easiest to implement in rust which does things a little differently.]]></summary></entry><entry><title type="html">Build a Simple Key Value Database from scratch with Rust</title><link href="/2023/05/21/rust-no-sql-database.html" rel="alternate" type="text/html" title="Build a Simple Key Value Database from scratch with Rust" /><published>2023-05-21T11:37:00+00:00</published><updated>2023-05-21T11:37:00+00:00</updated><id>/2023/05/21/rust-no-sql-database</id><content type="html" xml:base="/2023/05/21/rust-no-sql-database.html"><![CDATA[<p>I’ve always been fascitaned by databases and always wanted to learn more about its internals, in this tutorial, we will build a simple Key-Value store from scratch with Rust.</p>

<blockquote>
  <p>Due to the length of this topic, we will split it into chapter and at the end of each chapter will be the link to the PR containing the change for that chaper.</p>
</blockquote>

<p>Our Key-Value database is going to be called giraffeDB, why ? cos i love giraffes</p>

<p>Before we go ahead, it’s important to know that our goal is to aim for simplicity, so a lot of the implementations will be simplified to make it easier to follow.</p>

<h2 id="storage">Storage</h2>

<p>Our data is going to be stored to disk and it’s important to understand how our data will be stored and retrieved.</p>

<p>Databases typically store data in <code class="language-plaintext highlighter-rouge">pages</code> on disk, where a page is a fixed length contiguous block of memory. Pages are the smallest unit of data exchanged by the database and the disk. Database pages are stored contiguously on the disk to minimize disk seeks. <a href="https://en.wikipedia.org/wiki/Page_(computer_memory)">Here’s more on pages</a></p>

<p>At a high level, our database is just a binary file, could be 4MB or 4GB, but we will design it to store the data in pages, each of them with a number, so we can easily read from a page and write to a page.</p>

<p>Our Database is gonna have a page size of 4KB,unlike postgres that has one of <a href="https://www.postgresql.org/docs/current/storage-page-layout.html">8KB</a>,  which thus means our database can read 4KB of information at a go, , To  understand this better, let’s imagine we want to store a collection of students with their images as keys and values like such.</p>

<table>
  <thead>
    <tr>
      <th>student id</th>
      <th>student score</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>20</td>
    </tr>
    <tr>
      <td>2</td>
      <td>30</td>
    </tr>
    <tr>
      <td>3</td>
      <td>10</td>
    </tr>
    <tr>
      <td>4</td>
      <td>40</td>
    </tr>
  </tbody>
</table>

<p>Let’s now imagine that each row is the same as our page size (4KB), let’s see how this will be arranged in memory.</p>

<p>&lt;—- Insert Diagram of pages here —–&gt;</p>

<p>So if we start a database with a 4GB size, this should mean, we can store 1,000 pages (4KB * 1000).</p>

<p>Enough talk, let’s write some code.</p>

<p>Before we start, we will break the code into multiple parts, that explains different building blocks of the DB, first we start with the Data Access Layer</p>

<h2 id="part-1-data-access-layer">Part 1: Data Access Layer</h2>

<p>Our data access layer will hold our database file and handle reading and writing from and to pages. It is the wrapper around our database file, and every read/write operation must be done via our dal.</p>

<p>Our Dal will contain some basic configuration like page size, although, we’ll fix it to 4KB, this is just so we can tweak it later on.</p>

<p>Let’s create a new rust module called <code class="language-plaintext highlighter-rouge">dal.rs</code> where we’ll store our Dal struct.</p>

<p>Here’s what our dal initially looks like.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="k">pub</span> <span class="k">struct</span> <span class="n">Dal</span> <span class="p">{</span>
    <span class="n">file</span> <span class="p">:</span> <span class="n">File</span><span class="p">,</span>
    <span class="n">pageSize</span> <span class="p">:</span> <span class="nb">u32</span>
<span class="p">}</span>

<span class="k">impl</span> <span class="n">Dal</span><span class="p">{</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">path</span> <span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span><span class="p">,</span> <span class="n">pageSize</span> <span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">file</span> <span class="o">=</span>  <span class="nn">std</span><span class="p">::</span><span class="nn">fs</span><span class="p">::</span><span class="nn">OpenOptions</span><span class="p">::</span><span class="nf">new</span><span class="p">()</span>
            <span class="nf">.create</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
            <span class="nf">.write</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
            <span class="nf">.append</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
            <span class="nf">.mode</span><span class="p">(</span><span class="mi">0o666</span><span class="p">)</span>
            <span class="nf">.open</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
            <span class="nf">.unwrap</span><span class="p">();</span>

        <span class="n">Dal</span> <span class="p">{</span>
            <span class="n">file</span><span class="p">,</span>
            <span class="n">pageSize</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

</code></pre></div></div>

<p>Next thing is to create our Page struct, it should have a page number and hold data that is 4KB (Page Size for our DB).</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">pub</span> <span class="k">struct</span> <span class="n">Page</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="n">pageNumber</span> <span class="p">:</span> <span class="nb">u64</span><span class="p">,</span>
    <span class="k">pub</span> <span class="n">data</span> <span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">u8</span><span class="o">&gt;</span>
<span class="p">}</span>

<span class="k">impl</span>  <span class="n">Page</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">pageNumber</span> <span class="p">:</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">u64</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="n">Page</span> <span class="p">{</span>
            <span class="n">pageNumber</span><span class="p">:</span> <span class="n">pageNumber</span><span class="nf">.unwrap_or</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="c1">// if no page number, set to 0</span>
            <span class="n">data</span><span class="p">:</span> <span class="nd">vec!</span><span class="p">[</span><span class="mi">0_u8</span><span class="p">;</span>  <span class="n">PageSize</span> <span class="k">as</span> <span class="nb">usize</span><span class="p">]</span> <span class="c1">// create a 4kB zero filled vector </span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Now we write helper methods in our Dal struct to read from pages, and write to pages, to do that first, we add this helper method to allocate an empty page.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">pub</span> <span class="k">fn</span> <span class="nf">allocateEmptyPage</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">pageNumber</span> <span class="p">:</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">u64</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">Page</span> <span class="p">{</span>
    <span class="nn">Page</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="n">pageNumber</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Next, we write methods for reading and writing pages. To read a page, we need the page number, remember our database file is just a binary file that’s internally represented as a contiguous chunk of 4KB pages,so if we want to read page 5, we need to start reading from offset 20KB (5 * 4KB) and that will be the beginning of our page.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">pub</span> <span class="k">fn</span> <span class="nf">readPage</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">pageNumber</span> <span class="p">:</span> <span class="nb">u64</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">Page</span> <span class="p">{</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">page</span> <span class="o">=</span> <span class="k">self</span><span class="nf">.allocateEmptyPage</span><span class="p">(</span><span class="nf">Some</span><span class="p">(</span><span class="n">pageNumber</span><span class="p">));</span>
    <span class="k">let</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">pageNumber</span> <span class="o">*</span> <span class="k">self</span><span class="py">.pageSize</span> <span class="k">as</span> <span class="nb">u64</span><span class="p">;</span>

    <span class="c1">// fill in the data from poisition 'offset' into the buffer page.data</span>
    <span class="k">self</span><span class="py">.file</span><span class="nf">.read_at</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">page</span><span class="py">.data</span><span class="p">,</span> <span class="n">offset</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>

    <span class="n">page</span>
<span class="p">}</span>

<span class="k">pub</span> <span class="k">fn</span> <span class="nf">writePage</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">page</span> <span class="p">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">Page</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// get the right offset for the page so as not to overwrite any other data</span>
    <span class="k">let</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">page</span><span class="py">.pageNumber</span> <span class="o">*</span> <span class="k">self</span><span class="py">.pageSize</span> <span class="k">as</span> <span class="nb">u64</span><span class="p">;</span>

    <span class="c1">// write at offset 'offset', all that's in the buffer 'page.data' </span>
    <span class="k">self</span><span class="py">.file</span><span class="nf">.write_at</span><span class="p">(</span><span class="o">&amp;</span><span class="n">page</span><span class="py">.data</span><span class="p">,</span> <span class="n">offset</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="p">}</span>

</code></pre></div></div>

<p>With this basic set up, we can test that this works by attempting to write to some pages, and then try to see if what we did works.</p>

<p>In our <code class="language-plaintext highlighter-rouge">main.rs</code> file, we here’s a simple test we can run:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// initialize Dal</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">dal</span> <span class="o">=</span> <span class="nn">Dal</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"giraffe.db"</span><span class="p">,</span> <span class="nn">dal</span><span class="p">::</span><span class="n">PageSize</span><span class="p">);</span>

    <span class="k">let</span> <span class="k">mut</span> <span class="n">page_0</span> <span class="o">=</span> <span class="n">dal</span><span class="nf">.allocateEmptyPage</span><span class="p">(</span><span class="nf">Some</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>

    <span class="nf">writeToPage</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">page_0</span><span class="py">.data</span><span class="p">,</span> <span class="s">"Page 0, hello"</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>

    <span class="c1">// commit page</span>
    <span class="n">dal</span><span class="nf">.writePage</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">page_0</span><span class="p">);</span>

    <span class="k">let</span> <span class="k">mut</span> <span class="n">page_1</span> <span class="o">=</span> <span class="n">dal</span><span class="nf">.allocateEmptyPage</span><span class="p">(</span><span class="nf">Some</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span>

    <span class="nf">writeToPage</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">page_1</span><span class="py">.data</span><span class="p">,</span> <span class="s">"Page 1, hello"</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>

    <span class="c1">// commit page</span>
    <span class="n">dal</span><span class="nf">.writePage</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">page_1</span><span class="p">);</span>
<span class="p">}</span>

</code></pre></div></div>

<p>where the simple helper method <code class="language-plaintext highlighter-rouge">writeToPage</code> is defined as:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">writeToPage</span><span class="p">(</span><span class="n">buffer</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">mut</span><span class="p">[</span><span class="nb">u8</span><span class="p">],</span><span class="n">msg</span> <span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span><span class="p">,</span> <span class="n">startAt</span><span class="p">:</span> <span class="nb">usize</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// write to buffer from position `startAt`</span>
    <span class="n">buffer</span><span class="p">[</span><span class="n">startAt</span> <span class="o">..</span> <span class="n">msg</span><span class="nf">.len</span><span class="p">()]</span><span class="nf">.copy_from_slice</span><span class="p">(</span><span class="n">msg</span><span class="nf">.as_bytes</span><span class="p">());</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Let’s run our code with cargo run:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cargo run
</code></pre></div></div>

<p>Once this is done, hopefully there shouldn’t be any errors and we should see the file <code class="language-plaintext highlighter-rouge">giraffe.db</code>. Now, that’s a binary file and the best way to see what’s inside it is with the tool <code class="language-plaintext highlighter-rouge">hexdump</code></p>

<p>If we run the <code class="language-plaintext highlighter-rouge">hexdump</code> command with the <code class="language-plaintext highlighter-rouge">-C</code> flag, we can see ASCII representation of the bytes on the right as shown below</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>hexdump <span class="nt">-C</span> giraffe.db
</code></pre></div></div>

<p>we get this printed to our console.</p>

<p><img src="/assets/images/hexdump-part-1.png" alt="" /></p>

<p>We can easily see that the first page, represented by <code class="language-plaintext highlighter-rouge">00000000</code> to <code class="language-plaintext highlighter-rouge">00001000</code> just contains bytes that when interpreted as ASCII, reads <code class="language-plaintext highlighter-rouge">Page 0, hello</code> as seen on the right. The next 4KB, starting at <code class="language-plaintext highlighter-rouge">00001000</code> read <code class="language-plaintext highlighter-rouge">Page 1, hello</code>.</p>

<p>This a very good starting point, we have a Dal struct that can read and write a page, and we can see from our database file that it does as expected and our database can actually write to pages.</p>

<p>In the next part, we will introduce some new concepts that will improve our database.</p>

<p><a href="https://github.com/samuelorji/giraffeDB/pull/1/files">Here’s the github change</a></p>

<h2 id="part-2-freelist-metadata--and-persistence">Part 2: FreeList, Metadata  and Persistence</h2>
<h3 id="freelist">Freelist</h3>

<p>As with any database, data often gets delete, what happens to the a page when all its data is deleted, do we clean it up, do we ignore it and see our database file continuously increase, or do we reuse those pages for newer data.</p>

<p>We will use a Freelist to handle this issue, it is going to be responsoble for reusing/reclaiming empty pages. It’s going to be a simple component that we’ll attach to our Dal, it’s going to hold two fields for now, once called <code class="language-plaintext highlighter-rouge">maxPage</code> which represents the maximum page number of our database currently, and a list of page numbers called <code class="language-plaintext highlighter-rouge">releasedPages</code> that will store pages that have been emptied and are available for reuse.</p>

<p>So when we want to allocate a new page, the freelist first gives us a page from the <code class="language-plaintext highlighter-rouge">releasedPages</code> and it’s empty, it increments the <code class="language-plaintext highlighter-rouge">maxPage</code> counter:</p>

<blockquote>
  <p>We will do a little refactor here, we will make page numbers a 16 bit value as we don’t expect a page number to be greater than a 16 bit value. So head on to the page struct and change the <code class="language-plaintext highlighter-rouge">pageNumber</code> field to be a 16 bit value</p>
</blockquote>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="nd">#[derive(Debug)]</span>
<span class="k">struct</span> <span class="n">FreeList</span> <span class="p">{</span>
    <span class="n">maxPage</span> <span class="p">:</span> <span class="nb">u16</span><span class="p">,</span> <span class="c1">// Holds the maximum page allocated. maxPage*PageSize = fileSize</span>
    <span class="n">releasedPages</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">u16</span><span class="o">&gt;</span> <span class="c1">// Pages that were previously allocated but are now free</span>
<span class="p">}</span>

<span class="k">impl</span> <span class="n">FreeList</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="k">Self</span> <span class="p">{</span>
            <span class="n">maxPage</span> <span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
            <span class="n">releasedPages</span><span class="p">:</span> <span class="nd">vec!</span><span class="p">[]</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">getNextPageNumber</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u16</span> <span class="p">{</span>
        <span class="c1">// if possible, get pages from released pages first, else increment maxPage and return it</span>
        <span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">releasedPageId</span><span class="p">)</span> <span class="o">=</span> <span class="k">self</span><span class="py">.releasedPages</span><span class="nf">.pop</span><span class="p">()</span> <span class="p">{</span>
            <span class="n">releasedPageId</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">self</span><span class="py">.maxPage</span> <span class="o">+=</span> <span class="mi">1</span> <span class="p">;</span>
            <span class="k">self</span><span class="py">.maxPage</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">releasePage</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">pageNumber</span> <span class="p">:</span> <span class="nb">u16</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.releasedPages</span><span class="nf">.push</span><span class="p">(</span><span class="n">pageNumber</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

</code></pre></div></div>

<p>we can then add this as a component to the dal struct when creating it.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Dal</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">path</span> <span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span><span class="p">,</span> <span class="n">pageSize</span> <span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>

         <span class="c1">// rest of previous code // </span>
        <span class="k">let</span> <span class="n">freeList</span> <span class="o">=</span> <span class="nn">FreeList</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

        <span class="n">Dal</span> <span class="p">{</span>
            <span class="n">file</span><span class="p">,</span>
            <span class="n">pageSize</span><span class="p">,</span>
            <span class="n">freeList</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

</code></pre></div></div>

<h3 id="metadata">Metadata</h3>

<p>It’s typical for databases to store some metadata in a page, this typically holds data that’s crucial for the database operation. For now, we will just have store the freelist page.</p>

<p>This metadata will always be stored in Page 0, the very first page and it will also be part of the Dal component.</p>

<p>We will add more metadata as we continue. Let’s create a struct that we’ll call <code class="language-plaintext highlighter-rouge">Meta</code></p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">#[derive(Debug)]</span>
<span class="k">struct</span> <span class="n">Meta</span> <span class="p">{</span>
    <span class="n">freeListPage</span> <span class="p">:</span> <span class="nb">u16</span>
<span class="p">}</span>

<span class="k">impl</span> <span class="n">Meta</span> <span class="p">{</span>
    <span class="k">pub</span>  <span class="k">fn</span> <span class="nf">new</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="k">Self</span> <span class="p">{</span>
            <span class="c1">// start with a seed value of 0, this may change later on</span>
            <span class="n">freeListPage</span> <span class="p">:</span> <span class="mi">0</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

</code></pre></div></div>

<p>Now, let’s add this to our dal component.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Dal</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">path</span> <span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span><span class="p">,</span> <span class="n">pageSize</span> <span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>

         <span class="c1">// rest of previous code // </span>
         <span class="k">let</span> <span class="n">meta</span> <span class="o">=</span> <span class="nn">Meta</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

        <span class="n">Dal</span> <span class="p">{</span>
            <span class="n">file</span><span class="p">,</span>
            <span class="n">pageSize</span><span class="p">,</span>
            <span class="n">freeList</span><span class="p">,</span>
            <span class="n">meta</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

</code></pre></div></div>

<h3 id="persistence">Persistence</h3>

<p>If you’ve noticed, you’ll notice that our database seems to be recreated everytime the application is restarted. That is definitely not good, and in this section, we will try to implement persistence for our database.</p>

<p>Basically we want a way to serialize and deserialize our Dal to and from disk. To do this, we need to be able to convert our <code class="language-plaintext highlighter-rouge">FreeList</code> and <code class="language-plaintext highlighter-rouge">Meta</code> data structyres to and from bytes.</p>

<p>Since we’re going to be doing some bytes manipulation, let’s use the <a href="https://docs.rs/bytes/1.4.0/bytes/">bytes</a> crate to help with this (<a href="https://docs.rs/bytes/1.4.0/bytes/">installation here</a>).</p>

<blockquote>
  <p>I’m using a little endian machine, <a href="https://stackoverflow.com/a/66308651">here’s how to find out the endianness of your machine</a></p>
</blockquote>

<p>To formalize serialization and deserialization of structs to bytes, we can define the following traits in a new module called <code class="language-plaintext highlighter-rouge">util.rs</code>. This module may hold utilities like constants.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">pub</span> <span class="k">trait</span> <span class="n">Serialize</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">serialize</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">buffer</span> <span class="p">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="nb">u8</span><span class="p">]);</span>
<span class="p">}</span>

<span class="k">pub</span> <span class="k">trait</span> <span class="n">Deserialize</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">deserialize</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">buffer</span> <span class="p">:</span> <span class="o">&amp;</span><span class="p">[</span><span class="nb">u8</span><span class="p">]);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Our <code class="language-plaintext highlighter-rouge">serialize</code> function, takes a mutable buffer and serializes <code class="language-plaintext highlighter-rouge">self</code> into the buffer, while the <code class="language-plaintext highlighter-rouge">deserialize</code> function takes a mutable <code class="language-plaintext highlighter-rouge">self</code>and does the opposite.</p>

<p>Let’s now create serialize and deserialize function for our <code class="language-plaintext highlighter-rouge">Meta</code> and <code class="language-plaintext highlighter-rouge">FreeList</code> structs:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Serialize</span><span class="o">&lt;</span><span class="n">Meta</span><span class="o">&gt;</span> <span class="k">for</span> <span class="n">Meta</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">serialize</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">buffer</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="nb">u8</span><span class="p">])</span> <span class="p">{</span>
        <span class="c1">// To serialize a Meta</span>
        <span class="c1">// - 8 bytes for the freelist page</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">position</span><span class="p">:</span> <span class="nb">usize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="nn">LittleEndian</span><span class="p">::</span><span class="nf">write_u64</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">buffer</span><span class="p">[</span><span class="n">position</span><span class="o">..</span><span class="p">],</span> <span class="k">self</span><span class="py">.freeListPage</span><span class="p">);</span>
        <span class="n">position</span> <span class="o">+=</span> <span class="mi">8</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">impl</span> <span class="n">Deserialize</span><span class="o">&lt;</span><span class="n">Meta</span><span class="o">&gt;</span> <span class="k">for</span> <span class="n">Meta</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">deserialize</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">buffer</span><span class="p">:</span> <span class="o">&amp;</span><span class="p">[</span><span class="nb">u8</span><span class="p">])</span> <span class="p">{</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">position</span><span class="p">:</span> <span class="nb">usize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="c1">// read 8 bytes for freelist position at position `position`</span>
        <span class="k">let</span> <span class="n">freeListPage</span> <span class="o">=</span> <span class="nn">LittleEndian</span><span class="p">::</span><span class="nf">read_u64</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">[</span><span class="n">position</span><span class="o">..</span><span class="p">]);</span>
        <span class="n">position</span> <span class="o">+=</span> <span class="n">PAGE_NUM_SIZE</span> <span class="k">as</span> <span class="nb">usize</span><span class="p">;</span>

        <span class="k">self</span><span class="py">.freeListPage</span> <span class="o">=</span> <span class="n">freeListPage</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>For the FreeList:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Serialize</span><span class="o">&lt;</span><span class="n">FreeList</span><span class="o">&gt;</span> <span class="k">for</span> <span class="n">FreeList</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">serialize</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">buffer</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="p">[</span><span class="nb">u8</span><span class="p">])</span> <span class="p">{</span>

        <span class="c1">// To serialize a Meta</span>
        <span class="c1">// - 2 bytes for max page (u16)</span>
        <span class="c1">// - 2 bytes for length of released list (vector in our case)</span>
        <span class="c1">// - 2 bytes for each released page number</span>

        <span class="c1">// write max page (2 bytes)</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">cursor</span><span class="p">:</span> <span class="nb">u64</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="nn">LittleEndian</span><span class="p">::</span><span class="nf">write_u16</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">buffer</span><span class="p">[</span><span class="n">cursor</span> <span class="k">as</span> <span class="nb">usize</span><span class="o">..</span><span class="p">],</span> <span class="k">self</span><span class="py">.maxPage</span><span class="p">);</span>
        <span class="n">cursor</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">;</span>

        <span class="c1">// write length of released pages (2 bytes)</span>
        <span class="nn">LittleEndian</span><span class="p">::</span><span class="nf">write_u16</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">buffer</span><span class="p">[</span><span class="n">cursor</span> <span class="k">as</span> <span class="nb">usize</span><span class="o">..</span><span class="p">],</span> <span class="k">self</span><span class="py">.releasedPages</span><span class="nf">.len</span><span class="p">()</span> <span class="k">as</span> <span class="nb">u16</span><span class="p">);</span>
        <span class="n">cursor</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">;</span>

        <span class="c1">// for each released page, write the released page number (2 bytes)</span>
        <span class="k">for</span> <span class="n">pgNumber</span> <span class="k">in</span> <span class="o">&amp;</span><span class="k">self</span><span class="py">.releasedPages</span> <span class="p">{</span>
            <span class="nn">LittleEndian</span><span class="p">::</span><span class="nf">write_u16</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">buffer</span><span class="p">[</span><span class="n">cursor</span> <span class="k">as</span> <span class="nb">usize</span><span class="o">..</span><span class="p">],</span> <span class="o">*</span><span class="n">pgNumber</span><span class="p">);</span>
            <span class="n">cursor</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">impl</span> <span class="n">Deserialize</span><span class="o">&lt;</span><span class="n">FreeList</span><span class="o">&gt;</span> <span class="k">for</span> <span class="n">FreeList</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">deserialize</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">buffer</span><span class="p">:</span> <span class="o">&amp;</span><span class="p">[</span><span class="nb">u8</span><span class="p">])</span> <span class="p">{</span>

        <span class="c1">// To deserialize a Meta</span>
        <span class="c1">// - 2 bytes for max page (u16)</span>
        <span class="c1">// - 2 bytes for length of released list (vector in our case)</span>
        <span class="c1">// - 2 bytes for each released page number</span>

        <span class="c1">// read max page (2 bytes)</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">cursor</span> <span class="p">:</span> <span class="nb">usize</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="k">let</span> <span class="n">maxPage</span> <span class="o">=</span> <span class="nn">LittleEndian</span><span class="p">::</span><span class="nf">read_u16</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">);</span>
        <span class="n">cursor</span> <span class="o">+=</span><span class="mi">2</span><span class="p">;</span>

        <span class="c1">// read length of released pages (2 bytes)</span>
        <span class="k">let</span> <span class="n">numReleasedPages</span> <span class="o">=</span> <span class="nn">LittleEndian</span><span class="p">::</span><span class="nf">read_u16</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">[</span><span class="n">cursor</span> <span class="o">..</span> <span class="p">]);</span>
        <span class="n">cursor</span> <span class="o">+=</span><span class="mi">2</span><span class="p">;</span>

        <span class="k">let</span> <span class="k">mut</span> <span class="n">releasedPages</span> <span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">u16</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nn">Vec</span><span class="p">::</span><span class="nf">with_capacity</span><span class="p">(</span><span class="n">numReleasedPages</span> <span class="k">as</span> <span class="nb">usize</span><span class="p">);</span>

        <span class="c1">// for each released page, read the released page number (2 bytes)</span>
        <span class="k">for</span> <span class="n">_</span> <span class="k">in</span> <span class="mi">0</span><span class="o">..</span><span class="n">numReleasedPages</span> <span class="p">{</span>
            <span class="k">let</span> <span class="n">releasedPage</span> <span class="o">=</span> <span class="nn">LittleEndian</span><span class="p">::</span><span class="nf">read_u16</span><span class="p">(</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">[</span><span class="n">cursor</span> <span class="k">as</span> <span class="nb">usize</span> <span class="o">..</span><span class="p">]);</span>
            <span class="n">releasedPages</span><span class="nf">.push</span><span class="p">(</span><span class="n">releasedPage</span><span class="p">);</span>
            <span class="n">cursor</span> <span class="o">+=</span> <span class="mi">2</span>

        <span class="p">}</span>

        <span class="k">self</span><span class="py">.maxPage</span> <span class="o">=</span> <span class="n">maxPage</span> <span class="p">;</span>
        <span class="k">self</span><span class="py">.releasedPages</span> <span class="o">=</span> <span class="n">releasedPages</span>
    <span class="p">}</span>
<span class="p">}</span>

</code></pre></div></div>

<p>Now that we’ve defined <code class="language-plaintext highlighter-rouge">serialize</code> and <code class="language-plaintext highlighter-rouge">deserialize</code> methods for our structs, let’s write some helper methods on the dal struct that can read and write a meta and freelist:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="k">impl</span> <span class="n">Dal</span> <span class="p">{</span>
    <span class="c1">// rest of code</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">writeMeta</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">Page</span> <span class="p">{</span>
        <span class="c1">// meta page is 0 </span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">page</span> <span class="o">=</span>  <span class="k">self</span><span class="nf">.allocateEmptyPage</span><span class="p">(</span><span class="nf">Some</span><span class="p">(</span><span class="n">META_PAGE_NUMBER</span><span class="p">));</span> <span class="c1">// META_PAGE_NUMBER = 0</span>
        
        <span class="c1">// serialize the meta struct into the `page.data` buffer</span>
        <span class="k">self</span><span class="py">.meta</span><span class="nf">.serialize</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">page</span><span class="py">.data</span><span class="p">[</span><span class="o">..</span><span class="p">]);</span>

        <span class="c1">// write the page to disk</span>
        <span class="k">self</span><span class="nf">.writePage</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">page</span><span class="p">);</span>

        <span class="n">page</span>
    <span class="p">}</span>

    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">readMeta</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">Meta</span> <span class="p">{</span>
        <span class="c1">// read page</span>
        <span class="k">let</span> <span class="n">page</span> <span class="o">=</span> <span class="k">self</span><span class="nf">.readPage</span><span class="p">(</span><span class="n">META_PAGE_NUMBER</span><span class="p">);</span>

        <span class="c1">// create an empty meta</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">meta</span> <span class="o">=</span> <span class="nn">Meta</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

        <span class="c1">// deserialize what's in the read `page.data` into the empty meta struct</span>
        <span class="n">meta</span><span class="nf">.deserialize</span><span class="p">(</span><span class="o">&amp;</span><span class="n">page</span><span class="py">.data</span><span class="p">);</span>
        <span class="n">meta</span>
    <span class="p">}</span>

    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">writeFreeList</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">Page</span> <span class="p">{</span>
        <span class="c1">// get freelist page from meta</span>
        <span class="k">let</span> <span class="n">freeListPage</span> <span class="o">=</span> <span class="k">self</span><span class="py">.meta.freeListPage</span><span class="p">;</span>
        
        <span class="k">let</span> <span class="k">mut</span> <span class="n">page</span> <span class="o">=</span> <span class="k">self</span><span class="nf">.allocateEmptyPage</span><span class="p">(</span><span class="nf">Some</span><span class="p">(</span><span class="n">freeListPage</span><span class="p">));</span>
        
        <span class="c1">// serialize free list into the empty page</span>
        <span class="k">self</span><span class="py">.freeList</span><span class="nf">.serialize</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">page</span><span class="py">.data</span><span class="p">);</span>

        <span class="c1">// write page </span>
        <span class="k">self</span><span class="nf">.writePage</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">page</span><span class="p">);</span>
        <span class="n">page</span>
    <span class="p">}</span>

    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">readFreeList</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// get freelist page from meta</span>
        <span class="k">let</span> <span class="n">freeListPage</span> <span class="o">=</span> <span class="k">self</span><span class="py">.meta.freeListPage</span><span class="p">;</span>
        
        <span class="c1">// read freelist page</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">page</span> <span class="o">=</span> <span class="k">self</span><span class="nf">.readPage</span><span class="p">(</span><span class="n">freeListPage</span><span class="p">);</span>

        <span class="c1">// deserialize free list page</span>
        <span class="k">self</span><span class="py">.freeList</span><span class="nf">.deserialize</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">page</span><span class="py">.data</span><span class="p">);</span>

    <span class="p">}</span>
<span class="p">}</span>

</code></pre></div></div>

<p>One other thing we need to do is change how the <code class="language-plaintext highlighter-rouge">Dal::new()</code> method that creates a new <code class="language-plaintext highlighter-rouge">Dal</code> works, currently it just assumes that the file doesn’t exist and probably tries to recreate it. This is definitely not what we want. What we want instead is for the method to check if the database file exists, if it does, it tries to deserialize some of the data in it like the <code class="language-plaintext highlighter-rouge">Meta</code> and <code class="language-plaintext highlighter-rouge">FreeList</code>, otherwise it creates the new file.</p>

<blockquote>
  <p>We will do some refactoring here to not accept page size from outside also</p>
</blockquote>

<p>Here’s what the method will look like now:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Dal</span> <span class="p">{</span>

    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">path</span> <span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nn">Path</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="n">path</span><span class="p">)</span><span class="nf">.exists</span><span class="p">())</span> <span class="p">{</span>
            <span class="c1">// database file doesn't exist, create a new database file</span>
            <span class="k">let</span> <span class="n">file</span> <span class="o">=</span>  <span class="nn">std</span><span class="p">::</span><span class="nn">fs</span><span class="p">::</span><span class="nn">OpenOptions</span><span class="p">::</span><span class="nf">new</span><span class="p">()</span>
                <span class="nf">.create</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
                <span class="nf">.write</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
                <span class="nf">.read</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
                <span class="nf">.append</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
                <span class="nf">.mode</span><span class="p">(</span><span class="mi">0o666</span><span class="p">)</span>
                <span class="nf">.open</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
                <span class="nf">.unwrap</span><span class="p">();</span>

            <span class="n">c</span>
            <span class="k">let</span> <span class="k">mut</span> <span class="n">freeList</span> <span class="o">=</span> <span class="nn">FreeList</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>
            <span class="k">let</span> <span class="k">mut</span> <span class="n">meta</span> <span class="o">=</span> <span class="nn">Meta</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>


            <span class="k">let</span> <span class="k">mut</span> <span class="n">dal</span> <span class="o">=</span> <span class="n">Dal</span> <span class="p">{</span>
                <span class="n">file</span><span class="p">,</span>
                <span class="n">pageSize</span> <span class="p">:</span> <span class="n">PAGE_SIZE</span><span class="p">,</span> <span class="c1">// PAGE_SIZE is 4KB (4096)</span>
                <span class="n">meta</span><span class="p">,</span>
                <span class="n">freeList</span>
            <span class="p">};</span>

            <span class="c1">// set freelist to page 1 and increment maxPage in the freelist struct</span>
            <span class="k">let</span> <span class="n">freeListPageNumber</span> <span class="o">=</span> <span class="n">dal</span><span class="py">.freeList</span><span class="nf">.getNextPageNumber</span><span class="p">();</span>
            <span class="n">dal</span><span class="py">.meta.freeListPage</span> <span class="o">=</span> <span class="n">freeListPageNumber</span><span class="p">;</span>

            <span class="c1">// write the meta struct to disk</span>
            <span class="n">dal</span><span class="nf">.writeMeta</span><span class="p">();</span>
            <span class="n">dal</span>

        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="c1">// file exists, read meta to find freelist page and deserialize accordingly</span>
            <span class="k">let</span> <span class="n">file</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">fs</span><span class="p">::</span><span class="nn">OpenOptions</span><span class="p">::</span><span class="nf">new</span><span class="p">()</span>
                <span class="nf">.write</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
                <span class="nf">.read</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
                <span class="nf">.append</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
                <span class="nf">.open</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
                <span class="nf">.unwrap</span><span class="p">();</span>

            <span class="c1">// create new freelist and mets struct</span>
            <span class="k">let</span> <span class="k">mut</span> <span class="n">freeList</span> <span class="o">=</span> <span class="nn">FreeList</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>
            <span class="k">let</span> <span class="k">mut</span> <span class="n">meta</span> <span class="o">=</span> <span class="nn">Meta</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

            <span class="k">let</span> <span class="k">mut</span> <span class="n">dal</span> <span class="o">=</span> <span class="n">Dal</span> <span class="p">{</span>
                <span class="n">file</span><span class="p">,</span>
                <span class="n">pageSize</span> <span class="p">:</span> <span class="n">PAGE_SIZE</span><span class="p">,</span>
                <span class="n">meta</span><span class="p">,</span>
                <span class="n">freeList</span>
            <span class="p">};</span>

            <span class="c1">// read meta from disk and store in dal struct</span>
             <span class="n">dal</span><span class="nf">.readMeta</span><span class="p">();</span>

            <span class="c1">// read freeList from and store in dal struct</span>
            <span class="n">dal</span><span class="nf">.readFreeList</span><span class="p">();</span>
            <span class="n">dal</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// rest of code</span>
<span class="p">}</span>

</code></pre></div></div>]]></content><author><name></name></author><category term="rust" /><category term="nosql" /><summary type="html"><![CDATA[I’ve always been fascitaned by databases and always wanted to learn more about its internals, in this tutorial, we will build a simple Key-Value store from scratch with Rust.]]></summary></entry><entry><title type="html">Practically Understanding UTF-8 encoding</title><link href="/2022/01/30/practically-understanding-utf-8-encoding.html" rel="alternate" type="text/html" title="Practically Understanding UTF-8 encoding" /><published>2022-01-30T00:00:00+00:00</published><updated>2022-01-30T00:00:00+00:00</updated><id>/2022/01/30/practically-understanding-utf-8-encoding</id><content type="html" xml:base="/2022/01/30/practically-understanding-utf-8-encoding.html"><![CDATA[<p>If you save a text file with non-english characters and wondered how the editor knows how to interpret it correctly, then this is for you.</p>

<p>The Unicode standard defines a set of rules that govern how text is encoded and stored as bytes, such that it can be read back preserving the information that was encoded. In this tutorial, we’ll particularly look at <a href="https://en.wikipedia.org/wiki/UTF-8#Description">UTF-8</a>.</p>

<p>In UTF-8, characters are given a number, also known as code point, and these code points are grouped into what we will call code blocks for simplicity. The code block determines to an extent, how many bytes will be used to store the data.</p>

<p>Now, let’s see what this means in practice. if we open a notepad and type in the word “hello”, save the file as a text file (“sample.txt”), and check the file size, we will see it’s 5 bytes which makes a little sense as there are only 5 characters:</p>

<p><a href="https://www.youtube.com/watch?v=MijmeoH9LT4">Here’s a video explanation</a></p>

<p><img src="/assets/images/Screenshot-2022-01-30-at-10.13.16.png" alt="" /></p>

<p>We see ‘5’ Just before Jan 30, which is the size of the file. Now, let’s add the Chinese character ‘不’ just after hello in our text file like this “hello不”. If we save that and check the file size again:</p>

<p><img src="/assets/images/Screenshot-2022-01-30-at-10.17.02.png" alt="" /></p>

<p>We see that our file size is now 8 bytes. But we only added a single Chinese character, why does that add 3 extra bytes instead of 1.</p>

<p>The answer to that is that our text file is UTF-8 encoded, so some characters need a single byte, while some others need more than one byte.</p>

<p>The English alphabet typically needs one byte or 8 bits to store every possible English character. We can see it here in this <a href="https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html">ASCII chart</a>. ASCII is simply just some convention to map characters or symbols to a number. To make sense of the ASCII chart, let’s print out each character in our text file without the Chinese character. According to our chart, the characters “hello” should be 104, 101, 108, 108, 111. This simple rust code shows that:</p>
<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">res</span>  <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">fs</span><span class="p">::</span><span class="nf">read</span><span class="p">(</span><span class="s">"sample.txt"</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"character:t number"</span><span class="p">);</span>
    <span class="k">for</span> <span class="n">elem</span> <span class="k">in</span> <span class="n">res</span> <span class="p">{</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"  {}tt {}"</span><span class="p">,</span><span class="n">elem</span> <span class="k">as</span> <span class="nb">char</span><span class="p">,</span><span class="o">&amp;</span><span class="n">elem</span><span class="p">)</span>
    <span class="p">}</span>
</code></pre></div></div>

<p>Which prints out :</p>

<p><img src="/assets/images/Screenshot-2022-01-30-at-10.35.38.png" alt="" /></p>

<p>Now, this makes sense, but what happens when we add our Chinese character ‘不’ in there:</p>

<p><img src="/assets/images/Screenshot-2022-01-30-at-10.39.54.png" alt="" /></p>

<p>We can see that everything after “hello” isn’t what we expected, the three numbers after “hello” i.e( 228, 184, 141 ) should have represented the Chinese Character ‘不’, but we’re seeing something else instead:</p>

<p>But our notepad has no problem interpreting those numbers to represent the Chinese Character, so it’s obvious that it’s doing something we’re not doing, or has some piece of information that enables it to properly translate those numbers into the Chinese character. we actually expected. To understand how this works, <strong>we’ll get a little more technical</strong> and look into the bit representation of these characters and more.</p>

<p>Remember when we said that every character has a code point (number) and belongs to a code block that defines how many bytes are used to store the character. Let’s see the code point for our Chinese Character ‘不’</p>

<p><img src="/assets/images/Screenshot-2022-01-30-at-10.56.16.png" alt="" /></p>

<p>One thing we can see is that the number/ code point given to this character is 19981, and the hex representation is <strong>4E0D</strong>. Now in UTF-8, when we write the code point of a character, we write as U+, followed by its hex representation, so for our Chinese character, the code point is written as <strong>U+4E0D</strong>.</p>

<p><a href="https://en.wikipedia.org/wiki/Unicode_block#List_of_blocks">Here are the code blocks we have</a>. To make our example simple, will summarise the code blocks, giving the range of values and how many bytes can be used to store their values:</p>

<h2 id="code-blocks---bytes-needed">Code Blocks &lt;-&gt; Bytes needed</h2>

<table>
  <thead>
    <tr>
      <th>First Code Point</th>
      <th>Last Code Point</th>
      <th>Bytes needed</th>
      <th>Exact Bits needed</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>U+0000 (0)</td>
      <td>U+007F (127)</td>
      <td>1</td>
      <td>7</td>
    </tr>
    <tr>
      <td>U+0080 (128)</td>
      <td>U+07FF (2047)</td>
      <td>2</td>
      <td>11</td>
    </tr>
    <tr>
      <td>U+0800 (2048)</td>
      <td>U+FFFF (65535)</td>
      <td>3</td>
      <td>16</td>
    </tr>
    <tr>
      <td>U+10000 (65536)</td>
      <td>U+10FFFF (1114111)</td>
      <td>4</td>
      <td>21</td>
    </tr>
  </tbody>
</table>

<p>Now, we can see that our Chinese Character falls in the 3rd code block that needs 3 bytes to store its data. We will get to “Exact Bits needed” soon.</p>

<p>Before we go into how this character is encoded into bytes, let’s just see the binary as well as hex representation each character in our text file that contains the Chinese character:</p>

<p>This piece of rust code helps us:</p>
<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">println!</span><span class="p">(</span><span class="s">"character: t Binary:t decimal t"</span><span class="p">);</span>
<span class="k">for</span> <span class="n">elem</span> <span class="k">in</span> <span class="n">res</span> <span class="p">{</span>
  <span class="nd">println!</span><span class="p">(</span><span class="s">"  {}</span><span class="se">\t\t</span><span class="s">{:#010b}t  {}"</span><span class="p">,</span><span class="n">elem</span> <span class="k">as</span> <span class="nb">char</span><span class="p">,</span><span class="o">&amp;</span><span class="n">elem</span><span class="p">,</span><span class="o">&amp;</span><span class="n">elem</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Our output is:</p>

<p><img src="/assets/images/Screenshot-2022-01-30-at-11.23.09.png" alt="" /></p>

<p>It’s worth noting that after the ‘o’ in “hello”, the Chinese character is stored as 3 bytes with numbers (228,184,141) and binary representation (excluding the ‘0b’):</p>

<p><code class="language-plaintext highlighter-rouge">11100100 10111000 10001101</code></p>

<p>Now, how did our text editor convert our Chinese character that had a number <strong>19981</strong> or a code point of <strong>U+4E0D</strong> into that binary format.</p>

<p>Our first guess will be to convert the number directly into binary, but we will get this 16-bit value:</p>

<p><code class="language-plaintext highlighter-rouge">01001110 00001101</code></p>

<p>Which doesn’t look like what was stored by our notepad. Also, we see that our data can fit into 16 bits, but the encoding says we must use 3 bytes due to the code block it belongs to. Then it’s obvious that the other 8 bits will store some other kind of data we don’t know about yet.</p>

<p><strong>Think of UTF-8 encoding as some mechanism to pass metadata along with the actual data so that it can be interpreted correctly</strong></p>

<p>Now, let’s see how these characters are encoded:</p>

<h3 id="utf-8-encodingdecoding"><strong>UTF-8 Encoding/Decoding</strong></h3>

<p>We will try to oversimplify this and make it very easy to understand.</p>

<h3 id="writing--encoding"><strong>Writing / Encoding:</strong></h3>

<p>Let’s see how our Chinese character ‘不’ is practically encoded. Remember that its code point is <strong>U+4E0D</strong> (decimal <strong>19981</strong>) and from our Code block &lt;-&gt; bytes needed, we see that it falls in the block that needs 3 bytes, so we <strong>must</strong> use 3 bytes to store this information.</p>

<p>For simplicity, let’s think of our 3 bytes as 3 containers of 8 bits (1 byte) all with empty values. Will use ‘x’ to represent an empty bit, i.e, a bit yet to be filled with a 1 or 0.</p>

<p><strong>3 Byte Container</strong></p>

<table>
  <thead>
    <tr>
      <th>Container 1</th>
      <th>Container 2</th>
      <th>Container 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>xxxxxxxx</td>
      <td>xxxxxxxx</td>
      <td>xxxxxxxx</td>
    </tr>
  </tbody>
</table>

<p>According to the UTF-8 Encoding spec, it says that because our character will be three bytes long, <strong>we must fill the leading bytes (left most bytes), which in our case is in container 1, with three 1s followed by a 0.</strong> <strong>i.e, begin with 1110</strong> to signify that this byte belongs to a group of 3 bytes</p>

<p>So we’ll fill the first four empty bits, ‘x’ in our case, with three 1s and a 0. as explained by the spec. Because the encoding will be three bytes long, we have to do this.</p>

<p>Our container then looks like this.:</p>

<p><strong>3 Byte Container</strong></p>

<table>
  <thead>
    <tr>
      <th>Container 1</th>
      <th>Container 2</th>
      <th>Container 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1110xxxx</td>
      <td>xxxxxxxx</td>
      <td>xxxxxxxx</td>
    </tr>
  </tbody>
</table>

<p>Now, the encoding spec also says that the leading (leftmost) bits of the next two bytes, which in our case is in container 2 and 3, <strong>should begin with 10</strong>. This signifies a continuation byte, i.e, this byte is not standalone and should not be interpreted as such, <strong>rather it is part of a previous sequence of bytes that should be combined and read as a single value.</strong> This is the most important thing to be aware of.</p>

<p>What this encoding says simply is that, when you see a byte that begins with <strong>10</strong>, don’t just interpret it as a character, but instead treat it as a continuation of some byte sequence that needs to be read together at once. This was the mistake we made when reading the Chinese character, we were blindly reading each byte and trying to convert it into a character, not knowing that it was part of a contiguous byte sequence that resulted in a larger code point, number of character.</p>

<p>If we do this, our container should look like this:</p>

<p><strong>3 Byte Container</strong></p>

<table>
  <thead>
    <tr>
      <th>Container 1</th>
      <th>Container 2</th>
      <th>Container 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1110xxxx</td>
      <td>10xxxxxx</td>
      <td>10xxxxxx</td>
    </tr>
  </tbody>
</table>

<p>Now, if you count how many empty slots denoted by ‘x’ we have left, we see that it’s 16, which as we saw in the previous section is the exact amount of bits we need to store our Chinese character with a code point of <strong>U+4E0D</strong> <strong>(19981)</strong> which is represented in binary as</p>

<p><code class="language-plaintext highlighter-rouge">01001110 00001101</code></p>

<p>Now, let’s fill those empty slots (‘x’) with our 16-bit code point starting from the left. Our container will then look like this:</p>

<p><strong>3 Byte Container</strong></p>

<table>
  <thead>
    <tr>
      <th>Container 1</th>
      <th>Container 2</th>
      <th>Container 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>11100100</td>
      <td>10111000</td>
      <td>10001101</td>
    </tr>
  </tbody>
</table>

<p>With this, we’re done with our encoding. So our UTF-8 encoding for the code point <strong>U+4E0D</strong> is :</p>

<p><code class="language-plaintext highlighter-rouge">11100100 10111000 10001101</code></p>

<p>If we look at this number, we will see it is exactly the same binary representation of the last three bytes used to represent the Chinese character that we printed out (excluding the 0b):</p>

<p><img src="/assets/images/Screenshot-2022-01-30-at-12.13.39.png" alt="" /></p>

<p>Now, we can see that our notepad actually did UTF-8 encode the Chinese character, but our problem was we were incorrectly reading it programmatically.</p>

<p>Now that we’re confident that our text was correctly encoded, let’s see how to properly decode it.</p>

<p>P.S, We’ll call the extra 8 bits of data we added “metadata” as we’ll use them to interpret our data in the next section.</p>

<p>Here’s an excerpt from <a href="https://en.wikipedia.org/wiki/UTF-8#Description">Wikipedia.</a></p>

<p><img src="/assets/images/Screenshot-2022-01-30-at-14.22.25.png" alt="" /></p>

<h3 id="readingdecoding"><strong>Reading/Decoding:</strong></h3>

<p>According to the UTF-8 spec, when reading bytes, we should be careful of how we interpret a contiguous stream of bytes, <strong>some should be interpreted individually, while some should be interpreted as a group</strong>.</p>

<p>Here’s an <strong>oversimplified</strong> summary of how to interpret a stream of bytes (8-bit sequence) in UTF-8:</p>

<ol>
  <li>If a byte starts with the bit 0, then it’s a single byte data and rest of the bits can be interpreted or decoded as an individual code point or number or character in our case.</li>
  <li>If a byte starts with a sequence of 1s before a 0, the number of 1s it starts with, i.e, the numbers of 1s before the very first 0 tells the size of the group or nunber of bytes that should be collected and processed or decoded together. Everything else in this byte after the first 0 is part of the data itself.<br />
 In our example, we see that our Chinese character starts with: <code class="language-plaintext highlighter-rouge">11100100</code> which means that this byte is part of a group of 3 bytes that should be processed together, so the nth, n + 1 and n + 2 bytes together form the group that should be decoded together.</li>
  <li>If a byte starts with <strong>10</strong>, then it’s a continuation byte and is linked to the byte before it and every bit after the <strong>10</strong> or the first 0 is the data itself</li>
</ol>

<p>Of course, this is an oversimplification, but let’s use these rules to decode our stream of text and hope we can get back “hello不”.</p>

<p>First, let’s see what the stream of bytes look like before we start decoding, here’s what our text looks like as a stream of bytes:</p>

<p><code class="language-plaintext highlighter-rouge">01101000 01100101 01101100 01101100 01101111 11100100 10111000 10001101</code></p>

<p>Let’s try to parse these bytes.</p>

<p><strong>P.S, we’ll use this <a href="https://onlineutf8tools.com/convert-code-points-to-utf8">tool</a>, to put in the decimal equivalent of our code point to translate from hex to it’s Character representation</strong></p>

<p>The very first byte is <code class="language-plaintext highlighter-rouge">01101000</code>, it starts with a 0, so it’s an individual code point, so we remove the first 0 and we’re left with <code class="language-plaintext highlighter-rouge">1101000</code>, now this translates to <strong>U+0068</strong> or decimal <strong>104</strong> which according to our tool translates to the letter <strong>‘h’.</strong></p>

<p>The second byte is <code class="language-plaintext highlighter-rouge">01100101</code>, it starts with a 0, so it’s an individual code point, which translates to code point <strong>U+0065</strong> or decimal <strong>101</strong> which is the letter <strong>‘e’.</strong></p>

<p>The third byte is <code class="language-plaintext highlighter-rouge">01101100</code>, it starts with a 0, so it’s an individual code point, which translates to code point U+<strong>006C</strong> or decimal <strong>108</strong> which is the letter <strong>‘l’.</strong></p>

<p>The fourth byte is <code class="language-plaintext highlighter-rouge">01101100</code>, it starts with a 0, so it’s an individual code point, which translates to code point U+<strong>006C</strong> or decimal <strong>108</strong> which is the letter <strong>‘l’.</strong></p>

<p>The fifth byte is <code class="language-plaintext highlighter-rouge">01101111</code>, it starts with a 0, so it’s an individual code point, which translates to code point U+<strong>006F</strong> or decimal <strong>111</strong> which is the letter <strong>‘o’.</strong></p>

<p>The sixth byte is <code class="language-plaintext highlighter-rouge">11100100</code> and this is where this gets interesting, it starts with <strong>three</strong> 1s, so it tells us that this is part of a group of 3 bytes that need to be processed together, so we pick the next two bytes which form the group of 3 bytes that need to be processed together. Picking those 3 bytes we have :</p>

<p><code class="language-plaintext highlighter-rouge">11100100 10111000 10001101</code></p>

<p>We have our group of bytes that we need to extract our data from. Let’s remove the metadata that we used when we encoded our text, following our rule to extract data from each byte from the very first 0. Using our container analogy, this is what it’ll look like:</p>

<p><strong>3 Byte Container</strong></p>

<table>
  <thead>
    <tr>
      <th>Container 1</th>
      <th>Container 2</th>
      <th>Container 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>xxxx0100</td>
      <td>xx111000</td>
      <td>xx001101</td>
    </tr>
  </tbody>
</table>

<p>If we take the actual data bytes as shown above, we have this:</p>

<p><code class="language-plaintext highlighter-rouge">01001110 00001101</code></p>

<p>which if you take a look back seems similar to the binary representation of something, but let’s not spoil it, let’s follow due process. If we convert this binary, it translates to the hex value of <strong>4E0D</strong>, code point (<strong>U+4E0D</strong>) and a decimal value of <strong>19981</strong>. Now, using our online tool, we see that it translates to ‘不’.</p>

<p>VOILA !!!!!!!</p>

<p>We have successfully parsed our stream of bytes into text using Unicode and we can clearly see that we get our desired result as opposed to our previous approach of parsing individual bytes.</p>

<p>Hope this makes a little sense.</p>

<p>For some history into UTF-8 and other encodings, check <a href="https://betterexplained.com/articles/unicode/">here</a>:</p>]]></content><author><name></name></author><summary type="html"><![CDATA[If you save a text file with non-english characters and wondered how the editor knows how to interpret it correctly, then this is for you.]]></summary></entry><entry><title type="html">Essential Effects 08: Concurrent Coordination</title><link href="/2021/04/13/essential-effects-08-concurrent-coordination.html" rel="alternate" type="text/html" title="Essential Effects 08: Concurrent Coordination" /><published>2021-04-13T11:37:00+00:00</published><updated>2021-04-13T11:37:00+00:00</updated><id>/2021/04/13/essential-effects-08-concurrent-coordination</id><content type="html" xml:base="/2021/04/13/essential-effects-08-concurrent-coordination.html"><![CDATA[<p>It’s bad to use vars to define state that’s going to be shared by multiple threads, the same<br />
goes for using vars for using vars for sharing state amongst multiple effects.</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">object</span> <span class="nc">Refs</span> <span class="k">extends</span> <span class="nc">IOApp</span> <span class="o">{</span>

  <span class="k">var</span> <span class="n">counter</span> <span class="k">=</span> <span class="mi">0</span>
  <span class="k">def</span> <span class="nf">tickingClocks</span><span class="o">(</span><span class="n">name</span> <span class="k">:</span> <span class="kt">String</span><span class="o">)</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
    <span class="k">for</span> <span class="o">{</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"[$name] : ${System.currentTimeMillis()}"</span><span class="o">))</span>
      <span class="k">_</span> <span class="k">=</span>  <span class="n">counter</span> <span class="k">=</span> <span class="n">counter</span> <span class="o">+</span> <span class="mi">1</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="mi">1</span> <span class="n">second</span><span class="o">)</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nf">tickingClocks</span><span class="o">(</span><span class="n">name</span><span class="o">)</span>
    <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
  <span class="o">}</span>

  <span class="k">def</span> <span class="nf">printCounter</span><span class="o">()</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span>
    <span class="k">for</span> <span class="o">{</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"counter is $counter"</span><span class="o">))</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="mi">1</span> <span class="n">second</span><span class="o">)</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nf">printCounter</span><span class="o">()</span>
    <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>

  <span class="k">val</span> <span class="nv">program</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">ExitCode</span><span class="o">]</span> <span class="k">=</span> <span class="o">(</span><span class="nf">tickingClocks</span><span class="o">(</span><span class="s">"first clock"</span><span class="o">),</span> <span class="nf">tickingClocks</span><span class="o">(</span><span class="s">"second clock"</span><span class="o">),</span> <span class="nf">printCounter</span><span class="o">()).</span><span class="py">parTupled</span><span class="o">.</span><span class="py">as</span><span class="o">(</span><span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span><span class="o">)</span>

  <span class="k">override</span> <span class="k">def</span> <span class="nf">run</span><span class="o">(</span><span class="n">args</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">ExitCode</span><span class="o">]</span> <span class="k">=</span> <span class="n">program</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Running the above code will result in lost updates as the counter will never be accurate.</p>

<p>Although there are Atomic classes to solve these problems, they are not functional structures. Cats effect provides a functional wrapper around Atomic Classes called <code class="language-plaintext highlighter-rouge">Ref</code> .It has API’s similar to Atomic Classes.</p>

<p>We can modify our example to use a <code class="language-plaintext highlighter-rouge">Ref</code> and guarantee that state is safely shared amongst effects and ultimately threads.</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">def</span> <span class="nf">tickingClocks</span><span class="o">(</span><span class="n">name</span> <span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="n">counter</span> <span class="k">:</span> <span class="kt">Ref</span><span class="o">[</span><span class="kt">IO</span>,<span class="kt">Long</span><span class="o">])</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
      <span class="k">for</span> <span class="o">{</span>
        <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"[$name] : ${System.currentTimeMillis()}"</span><span class="o">))</span>
        <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">counter</span><span class="o">.</span><span class="py">update</span><span class="o">(</span><span class="k">_</span> <span class="o">+</span> <span class="mi">1</span><span class="o">)</span>
        <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="mi">1</span> <span class="n">second</span><span class="o">)</span>
        <span class="k">_</span> <span class="k">&lt;-</span> <span class="nf">tickingClocks</span><span class="o">(</span><span class="n">name</span><span class="o">,</span><span class="n">counter</span><span class="o">)</span>
      <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
    <span class="o">}</span>

    <span class="k">def</span> <span class="nf">printCounter</span><span class="o">(</span><span class="n">counter</span> <span class="k">:</span> <span class="kt">Ref</span><span class="o">[</span><span class="kt">IO</span>,<span class="kt">Long</span><span class="o">])</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span>
      <span class="k">for</span> <span class="o">{</span>
        <span class="n">counterValue</span> <span class="k">&lt;-</span> <span class="nv">counter</span><span class="o">.</span><span class="py">get</span>
        <span class="k">_</span>            <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"counter is $counterValue"</span><span class="o">))</span>
        <span class="k">_</span>            <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="mi">1</span> <span class="n">second</span><span class="o">)</span>
        <span class="k">_</span>            <span class="k">&lt;-</span> <span class="nf">printCounter</span><span class="o">(</span><span class="n">counter</span><span class="o">)</span>
      <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>

  <span class="k">override</span> <span class="k">def</span> <span class="nf">run</span><span class="o">(</span><span class="n">args</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">ExitCode</span><span class="o">]</span> <span class="k">=</span>
    <span class="k">for</span> <span class="o">{</span>
      <span class="n">ref</span> <span class="k">&lt;-</span> <span class="nc">Ref</span><span class="o">[</span><span class="kt">IO</span><span class="o">].</span><span class="py">of</span><span class="o">(</span><span class="mi">0L</span><span class="o">)</span>
      <span class="k">_</span>   <span class="k">&lt;-</span> <span class="o">(</span><span class="nf">tickingClocks</span><span class="o">(</span><span class="s">"first clock"</span><span class="o">,</span><span class="n">ref</span><span class="o">),</span> <span class="nf">tickingClocks</span><span class="o">(</span><span class="s">"second clock"</span><span class="o">,</span><span class="n">ref</span><span class="o">),</span> <span class="nf">printCounter</span><span class="o">(</span><span class="n">ref</span><span class="o">)).</span><span class="py">parTupled</span><span class="o">.</span><span class="py">as</span><span class="o">(</span><span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span><span class="o">)</span>
    <span class="o">}</span> <span class="k">yield</span> <span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span>
</code></pre></div></div>

<h4 id="deferred">Deferred</h4>

<p>Now, let’s imagine we want to alert the user when the counter hits 13. One way to do this is to check for the value each time we update the counter. A better way to do this is by the use of the <code class="language-plaintext highlighter-rouge">Deferred</code> data type.</p>

<p><code class="language-plaintext highlighter-rouge">Deffered</code> is a functional concurrency construct that sleeps or halts execution of subsequent effect until the task or value that was deferred completes. We can think of it as a Promise in Scala, that is completed elsewhere, could be another effect or effectively, another thread.</p>

<blockquote>
  <p>Deferred gives us the ability to serialize the execution of an effect with respect to some newly-produced state</p>
</blockquote>

<p>By using <code class="language-plaintext highlighter-rouge">Deferred</code>, we can separate the task to run upon completion from the task that completes the <code class="language-plaintext highlighter-rouge">Deferred</code>.</p>

<p>In our previous example, we’ll use the <code class="language-plaintext highlighter-rouge">Deferred</code> data type to alert us when the counter reaches 13, that will be separate from other tasks.</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="k">def</span> <span class="nf">tickingClocks</span><span class="o">(</span><span class="n">name</span> <span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="n">counter</span> <span class="k">:</span> <span class="kt">Ref</span><span class="o">[</span><span class="kt">IO</span>,<span class="kt">Long</span><span class="o">],</span> <span class="n">alerter</span> <span class="k">:</span> <span class="kt">Deferred</span><span class="o">[</span><span class="kt">IO</span>,<span class="kt">Unit</span><span class="o">])</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
      <span class="k">for</span> <span class="o">{</span>
        <span class="k">_</span>            <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="mi">1</span> <span class="n">second</span><span class="o">)</span>
        <span class="k">_</span>            <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"[$name] : ${System.currentTimeMillis()}"</span><span class="o">))</span>
        <span class="n">counterValue</span> <span class="k">&lt;-</span> <span class="nv">counter</span><span class="o">.</span><span class="py">updateAndGet</span><span class="o">(</span><span class="k">_</span> <span class="o">+</span> <span class="mi">1</span><span class="o">)</span>
        <span class="k">_</span>            <span class="k">&lt;-</span> <span class="nf">if</span> <span class="o">(</span><span class="n">counterValue</span> <span class="o">&gt;=</span> <span class="mi">13</span><span class="o">)</span> <span class="nv">alerter</span><span class="o">.</span><span class="py">complete</span><span class="o">(()).</span><span class="py">attempt</span><span class="o">.</span><span class="py">void</span> <span class="k">else</span> <span class="nv">IO</span><span class="o">.</span><span class="py">unit</span>
        <span class="k">_</span>            <span class="k">&lt;-</span> <span class="nf">tickingClocks</span><span class="o">(</span><span class="n">name</span><span class="o">,</span><span class="n">counter</span><span class="o">,</span><span class="n">alerter</span><span class="o">)</span>
      <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
    <span class="o">}</span>

  <span class="k">def</span> <span class="nf">alertIf13</span><span class="o">(</span><span class="n">is13</span> <span class="k">:</span> <span class="kt">Deferred</span><span class="o">[</span><span class="kt">IO</span>,<span class="kt">Unit</span><span class="o">])</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
    <span class="k">for</span> <span class="o">{</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">is13</span><span class="o">.</span><span class="py">get</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="s">"ALERT!!!!!!!"</span><span class="o">))</span>
    <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
  <span class="o">}</span>

    <span class="k">def</span> <span class="nf">printCounter</span><span class="o">(</span><span class="n">counter</span> <span class="k">:</span> <span class="kt">Ref</span><span class="o">[</span><span class="kt">IO</span>,<span class="kt">Long</span><span class="o">])</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span>
      <span class="k">for</span> <span class="o">{</span>
        <span class="n">counterValue</span> <span class="k">&lt;-</span> <span class="nv">counter</span><span class="o">.</span><span class="py">get</span>
        <span class="k">_</span>            <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"counter is $counterValue"</span><span class="o">))</span>
        <span class="k">_</span>            <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="mi">1</span> <span class="n">second</span><span class="o">)</span>
        <span class="k">_</span>            <span class="k">&lt;-</span> <span class="nf">printCounter</span><span class="o">(</span><span class="n">counter</span><span class="o">)</span>
      <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>

  <span class="k">override</span> <span class="k">def</span> <span class="nf">run</span><span class="o">(</span><span class="n">args</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">ExitCode</span><span class="o">]</span> <span class="k">=</span>
    <span class="k">for</span> <span class="o">{</span>
      <span class="n">ref</span>     <span class="k">&lt;-</span> <span class="nc">Ref</span><span class="o">[</span><span class="kt">IO</span><span class="o">].</span><span class="py">of</span><span class="o">(</span><span class="mi">0L</span><span class="o">)</span>
      <span class="n">alerter</span> <span class="k">&lt;-</span> <span class="nc">Deferred</span><span class="o">[</span><span class="kt">IO</span>,<span class="kt">Unit</span><span class="o">]</span>
          <span class="k">_</span>   <span class="k">&lt;-</span> <span class="o">(</span>
            <span class="nf">tickingClocks</span><span class="o">(</span><span class="s">"first clock"</span><span class="o">,</span><span class="n">ref</span><span class="o">,</span> <span class="n">alerter</span><span class="o">),</span> 
            <span class="nf">tickingClocks</span><span class="o">(</span><span class="s">"second clock"</span><span class="o">,</span><span class="n">ref</span><span class="o">,</span> <span class="n">alerter</span><span class="o">),</span>
            <span class="nf">alertIf13</span><span class="o">(</span><span class="n">alerter</span><span class="o">),</span> 
            <span class="nf">printCounter</span><span class="o">(</span><span class="n">ref</span><span class="o">)</span>
            <span class="o">).</span><span class="py">parTupled</span>
    <span class="o">}</span> <span class="k">yield</span> <span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span>
</code></pre></div></div>

<p>In this example, we complete the <code class="language-plaintext highlighter-rouge">Deferred</code> with <code class="language-plaintext highlighter-rouge">Unit</code> in the <code class="language-plaintext highlighter-rouge">tickingClocks</code> while we use it in the <code class="language-plaintext highlighter-rouge">alertIf13</code> function.</p>

<blockquote>
  <p>We used an IO#attempt on the call to complete the Deferred because our <code class="language-plaintext highlighter-rouge">tickingClocks</code> function is recursive and will attempt to call complete on an already completed <code class="language-plaintext highlighter-rouge">Deferred</code> <a href="https://github.com/typelevel/cats-effect/blob/1846813109b1e78c5bf36e6e179d7a91419e01d0/core/shared/src/main/scala/cats/effect/concurrent/Deferred.scala#L68">which will lead to an IllegalStateException</a></p>
</blockquote>

<h4 id="concurrent-state-machines">Concurrent State Machines</h4>

<p>An example used by the book was to design a functional <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/CountDownLatch.html">Countdown latch</a> using these functional concurrency structures.</p>

<p>To adapt to the parallel ticking clock example, here’s how the latch could work:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">run</span><span class="o">(</span><span class="n">args</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">ExitCode</span><span class="o">]</span> <span class="k">=</span>
    <span class="k">for</span> <span class="o">{</span>
      <span class="n">latch</span> <span class="k">&lt;-</span> <span class="nc">CountdownLatch</span><span class="o">(</span><span class="mi">13</span><span class="o">)</span>
      <span class="k">_</span>     <span class="k">&lt;-</span> <span class="o">(</span>
            <span class="nf">tickingClocks</span><span class="o">(</span><span class="s">"first clock"</span><span class="o">,</span> <span class="n">latch</span><span class="o">),</span>
            <span class="nf">tickingClocks</span><span class="o">(</span><span class="s">"second clock"</span><span class="o">,</span> <span class="n">latch</span><span class="o">),</span>
            <span class="nf">alertIf13</span><span class="o">(</span><span class="n">latch</span><span class="o">),</span>
            <span class="o">).</span><span class="py">parTupled</span>
    <span class="o">}</span> <span class="k">yield</span> <span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span>
</code></pre></div></div>

<p>Now, this was my initial implementation which didn’t work because for some reason, calling complete on the <code class="language-plaintext highlighter-rouge">Deferred</code> didn’t work:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">object</span> <span class="nc">CountdownLatch</span> <span class="o">{</span>
    <span class="k">def</span> <span class="nf">apply</span><span class="o">(</span><span class="n">n</span> <span class="k">:</span> <span class="kt">Int</span><span class="o">)</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">CountdownLatch</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
      <span class="nf">require</span><span class="o">(</span><span class="n">n</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">,</span> <span class="s">"number of latches should be greater than 0"</span><span class="o">)</span>
      <span class="k">for</span> <span class="o">{</span>
        <span class="n">latchSignal</span> <span class="k">&lt;-</span> <span class="nc">Deferred</span><span class="o">[</span><span class="kt">IO</span>,<span class="kt">Unit</span><span class="o">]</span>
        <span class="n">latchState</span>   <span class="k">&lt;-</span> <span class="nc">Ref</span><span class="o">[</span><span class="kt">IO</span><span class="o">].</span><span class="py">of</span><span class="o">[</span><span class="kt">LatchState</span><span class="o">](</span><span class="nc">CountingDown</span><span class="o">(</span><span class="n">n</span><span class="o">))</span>
      <span class="o">}</span> <span class="k">yield</span> <span class="k">new</span> <span class="nc">CountdownLatch</span> <span class="o">{</span>
        <span class="k">override</span> <span class="k">def</span> <span class="nf">await</span><span class="o">()</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span>
          <span class="nv">latchSignal</span><span class="o">.</span><span class="py">get</span>

        <span class="k">override</span> <span class="k">def</span> <span class="nf">decrement</span><span class="o">()</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
          <span class="nv">latchState</span><span class="o">.</span><span class="py">update</span> <span class="o">{</span>
            <span class="k">case</span> <span class="nc">CountingDown</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span> <span class="k">=&gt;</span>
              <span class="c1">// last latch</span>
              <span class="nv">latchSignal</span><span class="o">.</span><span class="py">complete</span><span class="o">(())</span>
              <span class="nc">Done</span>

            <span class="k">case</span> <span class="n">res</span> <span class="nd">@CountingDown</span><span class="o">(</span><span class="n">count</span><span class="o">)</span> <span class="k">=&gt;</span>
              <span class="nv">res</span><span class="o">.</span><span class="py">copy</span><span class="o">(</span><span class="n">count</span> <span class="o">-</span> <span class="mi">1</span><span class="o">)</span>

            <span class="k">case</span> <span class="nc">Done</span> <span class="k">=&gt;</span>
              <span class="nc">Done</span>
          <span class="o">}</span>
        <span class="o">}</span>
      <span class="o">}</span>
    <span class="o">}</span>
  <span class="o">}</span>
</code></pre></div></div>
<p>After a long time spent debugging the decrement function, I saw what the problem was, it was this line:</p>

<p>case CountingDown(1) =&gt;
    // last latch
    latchSignal.complete(())
    Done</p>

<p>I had totally forgotten that we were dealing with IO values, so to fulfil the <code class="language-plaintext highlighter-rouge">update</code> method function signature <code class="language-plaintext highlighter-rouge">A =&gt; A</code>, I added a <code class="language-plaintext highlighter-rouge">Done</code> after the <code class="language-plaintext highlighter-rouge">latchSignal.complete(())</code>. But that method isn’t going to be run because it’s an IO value.</p>

<p>The IO runtime won’t run it because it wasn’t returned, the IO computation as expected was just a description of computation and not the execution of the actual computation.</p>

<p>Now, after figuring this out, here was my next implementation for the decrement function:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">override</span> <span class="k">def</span> <span class="nf">decrement</span><span class="o">()</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
  <span class="nv">latchState</span><span class="o">.</span><span class="py">updateAndGet</span> <span class="o">{</span>
    <span class="k">case</span> <span class="nc">CountingDown</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span> <span class="o">|</span> <span class="nc">Done</span> <span class="k">=&gt;</span>
      <span class="c1">// last latch</span>
      <span class="nc">Done</span>

    <span class="k">case</span> <span class="n">res</span> <span class="nd">@CountingDown</span><span class="o">(</span><span class="n">count</span><span class="o">)</span> <span class="k">=&gt;</span>
      <span class="nv">res</span><span class="o">.</span><span class="py">copy</span><span class="o">(</span><span class="n">count</span> <span class="o">-</span> <span class="mi">1</span><span class="o">)</span>
  <span class="o">}.</span><span class="py">flatMap</span> <span class="o">{</span>
    <span class="k">case</span> <span class="nc">Done</span> <span class="k">=&gt;</span>
      <span class="c1">// used attempt because of multiple calls to attempt</span>
      <span class="nv">latchSignal</span><span class="o">.</span><span class="py">complete</span><span class="o">(()).</span><span class="py">attempt</span><span class="o">.</span><span class="py">void</span>
    <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span> <span class="nv">IO</span><span class="o">.</span><span class="py">unit</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>This worked, but i realized that since the ticking clock was continuous, the <code class="language-plaintext highlighter-rouge">complete</code> method of the latch was being called multiple times, throwing an error.</p>

<p>Then I remembered there was the <code class="language-plaintext highlighter-rouge">modify</code> method on the <code class="language-plaintext highlighter-rouge">Ref</code> that enabled returning some other state <code class="language-plaintext highlighter-rouge">B</code> and using that method seemed to totally solve the problem as seen below:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">object</span> <span class="nc">CountdownLatch</span> <span class="o">{</span>
    <span class="k">def</span> <span class="nf">apply</span><span class="o">(</span><span class="n">n</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">CountdownLatch</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
      <span class="nf">require</span><span class="o">(</span><span class="n">n</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="o">,</span> <span class="s">"number of latches should be greater than 0"</span><span class="o">)</span>
      <span class="k">for</span> <span class="o">{</span>
        <span class="n">latchSignal</span> <span class="k">&lt;-</span> <span class="nc">Deferred</span><span class="o">[</span><span class="kt">IO</span>, <span class="kt">Unit</span><span class="o">]</span>
        <span class="n">latchState</span> <span class="k">&lt;-</span> <span class="nc">Ref</span><span class="o">[</span><span class="kt">IO</span><span class="o">].</span><span class="py">of</span><span class="o">[</span><span class="kt">LatchState</span><span class="o">](</span><span class="nc">CountingDown</span><span class="o">(</span><span class="n">n</span><span class="o">))</span>
      <span class="o">}</span> <span class="k">yield</span> <span class="k">new</span> <span class="nc">CountdownLatch</span> <span class="o">{</span>
        <span class="k">override</span> <span class="k">def</span> <span class="nf">await</span><span class="o">()</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span>
          <span class="nv">latchSignal</span><span class="o">.</span><span class="py">get</span>

        <span class="k">override</span> <span class="k">def</span> <span class="nf">decrement</span><span class="o">()</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
          <span class="nv">latchState</span><span class="o">.</span><span class="py">modify</span> <span class="o">{</span>
            <span class="k">case</span> <span class="nc">CountingDown</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span> <span class="k">=&gt;</span>
                <span class="c1">// last latch</span>
                <span class="nc">Done</span> <span class="o">-&gt;</span> <span class="nv">latchSignal</span><span class="o">.</span><span class="py">complete</span><span class="o">(())</span>

            <span class="k">case</span> <span class="n">res</span><span class="nd">@CountingDown</span><span class="o">(</span><span class="n">count</span><span class="o">)</span> <span class="k">=&gt;</span>
              <span class="nv">res</span><span class="o">.</span><span class="py">copy</span><span class="o">(</span><span class="n">count</span> <span class="o">-</span> <span class="mi">1</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="nv">IO</span><span class="o">.</span><span class="py">unit</span>

            <span class="k">case</span> <span class="nc">Done</span> <span class="k">=&gt;</span>
              <span class="nc">Done</span> <span class="o">-&gt;</span> <span class="nv">IO</span><span class="o">.</span><span class="py">unit</span>

          <span class="o">}.</span><span class="py">flatten</span>
        <span class="o">}</span>
      <span class="o">}</span>
    <span class="o">}</span>
  <span class="o">}</span>
</code></pre></div></div>

<p>which coincidentally was similar to the answer in the book :)</p>]]></content><author><name></name></author><category term="cats" /><category term="fp" /><category term="functional-programming" /><category term="scala" /><category term="essential-effects" /><summary type="html"><![CDATA[It’s bad to use vars to define state that’s going to be shared by multiple threads, the same goes for using vars for using vars for sharing state amongst multiple effects. ```scala object Refs extends IOApp {]]></summary></entry><entry><title type="html">Essential Effects 07: Managing Resources</title><link href="/2021/04/12/essential-effects-07-managing-resources.html" rel="alternate" type="text/html" title="Essential Effects 07: Managing Resources" /><published>2021-04-12T11:37:00+00:00</published><updated>2021-04-12T11:37:00+00:00</updated><id>/2021/04/12/essential-effects-07-managing-resources</id><content type="html" xml:base="/2021/04/12/essential-effects-07-managing-resources.html"><![CDATA[<h3 id="managing-resources">Managing Resources</h3>

<p>In Cats Effect, the Resource data type represents this acquire-use-release pattern to<br />
manage state. In other words, a Resource represents acquisition of an entity with its release function already implemented, which will be called once that resource has been used.</p>

<p>To acquire and use a resource, we call <code class="language-plaintext highlighter-rouge">Resource.make</code> which has this type signature:</p>

<p><code class="language-plaintext highlighter-rouge">def make[F[_], A](acquire: F[A])(release: A =&gt; F[Unit])(implicit F: Functor[F]): Resource[F, A]</code></p>

<p>We see it takes the entity to acquire wrapped in a type constructor and the release function. The result of this is a Resource, that we can then call use on. Once it’s done being used, the release function kicks in</p>

<p>Let’s take a simple and contrived example where we acquire and eventually release simple file api</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">object</span> <span class="nc">ResourcesExample</span> <span class="k">extends</span> <span class="nc">IOApp</span> <span class="o">{</span>

  <span class="k">trait</span> <span class="nc">FileApi</span> <span class="o">{</span>
    <span class="k">def</span> <span class="nf">getContents</span> <span class="k">:</span> <span class="kt">Array</span><span class="o">[</span><span class="kt">Byte</span><span class="o">]</span>
    <span class="k">def</span> <span class="nf">close</span> <span class="k">:</span> <span class="kt">Unit</span>
  <span class="o">}</span>

  <span class="k">def</span> <span class="nf">getFileApi</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">FileApi</span> <span class="o">{</span>
    <span class="k">override</span> <span class="k">def</span> <span class="nf">getContents</span><span class="k">:</span> <span class="kt">Array</span><span class="o">[</span><span class="kt">Byte</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
      <span class="s">"hello there"</span><span class="o">.</span><span class="py">getBytes</span>
    <span class="o">}</span>

    <span class="k">override</span> <span class="k">def</span> <span class="nf">close</span><span class="k">:</span> <span class="kt">Unit</span> <span class="o">=</span>  <span class="o">{</span>
      <span class="nf">println</span><span class="o">(</span><span class="s">"closing this file"</span><span class="o">)</span>
    <span class="o">}</span>
  <span class="o">}</span>

  <span class="k">val</span> <span class="nv">fileResource</span><span class="k">:</span> <span class="kt">Resource</span><span class="o">[</span><span class="kt">IO</span>, <span class="kt">FileApi</span><span class="o">]</span> <span class="k">=</span> <span class="nv">Resource</span><span class="o">.</span><span class="py">make</span><span class="o">(</span><span class="nc">IO</span><span class="o">(</span><span class="n">getFileApi</span><span class="o">))(</span><span class="n">api</span> <span class="k">=&gt;</span> <span class="nv">IO</span><span class="o">.</span><span class="py">pure</span><span class="o">(</span><span class="nv">api</span><span class="o">.</span><span class="py">close</span><span class="o">))</span>

  <span class="k">override</span> <span class="k">def</span> <span class="nf">run</span><span class="o">(</span><span class="n">args</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">ExitCode</span><span class="o">]</span> <span class="k">=</span>
    <span class="k">for</span> <span class="o">{</span>
    <span class="k">_</span>               <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="s">"Let's check out file for your welcome message"</span><span class="o">))</span>
    <span class="n">welcomeMessage</span>  <span class="k">&lt;-</span> <span class="nv">fileResource</span><span class="o">.</span><span class="py">use</span> <span class="o">{</span> <span class="n">fileApi</span> <span class="k">=&gt;</span>
                        <span class="nc">IO</span><span class="o">(</span><span class="nv">fileApi</span><span class="o">.</span><span class="py">getContents</span><span class="o">)</span>
                      <span class="o">}</span>
    <span class="k">_</span>               <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"Your welcome message is [${new String(welcomeMessage)}]"</span><span class="o">))</span>
  <span class="o">}</span> <span class="k">yield</span> <span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span>
<span class="o">}</span>
</code></pre></div></div>

<p>The result of this program prints:</p>

<p>Let’s check out file for your welcome message
closing this file
Your welcome message is [hello there]</p>

<p>We easily see that our mock file api is closed immediately after use, even before the next line in in the for comprehension.</p>

<p>It’s important to know that the release function of a resource is called even if it throws an exception while being used</p>

<p>We could change our fil api exampe to throw an error:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">for</span> <span class="o">{</span>
    <span class="k">_</span>               <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="s">"Let's check out file for your welcome message"</span><span class="o">))</span>
    <span class="n">welcomeMessage</span>  <span class="k">&lt;-</span> <span class="nv">fileResource</span><span class="o">.</span><span class="py">use</span> <span class="o">{</span> <span class="n">fileApi</span> <span class="k">=&gt;</span>
      <span class="nv">IO</span><span class="o">.</span><span class="py">raiseError</span><span class="o">[</span><span class="kt">String</span><span class="o">](</span><span class="k">new</span> <span class="nc">Exception</span><span class="o">(</span><span class="s">"are we gonna be released ????"</span><span class="o">))</span>
    <span class="o">}</span>
    <span class="k">_</span>               <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"Your welcome message is [${new String(welcomeMessage)}]"</span><span class="o">))</span>
  <span class="o">}</span> <span class="k">yield</span> <span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span>
</code></pre></div></div>
<p>We still see that the resource is closed despite the exception being thrown</p>

<p>Let’s check out file for your welcome message
closing this file
java.lang.Exception: are we gonna be released ????</p>

<h5 id="resource-composition">Resource Composition</h5>

<p>Resources also compose. since they are functional constructs, we can map or flatMap over them. Which means we can construct a new resource from a previous resource.</p>

<p>We can also use a resource within another resource:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="k">val</span> <span class="nv">intResource</span><span class="k">:</span> <span class="kt">Resource</span><span class="o">[</span><span class="kt">IO</span>, <span class="kt">Int</span><span class="o">]</span> <span class="k">=</span> <span class="nv">Resource</span><span class="o">.</span><span class="py">make</span><span class="o">(</span><span class="nc">IO</span><span class="o">(</span><span class="mi">42</span><span class="o">))(</span><span class="n">x</span> <span class="k">=&gt;</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"releasing $x "</span><span class="o">))</span> <span class="o">*&gt;</span> <span class="nv">IO</span><span class="o">.</span><span class="py">unit</span><span class="o">)</span>
  <span class="k">val</span> <span class="nv">stringResource</span><span class="k">:</span> <span class="kt">Resource</span><span class="o">[</span><span class="kt">IO</span>, <span class="kt">String</span><span class="o">]</span> <span class="k">=</span> <span class="nv">Resource</span><span class="o">.</span><span class="py">make</span><span class="o">(</span><span class="nc">IO</span><span class="o">(</span><span class="s">"thor"</span><span class="o">))(</span><span class="n">x</span> <span class="k">=&gt;</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"releasing $x "</span><span class="o">))</span> <span class="o">*&gt;</span>  <span class="nv">IO</span><span class="o">.</span><span class="py">unit</span><span class="o">)</span>

  <span class="k">val</span> <span class="nv">result</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span><span class="k">=</span> <span class="k">for</span> <span class="o">{</span>
    <span class="n">result</span> <span class="k">&lt;-</span> <span class="nv">intResource</span><span class="o">.</span><span class="py">use</span> <span class="o">{</span> <span class="n">age</span> <span class="k">=&gt;</span>
      <span class="nv">stringResource</span><span class="o">.</span><span class="py">use</span> <span class="o">{</span><span class="n">name</span> <span class="k">=&gt;</span>
        <span class="nc">IO</span><span class="o">(</span><span class="n">s</span><span class="s">"name is $name, and age is $age"</span><span class="o">)</span>
      <span class="o">}</span>
    <span class="o">}</span>
    <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"result is $result"</span><span class="o">))</span>
  <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
</code></pre></div></div>]]></content><author><name></name></author><category term="cats" /><category term="fp" /><category term="functional-programming" /><category term="scala" /><category term="essential-effects" /><summary type="html"><![CDATA[Managing Resources]]></summary></entry><entry><title type="html">Essential Effects 06: Integrating with Legacy systems</title><link href="/2021/04/11/essential-effects-06-integrating-with-legacy-systems.html" rel="alternate" type="text/html" title="Essential Effects 06: Integrating with Legacy systems" /><published>2021-04-11T11:37:00+00:00</published><updated>2021-04-11T11:37:00+00:00</updated><id>/2021/04/11/essential-effects-06-integrating-with-legacy-systems</id><content type="html" xml:base="/2021/04/11/essential-effects-06-integrating-with-legacy-systems.html"><![CDATA[<h3 id="integrating-asynchrony">Integrating Asynchrony</h3>

<p>We’ve dealt a lot with IO values, but in practice, we may have to deal with legacy<br />
codebases that use futures or other async structures. But since we are writing pure functional programs, we need a way to be able to capture or lift the result of these asynchronous computations into an IO.</p>

<p>Cats effect provides that capability via the <code class="language-plaintext highlighter-rouge">IO.async</code> method. The way this works is that the method takes a function from a callback to Unit, where the callback itself is a function from an Either[Throwable,A] to Unit.</p>

<p>The function signature looks like this</p>

<p><code class="language-plaintext highlighter-rouge">def async[A](k : (Either[Throwable,A] =&gt; Unit ) =&gt; Unit)</code></p>

<p>The function signature may seem a little daunting, but the basic idea is that you call the method and complete the callback at the end of the computation with either a <code class="language-plaintext highlighter-rouge">Left</code> or a <code class="language-plaintext highlighter-rouge">Right</code></p>

<p>Now, for a contrived example, let’s imagine we have an asynchronous method that returns an Int, and we want to lift that into an IO, we could do it like this:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">object</span> <span class="nc">IOAsyncExample</span> <span class="k">extends</span> <span class="nc">IOApp</span> <span class="o">{</span>
  <span class="k">val</span> <span class="nv">ec</span> <span class="k">=</span> <span class="nv">Executors</span><span class="o">.</span><span class="py">newCachedThreadPool</span><span class="o">()</span>

  <span class="k">def</span> <span class="nf">getMagicNumber</span><span class="o">()</span> <span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="o">{</span>
    <span class="nv">Thread</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="mi">500</span><span class="o">)</span>
    <span class="mi">43</span>
  <span class="o">}</span>

  <span class="k">def</span> <span class="nf">asynComputation</span> <span class="k">=</span>  <span class="nv">ec</span><span class="o">.</span><span class="py">submit</span><span class="o">{</span>
    <span class="k">new</span> <span class="nc">Callable</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span> <span class="o">{</span>
      <span class="k">override</span> <span class="k">def</span> <span class="nf">call</span><span class="o">()</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="nf">getMagicNumber</span><span class="o">()</span>
    <span class="o">}</span>
  <span class="o">}</span>

  <span class="k">val</span> <span class="nv">magicIO</span> <span class="k">=</span>  <span class="nv">IO</span><span class="o">.</span><span class="py">async</span><span class="o">[</span><span class="kt">Int</span><span class="o">]{</span> <span class="n">cb</span> <span class="k">=&gt;</span>
    <span class="k">try</span> <span class="n">cb</span> <span class="o">{</span>
      <span class="k">val</span> <span class="nv">result</span> <span class="k">=</span> <span class="nc">Right</span><span class="o">(</span>
        <span class="nv">asynComputation</span><span class="o">.</span><span class="py">get</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="nv">TimeUnit</span><span class="o">.</span><span class="py">SECONDS</span><span class="o">)</span>
      <span class="o">)</span>
      <span class="nv">ec</span><span class="o">.</span><span class="py">shutdown</span><span class="o">()</span>
      <span class="n">result</span>
    <span class="o">}</span>
    <span class="k">catch</span> <span class="o">{</span>
      <span class="k">case</span> <span class="nc">NonFatal</span><span class="o">(</span><span class="n">e</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="nf">cb</span><span class="o">(</span><span class="nc">Left</span><span class="o">(</span><span class="n">e</span><span class="o">))</span>
    <span class="o">}</span>
  <span class="o">}</span>

  <span class="k">override</span> <span class="k">def</span> <span class="nf">run</span><span class="o">(</span><span class="n">args</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">ExitCode</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
    <span class="k">for</span> <span class="o">{</span>
      <span class="k">_</span>           <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="s">"Let's calculate the magic number"</span><span class="o">))</span>
      <span class="n">magicNumber</span> <span class="k">&lt;-</span> <span class="n">magicIO</span>
      <span class="k">_</span>           <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"magic number is $magicNumber"</span><span class="o">))</span>
    <span class="o">}</span> <span class="k">yield</span> <span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>With this, we’ve been able to encapsulate or lift our async computation into an IO. This is more or less the basis for the utility method to lift a future into an IO: <code class="language-plaintext highlighter-rouge">IO.fromFuture</code></p>

<blockquote>
  <p>IO.async provides a callback cb so the API (however asynchronous) can signal the result of the computation. When the API computes the result it provides it to the callback</p>
</blockquote>]]></content><author><name></name></author><category term="cats" /><category term="fp" /><category term="functional-programming" /><category term="scala" /><category term="essential-effects" /><summary type="html"><![CDATA[Integrating Asynchrony]]></summary></entry><entry><title type="html">Essential Effects 05: Contexts and Thread Pools</title><link href="/2021/04/10/essential-effects-05-contexts-and-thread-pools.html" rel="alternate" type="text/html" title="Essential Effects 05: Contexts and Thread Pools" /><published>2021-04-10T11:37:00+00:00</published><updated>2021-04-10T11:37:00+00:00</updated><id>/2021/04/10/essential-effects-05-contexts-and-thread-pools</id><content type="html" xml:base="/2021/04/10/essential-effects-05-contexts-and-thread-pools.html"><![CDATA[<h4 id="cpu-vs-io-bound-work">CPU vs IO Bound work</h4>

<h5 id="io-bound-work">IO Bound work</h5>

<p>IO operations typically involves reading or writing to files, databases, sockets e.t.c. Most of these times, waiting is involved as sometimes data isn’t yet available.<br />
In these scenarios, the CPU will have to wait until the underlying hardware has delivered the data since it is not immediately available.</p>

<p>Any IO operation that requires reading or writing using anything that is not stored in RAM<br />
will cause something called IOwait, which is basically a system call that tells the CPU to pause the execution og the current thread until data is available or data has been successfully transmitted. This way. the CPU can easily pause that thread and move on to do other things.</p>

<p>During the process of IOwait, the OS is free to pick up another thread and execute that thread.</p>

<p>If you have too few threads available for doing I/O work, the performance of your application will suffer as they can’t even get started until some other I/O operation is completed and that thread goes back to the thread pool.</p>

<h5 id="cpu-bound-work">CPU Bound Work</h5>

<p>Let’s imagine we want to do something like blur an image that is in memory. Because that image is already in memory and the CPU doesn’t have to wait for data and there won’t be calls to IOwait. Now, this means that the OS won’t allow other threads to run as this process doesn’t pause. Well, this is not technically true, the OS normally and automatically switches<br />
execution of threads even without a call to IOwait. This is to give other threads a fair chance to run.</p>

<p>But in our case of the CPU intensive work, there won’t be as many pauses or context switches compared to IO bound work because there were no explicit IOwait calls.</p>

<p>Now, what this means is that if we have a thread pool that mixes CPU and IO work, the IO work will mostly depend on the OS to automatically give it execution time as the CPU intensive work won’t willingly yield execution time compared to an all IO work where each thread willingly yields execution time until data is available for processing.</p>

<p>That’s why it’s quite important to create separate thread pools for different kinds of work.</p>

<p><a href="https://www.hellsoft.se/understanding-cpu-and-i-o-bound-for-asynchronous-operations/">inspired by this wonderful post</a></p>

<h3 id="multiple-thread-pools">Multiple Thread pools.</h3>

<p>By default, the <code class="language-plaintext highlighter-rouge">IOApp</code> provides us with a fixed pool thread executor where the<br />
number of threads is set to the number of available CPUs<br />
<code class="language-plaintext highlighter-rouge">Runtime.getRuntime.availableProcessors()</code></p>

<blockquote>
  <p>What do we do if our pool has at most n threads, but all those threads are<br />
blocked? If that happens, we can’t use any available cores to do CPU-bound work.<br />
To ensure our programs make progress—ensuring work proceeds when I/O-bound work is blocked—we’ll isolate the CPU-bound work from any I/O-bound tasks by having separate pools.</p>
</blockquote>

<p>The Cats effect Library supports this pattern by encouraging separate contexts.</p>

<ul>
  <li>CPU- bound work (using a fixed thread pool)</li>
  <li>IO bound work (using an unbounded thread pool so blocked threads merely take memory and don’t prevent other tasks from running)</li>
</ul>

<p>For IO bound tasks, cats effect provides a small wrapper around a Cached Thread pool execution context called a Blocker for execution.</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="k">val</span> <span class="nv">prog</span> <span class="k">=</span>  <span class="nv">Blocker</span><span class="o">.</span><span class="py">apply</span><span class="o">[</span><span class="kt">IO</span><span class="o">].</span><span class="py">use</span><span class="o">{</span> <span class="n">blocker</span> <span class="k">=&gt;</span>
    <span class="nf">withBlocker</span><span class="o">(</span><span class="n">blocker</span><span class="o">).</span><span class="py">as</span><span class="o">(</span><span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span><span class="o">)</span>
  <span class="o">}</span>

  <span class="k">def</span> <span class="nf">withBlocker</span><span class="o">(</span><span class="n">blocker</span> <span class="k">:</span> <span class="kt">Blocker</span><span class="o">)</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
    <span class="k">for</span> <span class="o">{</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="s">"on IOapp threadpool"</span><span class="o">).</span><span class="py">debug</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">blocker</span><span class="o">.</span><span class="py">blockOn</span><span class="o">(</span><span class="nc">IO</span><span class="o">(</span><span class="s">"on blocker"</span><span class="o">).</span><span class="py">debug</span><span class="o">)</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="s">"&lt;---- Thread I'm on"</span><span class="o">).</span><span class="py">debug</span>
    <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
  <span class="o">}</span>
</code></pre></div></div>

<p>Here’s what we see on the console</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>ioapp-compute-0] on IOapp threadpool
<span class="o">[</span>cats-effect-blocker-0] on blocker
<span class="o">[</span>ioapp-compute-1] &lt;<span class="nt">----</span> Thread I am on
</code></pre></div></div>

<p>We can clearly see that the blocking effect was executed on another thread pool<br />
<code class="language-plaintext highlighter-rouge">cats-effect-blocker-*</code> pool other than the one the previous effect ran on <code class="language-plaintext highlighter-rouge">ioapp-compute</code></p>

<h4 id="finer-grained-control-of-contexts">Finer Grained Control of Contexts</h4>

<p>What if we want to control the contexts used to run our effects and easily switch between contexts.</p>

<p>Let’s take the ticking clock example we designed a while back , It won’t make sense if this ws made to execute continuosly on one thread and hoarding that thread, thus making that thread unavailable for other effects to use and reducing the amount of work our application can perform within a time frame.</p>

<blockquote>
  <p>To ensure a recursive loop doesn’t steal a thread and never give it back, we’d like<br />
to be able to declare, as an effect itself, “reschedule the remainder of the<br />
computation”. Not only would this resume the computation on (potentially)<br />
another thread when the resumption is executed by the context, but it then allows other scheduled effects to re-use the previous thread. In other words, the current effect is “suspended” and sent “to the back of the line”, which prevents other effects from being “starved” of a thread.</p>
</blockquote>

<p>We can insert asynchronous boundaries and control to an extent the threads within a context that we want our effects to run using the IO.shift method If we run this code:</p>

<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">object</span> <span class="nc">Shifting</span> <span class="k">extends</span> <span class="nc">IOApp</span> <span class="o">{</span>
 <span class="k">def</span> <span class="nf">run</span><span class="o">(</span><span class="n">args</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">ExitCode</span><span class="o">]</span> <span class="k">=</span>
  <span class="k">for</span> <span class="o">{</span>
   <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="s">"one"</span><span class="o">).</span><span class="py">debug</span>
   <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">shift</span>
   <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="s">"two"</span><span class="o">).</span><span class="py">debug</span>
   <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">shift</span>
   <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="s">"three"</span><span class="o">).</span><span class="py">debug</span>
  <span class="o">}</span> <span class="k">yield</span> <span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span>
<span class="o">}</span>
</code></pre></div></div>

<p>We get</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>ioapp-compute-0] one
<span class="o">[</span>ioapp-compute-1] two
<span class="o">[</span>ioapp-compute-2] three
</code></pre></div></div>

<p>It’s obvious that for every shift, the next effect runs in a different thread in the same context.<br />
This is what inserting an async boundary means, where the next effect is made to run on another thread</p>

<p>The IO.sleep method does this because if blocked the current thread for the duration of the sleep, we’d be preventing that thread from being used by other effects.</p>

<blockquote>
  <p>Cats Effect inserts an async boundary at runtime every 512 flatMap calls. This is a kind of fail-safe—if you forget to add a boundary yourself, the library will ensure that a composed effect can’t re-use the same thread for very long</p>
</blockquote>

<p>The IO.shift is overloaded as it can also take an execution context as a parameter, so it’s possible to switch effects to a different execution context rather than a different thread.</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">val</span> <span class="nv">ec</span> <span class="k">=</span> <span class="nv">ExecutionContext</span><span class="o">.</span><span class="py">Implicits</span><span class="o">.</span><span class="py">global</span>
  <span class="k">val</span> <span class="nv">program</span> <span class="k">=</span> <span class="k">for</span> <span class="o">{</span>
    <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">shift</span><span class="o">(</span><span class="n">ec</span><span class="o">)</span>
    <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"I am running on ${Thread.currentThread().getName}"</span><span class="o">))</span>
  <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
</code></pre></div></div>
<p>which prints out:</p>

<p><code class="language-plaintext highlighter-rouge">I am running on scala-execution-context-global-12</code></p>]]></content><author><name></name></author><category term="cats" /><category term="fp" /><category term="functional-programming" /><category term="scala" /><category term="essential-effects" /><summary type="html"><![CDATA[CPU vs IO Bound work]]></summary></entry><entry><title type="html">Essential Effects 04: Granular Parallelism (Fibers)</title><link href="/2021/04/09/essential-effects-04-granular-parallelism-fibers.html" rel="alternate" type="text/html" title="Essential Effects 04: Granular Parallelism (Fibers)" /><published>2021-04-09T11:37:00+00:00</published><updated>2021-04-09T11:37:00+00:00</updated><id>/2021/04/09/essential-effects-04-granular-parallelism-fibers</id><content type="html" xml:base="/2021/04/09/essential-effects-04-granular-parallelism-fibers.html"><![CDATA[<h3 id="forking-joining-and-cancelling-an-effect">Forking, Joining and cancelling an effect</h3>

<p>As explained by the use of <code class="language-plaintext highlighter-rouge">ParallelIO</code> which is more or less the effectful form of Futures.<br />
It thus means that there has to be a way to run effects concurrently and/or in parallel.</p>

<p>It means there must be a wy to run our effect on another thread, wait for it to finish, and<br />
continue execution.</p>

<p>To explain this, we will try to rewrite the <code class="language-plaintext highlighter-rouge">parMapN</code> function that comes with cats effect, but we’‘ll call ours <code class="language-plaintext highlighter-rouge">myParMapN</code> with the following signature:</p>

<p><code class="language-plaintext highlighter-rouge">def myParMapN[A, B, C](ia: IO[A], ib: IO[B])(f: (A, B) =&gt; C): IO[C] = ???</code></p>

<p>which should do the following.</p>

<ul>
  <li>start both ia and ib computations so they run concurrently (i.e fork them)</li>
  <li>wait for their results</li>
  <li>cancel the other effect if one fails</li>
  <li>combine the results with the f function</li>
</ul>

<p>To cancel, wait or join, we need some sort of reference to the concurrent computation, in regular programming, we will easily hold reference to a thread, but in Cats Effect, instead of a thread, we have a fiber.</p>

<h4 id="fibers">Fibers</h4>

<p>Fibers are like green threads. When using a for comprehension, the computations are sequenced, so each computation is only going to start when the previous one successfully completes.</p>

<p>Instead of waiting for the computation to finish, we could <code class="language-plaintext highlighter-rouge">fork</code> that computation to work on<br />
another thread.<br />
Example:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="o">{</span>
 <span class="n">e1</span> <span class="k">&lt;-</span> <span class="nv">effect1</span><span class="o">.</span><span class="py">start</span>
 <span class="n">e2</span> <span class="k">&lt;-</span> <span class="n">effect2</span>
<span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
</code></pre></div></div>

<p>Now, by calling start on effect, we fork the effect, and it starts to run on another thread (if applicable) and effect2 doesn’t need to wait until e2 finishes.</p>

<p>The method signature for the start method is:</p>

<p>def start(implicit cs: ContextShift[IO]): IO[Fiber[IO, A]]</p>

<blockquote>
  <p>If you start an effect, the current execution is “forked”: the started effect’s<br />
execution is shifted to a different thread</p>
</blockquote>

<p>The <code class="language-plaintext highlighter-rouge">start</code> method takes an implicit parameter <code class="language-plaintext highlighter-rouge">ContextShift[IO]</code> which we can think of as an Execution Context that is responsible for scheduling tasks on other threads.</p>

<p>It’s important to know that it returns a fiber in an IO. If it just returned a fiber, this would mean that the original fiber had already started.</p>

<blockquote>
  <p>It returns a Fiber inside an IO because if it instead produced, directly, a Fiber, that<br />
would mean our original IO is running right now, but in reality it isn’t. The source<br />
IO only executes when we explicitly run it, so we need to delay access to this fiber—by wrapping it in an effect—until the source IO is executed.</p>
</blockquote>

<p>Similar to threads, Fibers are low level computing mechanisms for concurrent control, and it’s advisable to use higher level abstractions and operations.</p>

<h3 id="joining-fibers">Joining fibers</h3>

<p>Similar to threads, fibers can be joined too. Calling join on a fiber will block the calling<br />
thread (thread that called ‘join’) until the fibers returns a result.</p>

<p>Here’s an example:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">printMessagefromThread</span><span class="o">(</span><span class="n">msg</span><span class="k">:</span> <span class="kt">String</span><span class="o">)</span> <span class="k">=</span> <span class="o">{</span>
 <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"[${Thread.currentThread().getName}]: $msg"</span><span class="o">)</span>
<span class="o">}</span>
<span class="k">val</span> <span class="nv">prog</span> <span class="k">=</span>
 <span class="k">for</span> <span class="o">{</span>
  <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">unit</span>
  <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">printMessagefromThread</span><span class="o">(</span><span class="s">"Before fork"</span><span class="o">))</span>
  <span class="n">fiba</span> <span class="k">&lt;-</span> <span class="o">(</span><span class="nv">IO</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="mi">1</span> <span class="n">second</span><span class="o">)</span> <span class="o">&gt;&gt;</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">printMessagefromThread</span><span class="o">(</span><span class="s">"I am running on another thread"</span><span class="o">))).</span><span class="py">start</span>
  <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">printMessagefromThread</span><span class="o">(</span><span class="s">"After fork"</span><span class="o">))</span>
  <span class="k">_</span> <span class="k">&lt;-</span> <span class="nv">fiba</span><span class="o">.</span><span class="py">join</span>
  <span class="k">_</span> <span class="k">&lt;-</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">printMessagefromThread</span><span class="o">(</span><span class="s">"After Join"</span><span class="o">))</span>
 <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
</code></pre></div></div>

<p>which prints out:</p>

<p>Analysing the result we see that <code class="language-plaintext highlighter-rouge">After Fork</code> was printed before the forked fiber printed anything. This thus means that it didn’t wait for the fiber to finish execution. On the other hand, we see that after join was only called after the call to <code class="language-plaintext highlighter-rouge">Fiber#join</code> completed. We can prove this by even extending the fiber sleep time and we are sure that it won’t be called until that fiber is completed.</p>

<p>It’s worth noting that when we join a Fiber, execution continues on the thread the Fiber<br />
was running on, that explains why <code class="language-plaintext highlighter-rouge">After Join</code> was printed on another thread other than the one that printed <code class="language-plaintext highlighter-rouge">After Fork</code></p>

<p>Now, we can initially write our <code class="language-plaintext highlighter-rouge">myParMapN</code> like this :</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">myParMapN</span><span class="o">[</span><span class="kt">A</span>,<span class="kt">B</span>,<span class="kt">C</span><span class="o">](</span><span class="n">ia</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">A</span><span class="o">],</span> <span class="n">ib</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">B</span><span class="o">])(</span><span class="n">f</span> <span class="k">:</span> <span class="o">(</span><span class="kt">A</span><span class="o">,</span><span class="kt">B</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">C</span><span class="o">)</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">C</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
  <span class="k">for</span> <span class="o">{</span>
   <span class="n">fib1</span> <span class="k">&lt;-</span> <span class="nv">ia</span><span class="o">.</span><span class="py">start</span>
   <span class="n">fib2</span> <span class="k">&lt;-</span> <span class="nv">ib</span><span class="o">.</span><span class="py">start</span>
   <span class="n">a</span> <span class="k">&lt;-</span> <span class="nv">fib1</span><span class="o">.</span><span class="py">join</span>
   <span class="n">b</span> <span class="k">&lt;-</span> <span class="nv">fib2</span><span class="o">.</span><span class="py">join</span>
  <span class="o">}</span> <span class="k">yield</span> <span class="nf">f</span><span class="o">(</span><span class="n">a</span><span class="o">,</span><span class="n">b</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></div></div>

<h4 id="cancelling-a-fiber">Cancelling a Fiber</h4>

<p>We can cancel fibers. Imagine spinning up two CPU intensive computations in parallel, and we want the ability to cancel any one of them. We can easily do that with fibers by cancelling them.</p>

<p>Fibers can be cancelled by calling cancel on the fiber (Fiber#cancel). Cancellation is Idempotent in the sense that calling cancel on an already canceled fiber is the same as doing it once.</p>

<p>But calling join on a cancelled fiber. the join will never finish because no result will ever be produced which is opposite to regular threads that just return if we call join on an already terminated thread.</p>

<p>A naiive way to cancel can be:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">myParMapN</span><span class="o">[</span><span class="kt">A</span>,<span class="kt">B</span>,<span class="kt">C</span><span class="o">](</span><span class="n">ia</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">A</span><span class="o">],</span> <span class="n">ib</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">B</span><span class="o">])(</span><span class="n">f</span> <span class="k">:</span> <span class="o">(</span><span class="kt">A</span><span class="o">,</span><span class="kt">B</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">C</span><span class="o">)</span> <span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">C</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
  <span class="k">for</span> <span class="o">{</span>
    <span class="n">fib1</span> <span class="k">&lt;-</span> <span class="nv">ia</span><span class="o">.</span><span class="py">start</span>
    <span class="n">fib2</span> <span class="k">&lt;-</span> <span class="nv">ib</span><span class="o">.</span><span class="py">start</span>
    <span class="n">a</span>  <span class="k">&lt;-</span> <span class="nv">fib1</span><span class="o">.</span><span class="py">join</span><span class="o">.</span><span class="py">onError</span><span class="o">({</span> <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span> <span class="nv">fib2</span><span class="o">.</span><span class="py">cancel</span> <span class="o">})</span>
    <span class="n">b</span> <span class="k">&lt;-</span> <span class="nv">fib2</span><span class="o">.</span><span class="py">join</span><span class="o">.</span><span class="py">onError</span><span class="o">({</span> <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span> <span class="nv">fib1</span><span class="o">.</span><span class="py">cancel</span> <span class="o">})</span>
  <span class="o">}</span> <span class="k">yield</span> <span class="nf">f</span><span class="o">(</span><span class="n">a</span><span class="o">,</span><span class="n">b</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Where we register an <code class="language-plaintext highlighter-rouge">onError</code> handler on the IO result produced by the fiber</p>

<p>Registering an onErrorHandler is itself an effect, so it will only be registered after the fiber being joined has completed its join.</p>

<blockquote>
  <p>The issue is that registering an onError handler is itself an effect, so in the code<br />
above the handler would only be registered if we couple it to the result of fib1.join. But if we do that, then we won’t be registering the onError handler<br />
with the result of fib2 until after fib1 has actually finished</p>
</blockquote>

<p>So, this means that the onError handler of fib2 is not registered until fib1 has completed.</p>

<p>So, if fib1 fails, the error handler on fib2 isn’t registered to cancel fib1</p>

<p>It’s quite hard to directly implement cancellation using fibers, so we instead use other<br />
higher-order abstractions to handle cancellation. One of them is <code class="language-plaintext highlighter-rouge">IO#race</code> where you supply two computation values represented as <code class="language-plaintext highlighter-rouge">IO</code> values and it returns the first completed effect, either the first or second represented as an Either</p>

<blockquote>
  <p>Run two IO tasks concurrently, and return the first to finish, either in success or error. The loser of the race is canceled. The two tasks are executed in parallel if asynchronous, the winner being the first that signals a result.</p>
</blockquote>

<p>Looking at this example:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">val</span> <span class="nv">task</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="nv">IO</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="mi">100</span> <span class="n">millis</span><span class="o">)</span> <span class="o">*&gt;</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="s">"task"</span><span class="o">))</span>
<span class="k">val</span> <span class="nv">timeout</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="nv">IO</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="mi">200</span> <span class="n">millis</span><span class="o">)</span> <span class="o">*&gt;</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="s">"timeout"</span><span class="o">))</span>
<span class="k">val</span> <span class="nv">program</span> <span class="k">=</span> <span class="k">for</span> <span class="o">{</span>
      <span class="n">done</span> <span class="k">&lt;-</span> <span class="nv">IO</span><span class="o">.</span><span class="py">race</span><span class="o">(</span><span class="n">task</span><span class="o">,</span> <span class="n">timeout</span><span class="o">)</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="n">done</span> <span class="k">match</span> <span class="o">{</span>
        <span class="k">case</span> <span class="nc">Left</span><span class="o">(</span><span class="k">_</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="s">"task: won"</span><span class="o">))</span>
        <span class="k">case</span> <span class="nc">Right</span><span class="o">(</span><span class="k">_</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="nc">IO</span><span class="o">(</span><span class="nf">println</span><span class="o">(</span><span class="s">"timeout: won"</span><span class="o">))</span>
      <span class="o">}</span>
    <span class="o">}</span> <span class="k">yield</span> <span class="nv">ExitCode</span><span class="o">.</span><span class="py">Success</span>
</code></pre></div></div>

<p>We see this when we run the program:</p>

<p>task
task: won</p>

<p>We see that the other effect that should have printed <code class="language-plaintext highlighter-rouge">timeout</code> didn’t print it out to the console because it was cancelled by the race method.</p>

<p>IO#race is built upon a simpler abstraction IO#racePair which returns the winning effect and the fiber of the other effect.</p>

<blockquote>
  <p>IO#racePair: Run two IO tasks concurrently, and returns a pair containing both the winner’s successful value and the loser represented as a still-unfinished task.<br />
If the first task completes in error, then the result will complete in error, the other task being canceled.</p>
</blockquote>]]></content><author><name></name></author><category term="cats" /><category term="fp" /><category term="functional-programming" /><category term="scala" /><category term="essential-effects" /><summary type="html"><![CDATA[Forking, Joining and cancelling an effect]]></summary></entry><entry><title type="html">Essential Effects 03: Functional Parallelism</title><link href="/2021/04/08/essential-effects-03-functional-parallelism.html" rel="alternate" type="text/html" title="Essential Effects 03: Functional Parallelism" /><published>2021-04-08T11:37:00+00:00</published><updated>2021-04-08T11:37:00+00:00</updated><id>/2021/04/08/essential-effects-03-functional-parallelism</id><content type="html" xml:base="/2021/04/08/essential-effects-03-functional-parallelism.html"><![CDATA[<h3 id="parallelism">Parallelism</h3>

<p>Futures which are higher kinded <code class="language-plaintext highlighter-rouge">F[_]</code> types support parallelism by scheduling work on multiple threads via a scala.concurrent.ExecutionContext. This thus means that we can make Futures run in sequence and in parallel.<br />
Let’s see this example:</p>

<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">object</span> <span class="nc">Future2</span> <span class="k">extends</span> <span class="nc">App</span> <span class="o">{</span>

  <span class="k">implicit</span> <span class="k">val</span> <span class="nv">ec</span> <span class="k">=</span> <span class="nv">ExecutionContext</span><span class="o">.</span><span class="py">global</span>

  <span class="k">def</span> <span class="nf">sleepFor</span><span class="o">(</span><span class="n">time</span><span class="k">:</span> <span class="kt">Long</span><span class="o">)</span> <span class="k">=</span> <span class="nv">Thread</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="n">time</span><span class="o">)</span>

  <span class="k">def</span> <span class="nf">hello</span> <span class="k">=</span> <span class="nc">Future</span> <span class="o">{</span>
    <span class="nf">sleepFor</span><span class="o">(</span><span class="mi">1000</span><span class="o">)</span>
    <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"[${Thread.currentThread.getName}] Hello"</span><span class="o">)</span>
  <span class="o">}</span>

  <span class="k">def</span> <span class="nf">world</span> <span class="k">=</span> <span class="nc">Future</span> <span class="o">{</span>
    <span class="nf">sleepFor</span><span class="o">(</span><span class="mi">1000</span><span class="o">)</span>
    <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"[${Thread.currentThread.getName}] World"</span><span class="o">)</span>
  <span class="o">}</span>

  <span class="k">val</span> <span class="nv">st1</span> <span class="k">=</span> <span class="nv">System</span><span class="o">.</span><span class="py">currentTimeMillis</span><span class="o">()</span>
  <span class="k">val</span> <span class="nv">hw1</span><span class="k">:</span> <span class="kt">Future</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
    <span class="k">for</span> <span class="o">{</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="n">hello</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="n">world</span>
    <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
  <span class="o">}</span>

  <span class="nv">Await</span><span class="o">.</span><span class="py">ready</span><span class="o">(</span><span class="n">hw1</span><span class="o">,</span> <span class="mf">5.</span><span class="n">seconds</span><span class="o">)</span>
  <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"h1 took ${(System.currentTimeMillis() - st1)} milliseconds"</span><span class="o">)</span>

  <span class="k">val</span> <span class="nv">st2</span> <span class="k">=</span> <span class="nv">System</span><span class="o">.</span><span class="py">currentTimeMillis</span><span class="o">()</span>
  <span class="k">val</span> <span class="nv">hw2</span><span class="k">:</span> <span class="kt">Future</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span>
    <span class="o">(</span><span class="n">hello</span><span class="o">,</span> <span class="n">world</span><span class="o">).</span><span class="py">mapN</span><span class="o">((</span><span class="k">_</span><span class="o">,</span> <span class="k">_</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="o">())</span>

  <span class="nv">Await</span><span class="o">.</span><span class="py">ready</span><span class="o">(</span><span class="n">hw2</span><span class="o">,</span> <span class="mf">5.</span><span class="n">seconds</span><span class="o">)</span>
  <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"h2 took ${(System.currentTimeMillis() - st2)} milliseconds"</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></div></div>

<p>The first result <code class="language-plaintext highlighter-rouge">h1</code> took over 2 seconds, while the second result just took over<br />
1 second. <code class="language-plaintext highlighter-rouge">h1</code> uses a for comprehension which ensures that the computation is sequenced and “World” is printed only after “Hello” is printed. But with <code class="language-plaintext highlighter-rouge">mapN</code>, the result is undeterministic as we more or less spawn two Futures at once.</p>

<p>We composed functions using <code class="language-plaintext highlighter-rouge">flatMap</code> and <code class="language-plaintext highlighter-rouge">mapN</code> and we saw that mapN enabled parallelism for the Future data type.</p>

<p>This demonstrates that for Future, flatMap and mapN have different effects with<br />
respect to parallelism.</p>

<p>Now, let’s replace the Future data type with an IO:</p>

<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">object</span> <span class="nc">Future3</span> <span class="k">extends</span> <span class="nc">App</span> <span class="o">{</span>

  <span class="k">implicit</span> <span class="k">val</span> <span class="nv">ec</span> <span class="k">=</span> <span class="nv">ExecutionContext</span><span class="o">.</span><span class="py">global</span>

  <span class="k">def</span> <span class="nf">sleepFor</span><span class="o">(</span><span class="n">time</span><span class="k">:</span> <span class="kt">Long</span><span class="o">)</span> <span class="k">=</span> <span class="nv">Thread</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="n">time</span><span class="o">)</span>

  <span class="k">def</span> <span class="nf">hello</span> <span class="k">=</span> <span class="nc">IO</span> <span class="o">{</span>
    <span class="nf">sleepFor</span><span class="o">(</span><span class="mi">1000</span><span class="o">)</span>
    <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"[${Thread.currentThread.getName}] Hello"</span><span class="o">)</span>
  <span class="o">}</span>

  <span class="k">def</span> <span class="nf">world</span> <span class="k">=</span> <span class="nc">IO</span> <span class="o">{</span>
    <span class="nf">sleepFor</span><span class="o">(</span><span class="mi">1000</span><span class="o">)</span>
    <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"[${Thread.currentThread.getName}] World"</span><span class="o">)</span>
  <span class="o">}</span>

  <span class="k">val</span> <span class="nv">st1</span> <span class="k">=</span> <span class="nv">System</span><span class="o">.</span><span class="py">currentTimeMillis</span><span class="o">()</span>
  <span class="k">val</span> <span class="nv">hw1</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
    <span class="k">for</span> <span class="o">{</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="n">hello</span>
      <span class="k">_</span> <span class="k">&lt;-</span> <span class="n">world</span>
    <span class="o">}</span> <span class="nf">yield</span> <span class="o">()</span>
  <span class="o">}</span>

  <span class="nv">Await</span><span class="o">.</span><span class="py">ready</span><span class="o">(</span><span class="nv">hw1</span><span class="o">.</span><span class="py">unsafeToFuture</span><span class="o">(),</span> <span class="mf">5.</span><span class="n">seconds</span><span class="o">)</span>
  <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"h1 took ${(System.currentTimeMillis() - st1)} milliseconds"</span><span class="o">)</span>

  <span class="k">val</span> <span class="nv">st2</span> <span class="k">=</span> <span class="nv">System</span><span class="o">.</span><span class="py">currentTimeMillis</span><span class="o">()</span>
  <span class="k">val</span> <span class="nv">hw2</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span>
    <span class="o">(</span><span class="n">hello</span><span class="o">,</span> <span class="n">world</span><span class="o">).</span><span class="py">mapN</span><span class="o">((</span><span class="k">_</span><span class="o">,</span> <span class="k">_</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="o">())</span>

  <span class="nv">Await</span><span class="o">.</span><span class="py">ready</span><span class="o">(</span><span class="nv">hw2</span><span class="o">.</span><span class="py">unsafeToFuture</span><span class="o">(),</span> <span class="mf">5.</span><span class="n">seconds</span><span class="o">)</span>
  <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"h2 took ${(System.currentTimeMillis() - st2)} milliseconds"</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></div></div>

<p>If we run the code, we’ll see that both will take about the same time and will run on the same thread (main), this thus means that there was no parallelism involved whatsoever even with <code class="language-plaintext highlighter-rouge">mapN</code>.</p>

<blockquote>
  <p>But note: it isn’t the case mapN for Future is implemented with parallelism but<br />
flatMap is implemented as something sequential. The parallelism comes as a side effect—(pun intended)—of Future eagerly scheduling the computation, which happens before mapN itself is evaluated.</p>
</blockquote>

<p>Now, since IO doesn’t eagerly compute, mapN and flatMap have the same effect.</p>

<blockquote>
  <p>IO doesn’t provide any support for the effect of parallelism! And this is by design,<br />
because we want different effects to have different types, as per our Effect Pattern.</p>
</blockquote>

<h3 id="parallel-io">Parallel IO</h3>

<p>We have seen that the IO type we have been working with doesn’t support parrallelism, it acts more or less like non parallel higher kinded types such as regular scala collections.</p>

<p>If IO doesn’t support parallelism, we need a new type that does. In cats.effect, this type is named IO.Par (Par for “parallel”).</p>

<p>Now, this IO.Par type should not have a monad instance because we do not want to be able to serialize the execution of multiple actions (we don’t want the ability to sequence actions like flatMap), but we need an applicative instance to be able to compose independent IO.par values.</p>

<p>The IO.par type is defined as:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">object</span> <span class="nc">IO</span> <span class="o">{</span>
  <span class="k">class</span> <span class="nc">Par</span><span class="o">[</span><span class="kt">+A</span><span class="o">]</span> <span class="o">{</span> <span class="o">???</span> <span class="o">}</span> 
  <span class="k">object</span> <span class="nc">Par</span> <span class="o">{</span>
    <span class="k">def</span> <span class="nf">apply</span><span class="o">[</span><span class="kt">A</span><span class="o">](</span><span class="n">ioa</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">A</span><span class="o">])</span><span class="k">:</span> <span class="kt">Par</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="k">=</span> <span class="o">???</span> 
    <span class="k">def</span> <span class="nf">unwrap</span><span class="o">[</span><span class="kt">A</span><span class="o">](</span><span class="n">pa</span><span class="k">:</span> <span class="kt">Par</span><span class="o">[</span><span class="kt">A</span><span class="o">])</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="k">=</span> <span class="o">???</span> 
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Where we can convert wrap an <code class="language-plaintext highlighter-rouge">IO[A]</code> to give an <code class="language-plaintext highlighter-rouge">IO.Par[A]</code> as well as unwrapping an <code class="language-plaintext highlighter-rouge">IO.par[A]</code> to an <code class="language-plaintext highlighter-rouge">IO[A]</code>.<br />
Here’s a mock of what the applicative of IO.par looks like:</p>

<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">implicit</span> <span class="k">def</span> <span class="nf">ap</span><span class="o">(</span><span class="k">implicit</span> <span class="n">cs</span><span class="k">:</span> <span class="kt">ContextShift</span><span class="o">[</span><span class="kt">IO</span><span class="o">])</span><span class="k">:</span> <span class="kt">Applicative</span><span class="o">[</span><span class="kt">IO.Par</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
 <span class="k">new</span> <span class="nc">Applicative</span><span class="o">[</span><span class="kt">IO.Par</span><span class="o">]</span> <span class="o">{</span>
   <span class="k">def</span> <span class="nf">pure</span><span class="o">[</span><span class="kt">A</span><span class="o">](</span><span class="n">a</span><span class="k">:</span> <span class="kt">A</span><span class="o">)</span><span class="k">:</span> <span class="kt">IO.Par</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="k">=</span> <span class="nv">IO</span><span class="o">.</span><span class="py">Par</span><span class="o">(</span><span class="n">a</span><span class="o">)</span>
   <span class="k">def</span> <span class="nf">map</span><span class="o">[</span><span class="kt">A</span>, <span class="kt">B</span><span class="o">](</span><span class="n">pa</span><span class="k">:</span> <span class="kt">IO.Par</span><span class="o">[</span><span class="kt">A</span><span class="o">])(</span><span class="n">f</span><span class="k">:</span> <span class="kt">A</span> <span class="o">=&gt;</span> <span class="n">B</span><span class="o">)</span><span class="k">:</span> <span class="kt">IO.Par</span><span class="o">[</span><span class="kt">B</span><span class="o">]</span> <span class="k">=</span> <span class="o">???</span>
   <span class="k">def</span> <span class="nf">product</span><span class="o">[</span><span class="kt">A</span>, <span class="kt">B</span><span class="o">](</span><span class="n">pa</span><span class="k">:</span> <span class="kt">IO.Par</span><span class="o">[</span><span class="kt">A</span><span class="o">],</span> <span class="n">pb</span><span class="k">:</span> <span class="kt">IO.Par</span><span class="o">[</span><span class="kt">B</span><span class="o">])</span><span class="k">:</span> <span class="kt">IO.Par</span><span class="o">[(</span><span class="kt">A</span>, <span class="kt">B</span><span class="o">)]</span> <span class="k">=</span> <span class="o">???</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<ul>
  <li>Where ContextShift[IO] is required to be able to switch computations to different<br />
  threads, which for the present can be thought of as something similiar to a scala.concurrent.ExecutionContext or thread pool.</li>
  <li>The implementation of product will ensure that pa and pb execute on different<br />
  threads, using cs</li>
</ul>

<blockquote>
  <p>It’s quite rare that we will interact with the <code class="language-plaintext highlighter-rouge">IO.par</code> type, so it’s possible to convert from IO to IO.par types and<br />
back via the <code class="language-plaintext highlighter-rouge">Parallel[IO].parallel(a : IO[A])</code> or <code class="language-plaintext highlighter-rouge">Parallel[IO].sequential(a : IO.Par[A])</code></p>
</blockquote>

<p>Now, let us try our previous example, where we created IO values and used <code class="language-plaintext highlighter-rouge">mapN</code> on them. Let’ see if we can achieve any sort of parallelism.</p>

<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">object</span> <span class="nc">ParallelPlay</span> <span class="k">extends</span> <span class="nc">App</span> <span class="o">{</span>

  <span class="k">val</span> <span class="nv">global</span> <span class="k">=</span> <span class="nv">ExecutionContext</span><span class="o">.</span><span class="py">Implicits</span><span class="o">.</span><span class="py">global</span>

  <span class="c1">// context shift used by parallel IO for scheduling tasks on different threads</span>
  <span class="k">implicit</span> <span class="k">val</span> <span class="nv">cs</span> <span class="k">:</span> <span class="kt">ContextShift</span><span class="o">[</span><span class="kt">IO</span><span class="o">]</span> <span class="k">=</span> <span class="nv">IO</span><span class="o">.</span><span class="py">contextShift</span><span class="o">(</span><span class="n">global</span><span class="o">)</span> 

  <span class="k">def</span> <span class="nf">sleepFor</span><span class="o">(</span><span class="n">time</span><span class="k">:</span> <span class="kt">Long</span><span class="o">)</span> <span class="k">=</span> <span class="nv">Thread</span><span class="o">.</span><span class="py">sleep</span><span class="o">(</span><span class="n">time</span><span class="o">)</span>

  <span class="k">def</span> <span class="nf">hello</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="nc">IO</span> <span class="o">{</span>
    <span class="nf">sleepFor</span><span class="o">(</span><span class="mi">1000</span><span class="o">)</span>
    <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"[${Thread.currentThread.getName}] Hello"</span><span class="o">)</span>
  <span class="o">}</span>

  <span class="k">def</span> <span class="nf">world</span><span class="k">:</span> <span class="kt">IO</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="nc">IO</span> <span class="o">{</span>
    <span class="nf">sleepFor</span><span class="o">(</span><span class="mi">1000</span><span class="o">)</span>
    <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"[${Thread.currentThread.getName}] World"</span><span class="o">)</span>
  <span class="o">}</span>

  <span class="k">val</span> <span class="nv">parallelHello</span><span class="k">:</span> <span class="kt">IO.Par</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="nc">Parallel</span><span class="o">[</span><span class="kt">IO</span><span class="o">].</span><span class="py">parallel</span><span class="o">(</span><span class="n">hello</span><span class="o">)</span> <span class="c1">// converting from regular IO to a parallel IO </span>
  <span class="k">val</span> <span class="nv">parallelWorld</span><span class="k">:</span> <span class="kt">IO.Par</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="nc">Parallel</span><span class="o">[</span><span class="kt">IO</span><span class="o">].</span><span class="py">parallel</span><span class="o">(</span><span class="n">world</span><span class="o">)</span> <span class="c1">// converting from regular IO to a parallel IO </span>

  <span class="k">val</span> <span class="nv">startTime</span> <span class="k">=</span> <span class="nv">System</span><span class="o">.</span><span class="py">currentTimeMillis</span><span class="o">()</span>
  <span class="k">val</span> <span class="nv">parallelResult</span><span class="k">:</span> <span class="kt">IO.Par</span><span class="o">[</span><span class="kt">Unit</span><span class="o">]</span> <span class="k">=</span> <span class="o">(</span><span class="n">parallelHello</span><span class="o">,</span><span class="n">parallelWorld</span><span class="o">).</span><span class="py">mapN</span><span class="o">((</span><span class="k">_</span><span class="o">,</span> <span class="k">_</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="o">{</span>
    <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"computation took ${(System.currentTimeMillis() - startTime)} milliseconds"</span><span class="o">)</span>
  <span class="o">})</span>

  <span class="k">val</span> <span class="nv">sequentialIO</span> <span class="k">=</span> <span class="nc">Parallel</span><span class="o">[</span><span class="kt">IO</span><span class="o">].</span><span class="py">sequential</span><span class="o">(</span><span class="n">parallelResult</span><span class="o">)</span> <span class="c1">// turn parallel IO to sequential IO </span>

  <span class="nv">sequentialIO</span><span class="o">.</span><span class="py">unsafeRunSync</span><span class="o">()</span>
<span class="o">}</span>
</code></pre></div></div>

<p>If we run this example, we see hello and world printed on different threads as well as the total time just over 1 second.</p>

<p>Voila, we’ve achieved parallelism via the IO.Par type.</p>

<p>Now, it’s quite obvious that it’s gonna be tedious in real world programming to continuously convert between <code class="language-plaintext highlighter-rouge">IO</code> and <code class="language-plaintext highlighter-rouge">IO.Par</code>, so we have a convenient method on the regular IO called <code class="language-plaintext highlighter-rouge">parMapN</code> which behind the scenes does the same job of calling Parallel.sequential on an IO.Par as shown in the above example.</p>

<p>Here’s what it looks like:</p>
<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">(</span><span class="n">hello</span><span class="o">,</span><span class="n">world</span><span class="o">).</span><span class="py">parMapN</span><span class="o">((</span><span class="k">_</span><span class="o">,</span> <span class="k">_</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="o">{</span>
    <span class="nf">println</span><span class="o">(</span><span class="n">s</span><span class="s">"computation took ${(System.currentTimeMillis() - startTime)} milliseconds"</span><span class="o">)</span>
  <span class="o">})</span>
</code></pre></div></div>

<p>This will have the same result of running both IO effects in parallel. It’s important to note that it <code class="language-plaintext highlighter-rouge">parMapN</code> similar to <code class="language-plaintext highlighter-rouge">mapN</code> works for other tuple types apart from Tuple2.</p>

<h4 id="partraverse">parTraverse</h4>

<p>simply the parallel version of traverse with type signature:</p>

<p><code class="language-plaintext highlighter-rouge">F[A] =&gt; (A =&gt; G[B]) =&gt; G[F[B]]</code></p>

<p>simple usage: doing parallel work on a sequence and having the results combined in another F type</p>]]></content><author><name></name></author><category term="cats" /><category term="fp" /><category term="functional-programming" /><category term="scala" /><category term="essential-effects" /><summary type="html"><![CDATA[Parallelism]]></summary></entry></feed>