<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>English « Plataformatec Blog</title>
	<atom:link href="/category/english/feed/" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description>Plataformatec&#039;s place to talk about Ruby, Ruby on Rails, Elixir, and software engineering</description>
	<lastBuildDate>Wed, 06 Jan 2021 11:34:47 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.4.2</generator>
	<item>
		<title>Important information about our Elixir and Ruby Open Source projects</title>
		<link>/2020/01/important-information-about-our-elixir-and-ruby-open-source-projects/</link>
		
		<dc:creator><![CDATA[José Valim]]></dc:creator>
		<pubDate>Mon, 06 Jan 2020 21:20:55 +0000</pubDate>
				<category><![CDATA[English]]></category>
		<category><![CDATA[elixir]]></category>
		<category><![CDATA[ruby]]></category>
		<guid isPermaLink="false">/?p=9631</guid>

					<description><![CDATA[<p>You may have heard that Nubank has acqui-hired Plataformatec. Plataformatec has been working with Nubank over the past few months and Nubank saw great value on the practices and expertise shown by our teams. According to Nubank leaders, Plataformatec consultants have provided restructured rituals and new working agreements to its teams, and also brought improvements ... <a class="read-more-link" href="/2020/01/important-information-about-our-elixir-and-ruby-open-source-projects/">»</a></p>
<p>The post <a href="/2020/01/important-information-about-our-elixir-and-ruby-open-source-projects/">Important information about our Elixir and Ruby Open Source projects</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>You may have heard that <a href="https://medium.com/building-nubank/tech-perspectives-behind-nubanks-first-acquisition-deal-what-this-business-move-means-and-how-it-d7d1233c72b8">Nubank has acqui-hired Plataformatec</a>. Plataformatec has been working with Nubank over the past few months and Nubank saw great value on the practices and expertise shown by our teams. According to Nubank leaders, Plataformatec consultants have provided restructured rituals and new working agreements to its teams, and also brought improvements through better-planned teams using innovative metrics and more reliable estimates. The acquisition is a recognition of the work we displayed over the last 11 years to clients in Brazil and across the globe.</p>
<p>In the last decade, Plataformatec has also created and maintained a range of open source projects. In the next paragraphs, I will describe what the next steps are for the open source projects currently owned by Plataformatec.</p>
<p>We are very proud of the contributions we have made to open source communities throughout our history. We have built important projects in the Rails community, such as <a href="https://github.com/plataformatec/devise">Devise</a>, <a href="https://github.com/plataformatec/simple_form">Simple Form</a>, among others. We have also developed the <a href="https://elixir-lang.org/">Elixir programming language</a>, which started as a Research &amp; Development project inside Plataformatec, and today is used by companies around the world.</p>
<p>So what will happen with these projects from now on?</p>
<p>All of the projects above have one thing in common: they were created and maintained by passionate individuals who wanted to make positive contributions to their communities. Without these individuals and their efforts, these projects would not have become what they are today. Therefore, it is only fair that Plataformatec gives these individuals control of these projects moving forward.</p>
<p>For the Elixir programming language in particular, José Valim and the Elixir Core Team will continue developing and maintaining the programming language in the same capacity as they have been doing over the last few years, independently from Plataformatec and Nubank. We are in touch with the Elixir Core Team to transfer all assets, including the existing trademarks and the Elixir website, to their control. The remaining Elixir projects will be transferred to José Valim and his team at <a href="https://dashbit.co/">Dashbit</a>.</p>
<p>For all other Open Source projects <a href="https://github.com/plataformatec/">under the Plataformatec organization on GitHub</a>, we will reach out to the current maintainers and take the necessary steps to transfer the ownership of all relevant assets, including names, source code, and logos of such projects.</p>
<p>We are thankful to these communities for all the support and feedback they&#8217;ve given us throughout the years. We are glad to have been the home to these projects and to have worked with the teams that will continue shaping these projects from now on.</p><p>The post <a href="/2020/01/important-information-about-our-elixir-and-ruby-open-source-projects/">Important information about our Elixir and Ruby Open Source projects</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Elixir: What about tests?</title>
		<link>/2020/01/elixir-what-about-tests/</link>
		
		<dc:creator><![CDATA[Amanda Sposito]]></dc:creator>
		<pubDate>Thu, 02 Jan 2020 16:22:45 +0000</pubDate>
				<category><![CDATA[English]]></category>
		<category><![CDATA[elixir]]></category>
		<category><![CDATA[tests]]></category>
		<guid isPermaLink="false">/?p=9593</guid>

					<description><![CDATA[<p>There is no arguing about how important tests are for our application. But from time to time, when we are dealing with it, some questions came up on a daily basis. A very common day-do-day case is our application relying on APIs and external libs, but one of the things we don&#8217;t want our test ... <a class="read-more-link" href="/2020/01/elixir-what-about-tests/">»</a></p>
<p>The post <a href="/2020/01/elixir-what-about-tests/">Elixir: What about tests?</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="1024" src="/wp-content/uploads/2020/01/ben-kolde-H29h6a8j8QM-unsplash-1024x1024.jpg" alt="" class="wp-image-9594" srcset="/wp-content/uploads/2020/01/ben-kolde-H29h6a8j8QM-unsplash-1024x1024.jpg 1024w, /wp-content/uploads/2020/01/ben-kolde-H29h6a8j8QM-unsplash-300x300.jpg 300w, /wp-content/uploads/2020/01/ben-kolde-H29h6a8j8QM-unsplash-150x150.jpg 150w, /wp-content/uploads/2020/01/ben-kolde-H29h6a8j8QM-unsplash-768x768.jpg 768w, /wp-content/uploads/2020/01/ben-kolde-H29h6a8j8QM-unsplash-1536x1536.jpg 1536w, /wp-content/uploads/2020/01/ben-kolde-H29h6a8j8QM-unsplash-2048x2048.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>There is no arguing about how important tests are for our application.</p>



<p>But from time to time, when we are dealing with it, some questions came up on a daily basis.</p>



<p>A very common day-do-day case is our application relying on APIs and external libs, but one of the things we don&#8217;t want our test suite to do is to access the external world.</p>



<p>This can lead us to many undesired scenarios, for example: if we have a connection problem on an API test that hits the internet, the test will fail, causing our test suite to be intermittent.</p>



<h3 class="wp-block-heading">How do we mock or stub a request?</h3>



<p>Some libs can help us, I will talk about two of them.</p>



<h3 class="wp-block-heading">Bypass</h3>



<p>The first one I wanna talk about is <a href="https://github.com/PSPDFKit-labs/bypass">Bypass</a>.<br>
It is a lib that simulates an External Server, it works to stub the layer closer to the request. The idea is that you remove the external layer and start to call Bypass, so now, instead of talking to the internet, you are talking to a local server that you have control of. This way you can keep your tests protected.</p>



<p>Let&#8217;s think about an example, we will build an application that needs to fetch data from an API, and we will create a <code>LastfmClient</code> module that will be responsible for doing that.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-1" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">defmodule MyApp.Lastfm.Client <span class="hljs-keyword">do</span>
  @moduledoc<span class="hljs-string">""</span><span class="hljs-string">"
  Search tracks

  https://www.last.fm/api/show/track.search
  "</span><span class="hljs-string">""</span>

  @api_url <span class="hljs-string">"https://ws.audioscrobbler.com/2.0/"</span>

  def search(term, url \\ @api_url) <span class="hljs-keyword">do</span>
    response = Mojito.request(method: :get, url: search_url(url, term))

    <span class="hljs-keyword">case</span> response <span class="hljs-keyword">do</span>
      {:ok, %{status_code: <span class="hljs-number">200</span>, body: body}} -&gt;
        {:ok, response(body)}
      {:ok, %{status_code: <span class="hljs-number">404</span>}} -&gt;
        {:not_found, <span class="hljs-string">"Not found"</span>}
      {_, response} -&gt;
        {:error, response}
    end
  end
end</code></div><small class="shcb-language" id="shcb-language-1"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<p>What this client does is fetch the tracks from our API and according to the type of the response return something. Not that different from most of the clients we wrote on a daily basis. Let&#8217;s test it now.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-2" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">describe <span class="hljs-string">"search/2"</span> <span class="hljs-keyword">do</span>
  test <span class="hljs-string">"searches tracks by the term"</span> <span class="hljs-keyword">do</span>
    response = Client.search(<span class="hljs-string">"The Kooks"</span>)

    assert {:ok, [
      %{
        <span class="hljs-string">"artist"</span> =&gt; <span class="hljs-string">"The Kooks"</span>,
        <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Seaside"</span>,
        <span class="hljs-string">"url"</span> =&gt; <span class="hljs-string">"https://www.last.fm/music/The+Kooks/_/Seaside"</span>
      }
    ]} = response
  end
end</code></div><small class="shcb-language" id="shcb-language-2"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<h3 class="wp-block-heading">What&#8217;s the problem with this test?</h3>



<p>It seems pretty straight forward we exercise the <a href="https://en.wikipedia.org/wiki/System_under_test">SUT</a> and verify the expected outcome, but this is a fragile test because it is accessing the external world.</p>



<p>Every time we call the <code>Client.search/2</code> we are hitting the internet. A lot of problems can happen here: if the internet is down the test will fail, if the internet is slow your suit test will be slow, you won&#8217;t have the feedback as fast as you need and will be less inclined to run the test suit, or your suit test will become intermittent and you won&#8217;t trust your tests anymore, meaning that when a real failure happens you won&#8217;t care.</p>



<h3 class="wp-block-heading">How can we fix it?</h3>



<p>And that&#8217;s when <a href="https://github.com/PSPDFKit-labs/bypass">Bypass</a> comes to our aid.</p>



<p>First, you will need to setup Bypass in your tests.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-3" data-shcb-language-name="JavaScript" data-shcb-language-slug="javascript"><div><code class="hljs language-javascript">setup <span class="hljs-keyword">do</span>
  bypass = Bypass.open()

  {:ok, <span class="hljs-attr">bypass</span>: bypass}
end</code></div><small class="shcb-language" id="shcb-language-3"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">JavaScript</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">javascript</span><span class="shcb-language__paren">)</span></small></pre>


<p>And in your test, you will set up which scenarios you want to test. Is it a success call? A not found? How should your code behave in each scenario? Tell Bypass that.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-4" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">describe <span class="hljs-string">"search/2"</span> <span class="hljs-keyword">do</span>
  test <span class="hljs-string">"searches tracks by the term"</span>, %{bypass: bypass} <span class="hljs-keyword">do</span>
    Bypass.expect bypass, fn conn -&gt;
      Plug.Conn.resp(conn, <span class="hljs-number">200</span>, payload())
    end

    response = Client.search(<span class="hljs-string">"The Kooks"</span>, <span class="hljs-string">"http://localhost:/#{bypass.port}/"</span>)

    assert {:ok, [
      %{
        <span class="hljs-string">"artist"</span> =&gt; <span class="hljs-string">"The Kooks"</span>,
        <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Seaside"</span>,
        <span class="hljs-string">"url"</span> =&gt; <span class="hljs-string">"https://www.last.fm/music/The+Kooks/_/Seaside"</span>
      }
    ]} = response
  end
end

defp payload <span class="hljs-keyword">do</span>
  ~s(
    {
      <span class="hljs-string">"results"</span>: {
        <span class="hljs-string">"@attr"</span>: {},
        <span class="hljs-string">"opensearch:Query"</span>: {
          <span class="hljs-string">"#text"</span>: <span class="hljs-string">""</span>,
          <span class="hljs-string">"role"</span>: <span class="hljs-string">"request"</span>,
          <span class="hljs-string">"startPage"</span>: <span class="hljs-string">"1"</span>
        },
        <span class="hljs-string">"opensearch:itemsPerPage"</span>: <span class="hljs-string">"20"</span>,
        <span class="hljs-string">"opensearch:startIndex"</span>: <span class="hljs-string">"0"</span>,
        <span class="hljs-string">"opensearch:totalResults"</span>: <span class="hljs-string">"51473"</span>,
        <span class="hljs-string">"trackmatches"</span>: {
          <span class="hljs-string">"track"</span>: [
            {
              <span class="hljs-string">"artist"</span>: <span class="hljs-string">"The Kooks"</span>,
              <span class="hljs-string">"image"</span>: [
                {
                  <span class="hljs-string">"#text"</span>: <span class="hljs-string">"https://lastfm.freetls.fastly.net/i/u/34s/2a96cbd8b46e442fc41c2b86b821562f.png"</span>,
                  <span class="hljs-string">"size"</span>: <span class="hljs-string">"small"</span>
                },
                {
                  <span class="hljs-string">"#text"</span>: <span class="hljs-string">"https://lastfm.freetls.fastly.net/i/u/64s/2a96cbd8b46e442fc41c2b86b821562f.png"</span>,
                  <span class="hljs-string">"size"</span>: <span class="hljs-string">"medium"</span>
                },
                {
                  <span class="hljs-string">"#text"</span>: <span class="hljs-string">"https://lastfm.freetls.fastly.net/i/u/174s/2a96cbd8b46e442fc41c2b86b821562f.png"</span>,
                  <span class="hljs-string">"size"</span>: <span class="hljs-string">"large"</span>
                },
                {
                  <span class="hljs-string">"#text"</span>: <span class="hljs-string">"https://lastfm.freetls.fastly.net/i/u/300x300/2a96cbd8b46e442fc41c2b86b821562f.png"</span>,
                  <span class="hljs-string">"size"</span>: <span class="hljs-string">"extralarge"</span>
                }
              ],
              <span class="hljs-string">"listeners"</span>: <span class="hljs-string">"851783"</span>,
              <span class="hljs-string">"mbid"</span>: <span class="hljs-string">"c9b89088-01cd-4d98-a1f4-3e4a00519320"</span>,
              <span class="hljs-string">"name"</span>: <span class="hljs-string">"Seaside"</span>,
              <span class="hljs-string">"streamable"</span>: <span class="hljs-string">"FIXME"</span>,
              <span class="hljs-string">"url"</span>: <span class="hljs-string">"https://www.last.fm/music/The+Kooks/_/Seaside"</span>
            }
          ]
        }
      }
    }
  )
end</code></div><small class="shcb-language" id="shcb-language-4"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<h3 class="wp-block-heading">When to use Bypass?</h3>



<p>When you have code that needs to make an HTTP request. You need to know how your application will behave. For instance, if the API is down, will your application stop working?</p>



<p>But then comes some questions, if I have a module that depends on this <code>Client</code> implementation, will I need to repeat this Bypass code every time in my tests?<br>
Why does another module need to know these implementation details if it is not dealing with the request?</p>



<h3 class="wp-block-heading">Mox</h3>



<p><a href="https://github.com/plataformatec/mox">Mox</a> can help us with that. It forces you to implement explicit contracts in your application so we know what to expect.</p>



<p>Going back to our example, let&#8217;s implement a module called <code>Playlist</code> that will be responsible for fetching a list of songs by artist and give it a name.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-5" data-shcb-language-name="JavaScript" data-shcb-language-slug="javascript"><div><code class="hljs language-javascript">defmodule MyApp.Playlist <span class="hljs-keyword">do</span>
  alias MyApp.Lastfm.Client

  def artist(name) <span class="hljs-keyword">do</span>
    {:ok, songs} = Client.search(name)

    %{
      <span class="hljs-attr">name</span>: <span class="hljs-string">"This is #{name}"</span>,
      <span class="hljs-attr">songs</span>: songs
    }
  end
end</code></div><small class="shcb-language" id="shcb-language-5"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">JavaScript</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">javascript</span><span class="shcb-language__paren">)</span></small></pre>


<p>The simplest test we can write to this code would be something like:</p>


<pre class="wp-block-code" aria-describedby="shcb-language-6" data-shcb-language-name="JavaScript" data-shcb-language-slug="javascript"><div><code class="hljs language-javascript">describe <span class="hljs-string">"artist/1"</span> <span class="hljs-keyword">do</span>
  test <span class="hljs-string">"returns the songs by artist"</span> <span class="hljs-keyword">do</span>
    result = Playlist.artist(<span class="hljs-string">"The Kooks"</span>)

    assert result[<span class="hljs-string">"name"</span>] == <span class="hljs-string">"This is The Kooks"</span>
    assert Enum.any?(result[<span class="hljs-string">"songs"</span>], fn song -&gt;
      song[<span class="hljs-string">"artist"</span>] == <span class="hljs-string">"The Kooks"</span>
    end)
  end
end</code></div><small class="shcb-language" id="shcb-language-6"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">JavaScript</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">javascript</span><span class="shcb-language__paren">)</span></small></pre>


<p>Since the <code>Playlist</code> depends on the <code>Client</code>, to have an accurate test we would need to stub the request with the payload response from the Lastfm API so we can make sure the <code>Playlist</code> behaves accordingly.</p>



<p>You don&#8217;t need to stub all the <code>Client</code> requests in the <code>Playlist</code> tests, you need to know what it returns and handle the responses, you need to have a <a href="/2015/10/mocks-and-explicit-contracts/">explicit contract</a>.</p>



<p>Let&#8217;s see how we can implement those contracts.</p>



<h3 class="wp-block-heading">Behaviours</h3>



<p>Elixir uses <a href="https://elixir-lang.org/getting-started/typespecs-and-behaviours.html#behaviours">behaviours</a> as a way to define a set of functions that have to be implemented by a module. You can compare them to <a href="https://en.wikipedia.org/wiki/Interface_(computing)">interfaces</a> in OOP.</p>



<p>Let&#8217;s create a file at <code>lib/my_app/music.ex</code> that says what our <code>Client</code> expects as an argument and what it returns:</p>


<pre class="wp-block-code" aria-describedby="shcb-language-7" data-shcb-language-name="JavaScript" data-shcb-language-slug="javascript"><div><code class="hljs language-javascript">defmodule MyApp.Music <span class="hljs-keyword">do</span>
  @callback search(<span class="hljs-built_in">String</span>.t()) :: map()
end</code></div><small class="shcb-language" id="shcb-language-7"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">JavaScript</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">javascript</span><span class="shcb-language__paren">)</span></small></pre>


<p>In our <code>config/config.exs</code> file, let&#8217;s include two lines. The first one says which client we are using and the second one is the Lastfm API that we will remove from the default argument, just to keep the callback simple.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-8" data-shcb-language-name="JavaScript" data-shcb-language-slug="javascript"><div><code class="hljs language-javascript">config :my_app, :music, MyApp.Lastfm.Client
<span class="hljs-attr">config</span> :my_app, :lastfm_api, <span class="hljs-string">"https://ws.audioscrobbler.com/2.0/"</span></code></div><small class="shcb-language" id="shcb-language-8"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">JavaScript</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">javascript</span><span class="shcb-language__paren">)</span></small></pre>


<p>In our <code>config/test.exs</code> file, let&#8217;s include our mock module.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-9" data-shcb-language-name="CSS" data-shcb-language-slug="css"><div><code class="hljs language-css"><span class="hljs-selector-tag">config</span> <span class="hljs-selector-pseudo">:my_app</span>, <span class="hljs-selector-pseudo">:music</span>, <span class="hljs-selector-tag">MyApp</span><span class="hljs-selector-class">.MusicMock</span></code></div><small class="shcb-language" id="shcb-language-9"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">CSS</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">css</span><span class="shcb-language__paren">)</span></small></pre>


<p>In the <code>test/test_helper</code> file, let&#8217;s tell Mox which is the mock module that is responsible for mocking the calls to our behaviour.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-10" data-shcb-language-name="CSS" data-shcb-language-slug="css"><div><code class="hljs language-css"><span class="hljs-selector-tag">Mox</span><span class="hljs-selector-class">.defmock</span>(<span class="hljs-selector-tag">MyApp</span><span class="hljs-selector-class">.MusicMock</span>, <span class="hljs-selector-tag">for</span>: <span class="hljs-selector-tag">MyApp</span><span class="hljs-selector-class">.Music</span>)</code></div><small class="shcb-language" id="shcb-language-10"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">CSS</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">css</span><span class="shcb-language__paren">)</span></small></pre>


<p>Let&#8217;s go back to our <code>Playlist</code> module, and let&#8217;s change the way we call the <code>Client</code> module, to use the config we just created.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-11" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">defmodule MyApp.Playlist <span class="hljs-keyword">do</span>
  @music Application.get_env(:my_app, :music)

  def artist(name) <span class="hljs-keyword">do</span>
    {:ok, songs} = @music.search(name)

    %{
      <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"This is #{name}"</span>,
      <span class="hljs-string">"songs"</span> =&gt; songs
    }
  end
end</code></div><small class="shcb-language" id="shcb-language-11"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<p>In our <code>Client</code> module let&#8217;s adopt the behaviour we created, and let&#8217;s change the API url to fetch from the config we created.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-12" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">defmodule MyApp.Lastfm.Client <span class="hljs-keyword">do</span>
  @moduledoc<span class="hljs-string">""</span><span class="hljs-string">"
  Search tracks

  https://www.last.fm/api/show/track.search
  "</span><span class="hljs-string">""</span>

  @behaviour MyApp.Music

  def search(term) <span class="hljs-keyword">do</span>
    url = lastfm_api_url()
    response = Mojito.request(method: :get, url: search_url(url, term))

    <span class="hljs-keyword">case</span> response <span class="hljs-keyword">do</span>
      {:ok, %{status_code: <span class="hljs-number">200</span>, body: body}} -&gt;
        {:ok, response(body)}
      {:ok, %{status_code: <span class="hljs-number">404</span>}} -&gt;
        {:not_found, <span class="hljs-string">"Not found"</span>}
      {_, response} -&gt;
        {:error, response}
    end
  end

  defp lastfm_api_url <span class="hljs-keyword">do</span>
    Application.get_env(:my_app, :lastfm_api)
  end
end</code></div><small class="shcb-language" id="shcb-language-12"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<p>We will need to change the <code>test/my_app/lastfm/client_test.exs</code> to change the env config for the API url on the setup of the test, but I&#8217;ll leave it to you to do that.</p>



<p>Finally, in our <code>PlaylistTest</code> we will need to import <code>Mox</code>.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-13" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">import Mox

<span class="hljs-comment"># Make sure mocks are verified when the test exits</span>
setup :verify_on_exit!</code></div><small class="shcb-language" id="shcb-language-13"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<p>And in our test, we need to tell our <code>MusicMock</code> what is expected to return.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-14" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">describe <span class="hljs-string">"artist/1"</span> <span class="hljs-keyword">do</span>
  test <span class="hljs-string">"returns the songs by artist"</span> <span class="hljs-keyword">do</span>
    MusicMock
    |&gt; expect(:search, fn _name -&gt;
      {
        :ok,
        [
          %{
            <span class="hljs-string">"artist"</span> =&gt; <span class="hljs-string">"The Kooks"</span>,
            <span class="hljs-string">"name"</span> =&gt; <span class="hljs-string">"Seaside"</span>,
            <span class="hljs-string">"url"</span> =&gt; <span class="hljs-string">"https://www.last.fm/music/The+Kooks/_/Seaside"</span>
          }
        ]
      }
    end)

    result = Playlist.artist(<span class="hljs-string">"The Kooks"</span>)

    assert result[<span class="hljs-string">"name"</span>] == <span class="hljs-string">"This is The Kooks"</span>
    assert Enum.any?(result[<span class="hljs-string">"songs"</span>], fn song -&gt;
      song[<span class="hljs-string">"artist"</span>] == <span class="hljs-string">"The Kooks"</span>
    end)
  end
end</code></div><small class="shcb-language" id="shcb-language-14"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<h3 class="wp-block-heading">What&#8217;s the difference?</h3>



<p>Looking at the code it seems that we still need to pass the list of music in the tests. But there is a difference, the music&#8217;s list is a dependency of the <code>Playlist</code> module, but we don&#8217;t know its internals, we don&#8217;t know from where we are fetching it, how the request response works, and all these details. The only thing we need to know at the <code>Playlist</code> module is that it depends on a list of songs.</p>



<h3 class="wp-block-heading">One last thing before we go</h3>



<p>We went through all that trouble to make sure the tests are protected from the outside world, but you know, Elixir has this amazing <code>Doctest</code> feature, and one can argue that this replaces the application tests.</p>



<p>That&#8217;s not the case, <code>Doctests</code> are not <code>tests</code> and you shouldn&#8217;t rely on it to make sure your application behaves the way you expect it to. Make sure you don&#8217;t use any code that hits the external world when you are writing your documentation, there is no way to mock calls and this can cause all the problems we already discussed.</p>



<h3 class="wp-block-heading">That&#8217;s all folks</h3>



<p>The code from this example can be found <a href="https://github.com/amandasposito/my_app">here</a>, I hope it helps!</p><p>The post <a href="/2020/01/elixir-what-about-tests/">Elixir: What about tests?</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>OKR: lições aprendidas para você começar a aplicá-lo de forma efetiva</title>
		<link>/2019/12/okr-licoes-aprendidas-para-voce-comecar-a-aplica-lo-de-forma-efetiva/</link>
		
		<dc:creator><![CDATA[Raphael Albino]]></dc:creator>
		<pubDate>Wed, 18 Dec 2019 16:46:00 +0000</pubDate>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[OKR]]></category>
		<guid isPermaLink="false">/?p=9570</guid>

					<description><![CDATA[<p>Depois do sucesso do livro&#160;Measure What Matters: How Google, Bono, and the Gates Foundation Rock the World with OKRs&#160;de John Doerr, praticamente toda organização vem buscando utilizar OKR como forma de desdobrar seus objetivos e medir os avanços dos resultados. Assim como qualquer modelo,&#160;framework&#160;ou ferramenta, existe uma tendência natural das pessoas acreditarem que o artefato ... <a class="read-more-link" href="/2019/12/okr-licoes-aprendidas-para-voce-comecar-a-aplica-lo-de-forma-efetiva/">»</a></p>
<p>The post <a href="/2019/12/okr-licoes-aprendidas-para-voce-comecar-a-aplica-lo-de-forma-efetiva/">OKR: lições aprendidas para você começar a aplicá-lo de forma efetiva</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Depois do sucesso do livro&nbsp;<a href="https://www.amazon.com/Measure-What-Matters-Google-Foundation/dp/0525536221">Measure What Matters: How Google, Bono, and the Gates Foundation Rock the World with OKRs</a>&nbsp;de John Doerr, praticamente toda organização vem buscando utilizar OKR como forma de desdobrar seus objetivos e medir os avanços dos resultados.</p>



<p>Assim como qualquer modelo,&nbsp;<em>framework</em>&nbsp;ou ferramenta, existe uma tendência natural das pessoas acreditarem que o artefato resolverá os problemas organizacionais simplesmente por estar sendo aplicado. A partir das minhas andanças como consultor, me deparei com diversas situações onde as pessoas disseram que tentaram aplicar os OKRs e não obtiveram sucesso.</p>



<p>No texto a seguir, compartilharei um compilado de aprendizados e dicas para quem já lida com o&nbsp;<em>framework</em>&nbsp;ou para quem está considerando levá-lo para o seu dia a dia.</p>



<p></p>



<h2 class="wp-block-heading">1) Qual a relação entre OKR e pensamento estratégico?</h2>



<p>Um grande desafio nas organizações diz respeito a como decompor sua estratégia. Tudo começa com a construção de um pensamento estratégico que, em linhas gerais, passa por três grandes etapas: (1) coleta de informações; (2) formulação de ideias; (3) planejamento das ações (essas diretrizes e mais dicas podem ser vistas em&nbsp;<a href="https://www.amazon.com/Strategic-Thinking-Step-step-Leadership-ebook/dp/B00AXDJJ38">Strategic Thinking: A Step-by-step Approach to Strategy and Leadership</a>).</p>



<p>É fundamental que a organização entenda o que está mudando no mercado em que ela atua, como a concorrência tem se posicionado diante de tais mudanças e como a organização está operando hoje.</p>



<p>Passada a etapa de entendimento do contexto, o próximo passo de um pensamento estratégico é o levantamento de desejos, hipóteses e necessidades. É importante que a organização crie uma visão futura inspiradora e que garanta a sustentabilidade do negócio diante dos desafios que ela enfrentará.</p>



<p>O último passo é o planejamento daquilo que será feito. A organização precisa compreender quais são as opções de ações e, com muita clareza, deverá escolher o que será feito e o que não será. Neste momento, é essencial que haja uma clareza do que é prioridade dentro de uma perspectiva de curto, médio e longo prazo. Costumo dizer que prioridade é uma palavra que não deveria ser colocada no plural porque quando tudo é prioridade, nada é prioridade.<br></p>



<figure class="wp-block-image size-large"><img decoding="async" width="652" height="444" src="/wp-content/uploads/2019/12/imagem_pensamento_estrategico.png" alt="" class="wp-image-9566" srcset="/wp-content/uploads/2019/12/imagem_pensamento_estrategico.png 652w, /wp-content/uploads/2019/12/imagem_pensamento_estrategico-300x204.png 300w" sizes="(max-width: 652px) 100vw, 652px" /></figure>



<p><strong>Pois bem, então o que OKR tem a ver com o pensamento estratégico exposto acima?</strong><br></p>



<p>Quando falamos que o OKR é a composição do que desejo alcançar (objetivo) e como vou medir o progresso (conjunto de resultados-chave), precisamos partir de uma referência, que no caso do pensamento estratégico se dá através da coleta de informações. Se eu não conheço meu contexto atual, como eu posso definir onde eu quero chegar?</p>



<p>Além do mais, uma visão clara é necessária para orientar o processo de criação dos OKRs. Quando a organização não consegue estabelecer seu norte, qualquer caminho (ou no caso OKR) servirá. O problema dessa condição é que ela gera desperdício de dinheiro, esforço e energia.</p>



<p>Por fim, os OKRs nos forçam a fazer escolhas quando precisamos pensar no que será o foco de um trimestre, por exemplo. Ao definir poucos objetivos, estamos garantindo que a organização estará voltada naquilo que é o mais importante para o horizonte de tempo determinado.</p>



<p><strong>Portanto, lembre-se:</strong>&nbsp;sem estratégia, não faz sentido a aplicação de OKR.</p>



<h2 class="wp-block-heading">2) Quais problemas você pode resolver com OKRs?</h2>



<p>Se você deseja comunicar a estratégia da organização, melhorar a transparência, trazer senso de propósito para as equipes e conectar o trabalho das pessoas com os resultados do negócio, OKR pode ser uma boa forma de você chegar lá.</p>



<p><strong>2.1 &#8211; Comunicação da estratégia</strong></p>



<p>A partir do momento em que a organização tem a sua estratégia estabelecida, os OKRs que serão desenhados pelas equipes deverão se comunicar com a mesma. Em outras palavras, caso existam OKRs que não estão conectados com as diretrizes estratégicas do negócio, eles deveriam ser descartados.</p>



<p><strong>2.2 Transparência</strong></p>



<p>Ao acompanhar semanalmente o progresso dos resultados-chave, validar e comunicar mensalmente os resultados dos OKRs e refinar trimestralmente os avanços em um momento de inspeção e adaptação, a organização reduzirá uma natural assimetria de informação que existe nas hierarquias e nos silos departamentais. Ficou na dúvida de como aumentar a transparência? Siga o fluxo abaixo.</p>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-15 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><img decoding="async" width="960" height="720" src="/wp-content/uploads/2019/12/imagem_fluxo_cadencia_okr.png" alt="" data-id="9568" data-full-url="/wp-content/uploads/2019/12/imagem_fluxo_cadencia_okr.png" data-link="/imagem_fluxo_cadencia_okr/" class="wp-image-9568" srcset="/wp-content/uploads/2019/12/imagem_fluxo_cadencia_okr.png 960w, /wp-content/uploads/2019/12/imagem_fluxo_cadencia_okr-300x225.png 300w, /wp-content/uploads/2019/12/imagem_fluxo_cadencia_okr-768x576.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure></li></ul></figure>



<p>Ao atingirmos as cadências mencionadas na imagem acima, aumentamos a visibilidade do que está acontecendo no negócio e deixamos os problemas palpáveis para serem tratados.</p>



<p><strong>2.3 Conexão do trabalho com os resultados</strong></p>



<p>Ao atrelar as iniciativas (ex: projetos, evoluções de um produto) com os resultados do negócio, trazemos um senso de propósito que pode motivar e engajar as pessoas no trabalho que está sendo feito.</p>



<p>Como exercício, tenho proposto uma amarração onde toda iniciativa trabalhada por uma equipe (ex: projeto, história de usuário etc.) deve ter um objetivo e uma clareza do impacto no negócio, além da sua descrição e critério de término.</p>



<p>O exemplo abaixo é uma situação de uma equipe que, a priori, tinha recebido a “demanda” de contratar uma solução de força de vendas. Ao conectar tal demanda com o objetivo do negócio e com os resultados-chave, a equipe conseguiu ter maior entendimento da importância do trabalho que seria feito.</p>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-16 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="774" height="474" src="/wp-content/uploads/2019/12/imagem_exemplo_aplicacao_okr_iniciativa.png" alt="" data-id="9569" data-full-url="/wp-content/uploads/2019/12/imagem_exemplo_aplicacao_okr_iniciativa.png" data-link="/imagem_exemplo_aplicacao_okr_iniciativa/" class="wp-image-9569" srcset="/wp-content/uploads/2019/12/imagem_exemplo_aplicacao_okr_iniciativa.png 774w, /wp-content/uploads/2019/12/imagem_exemplo_aplicacao_okr_iniciativa-300x184.png 300w, /wp-content/uploads/2019/12/imagem_exemplo_aplicacao_okr_iniciativa-768x470.png 768w" sizes="(max-width: 774px) 100vw, 774px" /></figure></li></ul></figure>



<p>Ao unir a entrega com o resultado, você garantirá a necessidade das pessoas olharem os números e os dados da organização. Além disso, você evitará que a equipe invista tempo e esforço para atender uma demanda que não gera impacto nos objetivos do negócio. E em último caso, mas nem por isso menos importante, você forçará a equipe se questionar o porquê de estarem fazendo algo que não impacta diretamente nos objetivos do negócio.</p>



<h2 class="wp-block-heading">3) Qual a importância das métricas na definição dos OKRs?</h2>



<p>Indicadores de negócio são as melhores medidas para avaliar o progresso em direção aos objetivos. Se você está em busca de sair de um modelo onde há uma cobrança por entregas (<em>output</em>) e deseja ser cobrado por resultado (<em>outcome</em>), defina resultados-chave (<em>key results</em>) que se acoplem com os&nbsp;<a href="https://www.klipfolio.com/resources/articles/what-is-a-key-performance-indicator">indicadores de performance (KPI)</a>&nbsp;da organização.</p>



<p>Lembrando que a sigla OKR é composta de duas partes (objetivos e resultados-chave), um KPI que precisa ser melhorado será um excelente ponto de partida para criar um OKR e se tornará um resultado-chave para um objetivo.</p>



<p><strong>Lembre-se:</strong>&nbsp;OKR e KPI funcionarão perfeitamente juntos dado que os KPIs ajudam a monitorar o desempenho e a identificar problemas e áreas de melhoria no modo atual de operar da organização. Já os OKRs, contribuem na resolução de problemas, na melhoria de processos e no impulsionamento de inovações.</p>



<p>Para exemplificar, gostaria de compartilhar um caso real de uma organização que tinha como objetivo “Expandir os talentos da área de produto” e possuía como indicadores de performance o tempo médio de contratação, o número de vagas ocupadas e a pesquisa de satisfação. Depois de uma sessão de definição, saímos com o seguinte OKR:</p>



<p><strong>Objetivo:</strong>&nbsp;Expandir os talentos da área de produto.</p>



<p><strong>Resultados-chave:</strong></p>



<ul><li>Contratar 4 novas pessoas de desenvolvimento para aumentar a senioridade da equipe.</li><li>Aumentar o resultado da pesquisa de satisfação de 75% (resultado no último trimestre) para 85%.</li><li>Reduzir o tempo médio de contratação de 45 dias para 30 dias.</li></ul>



<h2 class="wp-block-heading">4) Dicas práticas</h2>



<p>Antes de finalizar o texto gostaria, de compartilhar 6 dicas práticas para você revisar sua estratégia de adoção de OKR:</p>



<ol><li><strong>Tenha o apoio executivo:</strong>&nbsp;OKR, assim como qualquer outra mudança organizacional precisa do suporte executivo para acontecer. Acreditar que apenas movimentos locais (debaixo para cima) farão com que a transformação aconteça é começar o jogo perdendo. Portanto, é fundamental que os OKRs da empresa se desdobrem para os times.</li><li><strong>Não defina muitos objetivos:</strong>&nbsp;independente do contexto (empresa, equipe, tribo etc.), tenha de 2 até 3 objetivos para garantir que as pessoas estejam focadas naquilo que importa durante o trimestre.</li><li><strong>Tenha resultados-chave mensuráveis:</strong>&nbsp;se você não consegue medir, você não saberá se está alcançado o seu objetivo. Não criei resultados-chave para métricas que não existem. Se você quer ter bons OKRs, coloque um esforço para ter as métricas disponíveis.</li><li><strong>Não tenha mais do que 3 resultados-chave por objetivo:</strong>&nbsp;se é muito difícil de medir um objetivo talvez ela possa ser repensando, reescrito ou reestruturado.</li><li><strong>Deixe os resultados visíveis para todas as pessoas da organização:</strong>&nbsp;visibilidade é alma para um melhor alinhamento e para que os problemas que surgirem de fato sejam resolvidos.</li><li><strong>Evite resultados-chave orientados por tarefas (ex: entrega de projetos):</strong>&nbsp;foque em resultados orientados ao negócio porque isso ajudará a organização a traduzir os benefícios de uma nova abordagem de trabalho e suportará a ideia de equipes multidisciplinares.</li></ol>



<h2 class="wp-block-heading">Conclusão<br><a href="https://github.com/plataformatec/blog-posts/blob/master/2019-12-OKR-licoes-aprendidas.md#conclus%C3%A3o"></a></h2>



<p>OKR é uma ótima forma de pensar de forma estratégica e fazer com que as pessoas colaborem na execução daquilo que a organização busca conquistar. O&nbsp;<em>framework</em>&nbsp;em si é bem simples, porém sua adoção, nem tanto.</p>



<p>Pensando em sistematizar a mensagem deste <em>post</em>, resolvi criar um Canvas que te ajudará no momento de desenvolver os OKRs na sua organização.</p>



<p>Basta seguir os passos sinalizados pelas setas e responder às perguntas necessárias em cada um dos quadrantes. Comece pela estratégia, defina os objetivos, crie os resultados-chave, priorize as iniciativas e defina as áreas que precisarão colaborar com aquele OKR. Cada linha do quadro representará um OKR.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="662" height="422" src="/wp-content/uploads/2019/12/imagem_okr_canvas.png" alt="" class="wp-image-9567" srcset="/wp-content/uploads/2019/12/imagem_okr_canvas.png 662w, /wp-content/uploads/2019/12/imagem_okr_canvas-300x191.png 300w" sizes="(max-width: 662px) 100vw, 662px" /></figure>



<p>E você, quais têm sido os desafios e os principais aprendizados com OKRs? O que achou do OKR Canvas?</p>



<p>Compartilhe comigo sua opinião nos comentários abaixo!</p>



<p>Referências:</p>



<ul><li><a href="/2017/09/dilemas-de-po-como-definir-okrs-em-equipes-ageis/">Como definir OKRs em equipes ágeis?</a></li><li><a href="http://eleganthack.com/the-art-of-the-okr/">The Art of the OKR</a></li><li><a href="https://felipecastro.com/en/blog/">Blog do Felipe Castro</a></li></ul><p>The post <a href="/2019/12/okr-licoes-aprendidas-para-voce-comecar-a-aplica-lo-de-forma-efetiva/">OKR: lições aprendidas para você começar a aplicá-lo de forma efetiva</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Relation between Story Points and Development Time (Lead Time)</title>
		<link>/2019/11/relation-between-story-points-and-development-time-lead-time/</link>
		
		<dc:creator><![CDATA[Otávio Silvério]]></dc:creator>
		<pubDate>Fri, 08 Nov 2019 16:01:56 +0000</pubDate>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Agile]]></category>
		<guid isPermaLink="false">/?p=9534</guid>

					<description><![CDATA[<p>Frequently I hear speculations about&#160;story points&#160;and their relation with the development time. Questions like: “Why a 3 points card took so much time to be developed” “How long it takes to deliver an 8 points card?”, “Why the team took so long to deliver only this amount of points?” and others are frequent. However, when ... <a class="read-more-link" href="/2019/11/relation-between-story-points-and-development-time-lead-time/">»</a></p>
<p>The post <a href="/2019/11/relation-between-story-points-and-development-time-lead-time/">Relation between Story Points and Development Time (Lead Time)</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Frequently I hear speculations about&nbsp;<a href="https://www.mountaingoatsoftware.com/blog/what-are-story-points" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">story points</a>&nbsp;and their relation with the development time. Questions like: “Why a 3 points card took so much time to be developed” “How long it takes to deliver an 8 points card?”, “Why the team took so long to deliver only this amount of points?” and others are frequent. However, when searching about story points and development time, there is a series of comments about this relationship where: some people will tell you story points measure only the effort to implement a card, others consider a relation between days (or even hours) and the points, while others only compare sizes between the cards and so on.</p>



<p>Trying to get a better understanding of this subject to talk to clients and stakeholders in general, I decided to collect real project data and analyze the relation between amount of story points of the cards and the time it took for each to be developed, counting since the time they started to be developed until the moment they are delivered to production, the famous&nbsp;<a href="/2017/08/metricas-ageis-o-que-lead-time-fala-sobre-seu-projeto/" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">Lead Time</a>.</p>



<h2 class="wp-block-heading" id="disclaimers">Disclaimers</h2>



<p>Before we start, some disclaimers about the context of the project:</p>



<ul><li>Right in the first few weeks of the project we already had the first big problem with story points: subjectivity in estimate the cards. Why this card is worth 3? How do I know this card is twice or thrice the size of the X card? What do I consider in this estimative?</li><li>Thus, it was suggested to the team to utilize some criteria to estimate, intending to reduce this subjectivity.</li><li>My friend and colleague&nbsp;<a href="https://www.linkedin.com/in/henriqueadeoliveira/" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">Henrique Oliveira</a>&nbsp;suggested a Fibonacci-like matrix, taking into account T-Shirt Size estimates, to estimate the cards, that helped the team a lot. Check it below:</li></ul>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="875" src="/wp-content/uploads/2019/11/image-1-1024x875.png" alt="" class="wp-image-9538" srcset="/wp-content/uploads/2019/11/image-1-1024x875.png 1024w, /wp-content/uploads/2019/11/image-1-300x256.png 300w, /wp-content/uploads/2019/11/image-1-768x656.png 768w, /wp-content/uploads/2019/11/image-1.png 1098w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<ul><li>Cards estimated as 13 points or higher were broken into smaller cards, as the only time we worked with a card with 13 points, it exceeded the timebox of the sprint, which was 10 business days. So we decide to do not let any card with 13 or more story points to be added to the sprint backlog.</li><li>Cards were broken down into smaller cards in a way that they delivered something functional in production, so that the backend and frontend stayed together on the same card.</li></ul>



<h2 class="wp-block-heading" id="a-look-into-the-data">A look into the data</h2>



<p>I began by collecting the data of the project as a whole and analyzing the lead time graph with all cards that had already been finished or that were in production.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="446" src="/wp-content/uploads/2019/09/grafico-lt-all-1024x446.png" alt="" class="wp-image-9381" srcset="/wp-content/uploads/2019/09/grafico-lt-all-1024x446.png 1024w, /wp-content/uploads/2019/09/grafico-lt-all-300x131.png 300w, /wp-content/uploads/2019/09/grafico-lt-all-768x335.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>After acquiring this data, I segmented them by the amount of story points and analyzed them individually, having the following graphs:</p>



<h4 class="wp-block-heading" id="cards-with-1-story-point">Cards with 1 story point</h4>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="405" src="/wp-content/uploads/2019/09/grafico-lt-1-sp-1024x405.png" alt="" class="wp-image-9382" srcset="/wp-content/uploads/2019/09/grafico-lt-1-sp-1024x405.png 1024w, /wp-content/uploads/2019/09/grafico-lt-1-sp-300x119.png 300w, /wp-content/uploads/2019/09/grafico-lt-1-sp-768x304.png 768w, /wp-content/uploads/2019/09/grafico-lt-1-sp.png 1242w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h4 class="wp-block-heading" id="cards-with-2-story-points">Cards with 2 story points</h4>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="405" src="/wp-content/uploads/2019/09/grafico-lt-2-sp-1024x405.png" alt="" class="wp-image-9383" srcset="/wp-content/uploads/2019/09/grafico-lt-2-sp-1024x405.png 1024w, /wp-content/uploads/2019/09/grafico-lt-2-sp-300x119.png 300w, /wp-content/uploads/2019/09/grafico-lt-2-sp-768x304.png 768w, /wp-content/uploads/2019/09/grafico-lt-2-sp.png 1242w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h4 class="wp-block-heading" id="cards-with-3-story-points">Cards with 3 story points</h4>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="405" src="/wp-content/uploads/2019/09/grafico-lt-3-sp-1024x405.png" alt="" class="wp-image-9384" srcset="/wp-content/uploads/2019/09/grafico-lt-3-sp-1024x405.png 1024w, /wp-content/uploads/2019/09/grafico-lt-3-sp-300x119.png 300w, /wp-content/uploads/2019/09/grafico-lt-3-sp-768x304.png 768w, /wp-content/uploads/2019/09/grafico-lt-3-sp.png 1242w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h4 class="wp-block-heading" id="cards-with-5-story-points">Cards with 5 story points</h4>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="405" src="/wp-content/uploads/2019/09/grafico-lt-5-sp-1024x405.png" alt="" class="wp-image-9385" srcset="/wp-content/uploads/2019/09/grafico-lt-5-sp-1024x405.png 1024w, /wp-content/uploads/2019/09/grafico-lt-5-sp-300x119.png 300w, /wp-content/uploads/2019/09/grafico-lt-5-sp-768x304.png 768w, /wp-content/uploads/2019/09/grafico-lt-5-sp.png 1242w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h4 class="wp-block-heading" id="cards-with-8-story-points">Cards with 8 story points</h4>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="405" src="/wp-content/uploads/2019/09/grafico-lt-8-sp-1024x405.png" alt="" class="wp-image-9386" srcset="/wp-content/uploads/2019/09/grafico-lt-8-sp-1024x405.png 1024w, /wp-content/uploads/2019/09/grafico-lt-8-sp-300x119.png 300w, /wp-content/uploads/2019/09/grafico-lt-8-sp-768x304.png 768w, /wp-content/uploads/2019/09/grafico-lt-8-sp.png 1242w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h4 class="wp-block-heading" id="cards-with-13-story-points">Cards with 13 story points</h4>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="405" src="/wp-content/uploads/2019/09/grafico-lt-13-sp-1024x405.png" alt="" class="wp-image-9387" srcset="/wp-content/uploads/2019/09/grafico-lt-13-sp-1024x405.png 1024w, /wp-content/uploads/2019/09/grafico-lt-13-sp-300x119.png 300w, /wp-content/uploads/2019/09/grafico-lt-13-sp-768x304.png 768w, /wp-content/uploads/2019/09/grafico-lt-13-sp.png 1242w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="data-analysis">Data Analysis</h2>



<p>After analyzing the data, I reached some conclusions:</p>



<ul><li>It’s possible to verify that cards worthing 3, 5 or 8 points have a development time (lead time) similar, not being possible to find a correlation between time and the number of story points (it is not scalar).</li><li>If we take a category with plenty of samples, like the cards with 5 points, it’s evident they differ a lot, not being possible to make some affirmations such as “a card worth 5 points takes between X and Y days to finish” when X and Y a small interval of days (1 to 3 days). The same happens with cards with 3 and 8 points.</li></ul>



<p><strong>Observation:</strong>&nbsp;Data referring to cards worth 1, 2 or 13 story points were excluded from the individual analysis, because there was little data to be analyzed individually.</p>



<h2 class="wp-block-heading" id="other-analysis-beyond-story-points-x-lead-time">Other Analysis beyond story points x lead time</h2>



<p>I reached more conclusions about the use of story points that I would like to share with you all:</p>



<ul><li>At the beginning of the project, when we started to use story points, the subjectivity was very high. By establishing some criteria for estimation, we were able to stabilize it, making the time of development vary a lot less, increasing predictability. If you want to develop this with your team, consider checking out this article from&nbsp;<a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://www.mountaingoatsoftware.com/blog/what-are-story-points" target="_blank">Mike Cohn</a>.</li><li>With the addition of more scoring criteria, like test complexity, dependency on people that are not in the team (internal or external to the company), risks related to the cards and more, we lowered the lead time variability and increased the card delivery rate by breaking the card into smaller ones.</li><li>Many times people relate story points with only the development effort, and this makes the team consider only the time of the Execution of a task. Another point is that the testers/QAs and UXs/designers, have little to no involvement in the estimatives. Making the team think not only about development, but also about the duration of the process as a whole (considering the steps of code review, tests, deploy, etc) and inviting more people to share their concerns about the estimatives helps to improve the predictability of the team.</li><li>With help from metrics like&nbsp;<a href="/2017/10/metricas-ageis-cumulative-flow-diagrams-e-lead-time-breakdown/" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">lead time breakdown and CFD</a>, the process of stabilizing the scoring was much easier, as it made the team think about the whole process and showed in which step of the process the team was spending the most time with.</li></ul>



<h2 class="wp-block-heading" id="conclusions">Conclusions</h2>



<p>The major conclusions I had were:</p>



<ul><li>It wasn’t possible to relate time of development (lead time) with Story Points directly, as the goal of the study was.</li><li>It is important to say Story Points should be used inside the team level. If you want to know more about this subject, I recommend the&nbsp;<a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://observablehq.com/@troymagennis/story-point-velocity-or-throughput-forecasting-does-it-mat" target="_blank">reading of this text from Troy Magennis.</a></li><li>It was possible to increase the predictability of team delivery and stabilize the process of development using story points with other tools at the same time.</li><li>There are indications that, when you add more criteria to the estimation to breakdown the cards into smaller cards, the smaller the risk/effort/complexity will be and, consequently, the predictability you also increase.</li><li>An important point here is that story points and other estimative methods consider only the moments in which a demand is being worked on, and not consider/can&#8217;t predict the time that a demand will be staying in waiting to be worked on. Basically, the team considers how long it will take for a demand to be developed and tested, but don’t consider in this estimatives (as it is not possible to predict some points in the middle of the development) how long the demand will be staying in waiting to be tested, to be deployed or how long it will take to resolve a hypothetical impediment. In other words, the&nbsp;<a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://observablehq.com/@troymagennis/how-does-utilization-impact-lead-time-of-work?collection=@troymagennis/agile-software-development" target="_blank">process efficiency</a>&nbsp;will impact your lead time, and consequently, the relation between story points with the time of development. This way, it’s plausible that a user story of 1 story point takes the same amount of days that a 13 points user story to be delivered, because of the flow efficiency. If you would like to know more about process efficiency,&nbsp;<a href="https://observablehq.com/@troymagennis/story-point-velocity-or-throughput-forecasting-does-it-mat" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">check this article</a>.</li></ul>



<h2 class="wp-block-heading" id="and-if-you-were-asked-if-you-would-use-story-points-to-estimate-a-deadline-for-a-delivery-of-a-project-or-card-what-would-you-respond">And if you were asked if you would use story points to estimate a deadline for a delivery of a project or card, what would you respond?</h2>



<p>I would say that story points, like the&nbsp;<a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="/2017/01/requisitos-em-equipes-ageis-falando-sobre-complexidade-e-incerteza/" target="_blank">matrix for complexity and uncertainty (T-shirt Size)</a>, are excellent tools to instigate your team in better breaking user stories down and help with improvements in the processes, however, to estimate deadlines, I prefer to utilize process metrics and other tools, like a&nbsp;<a href="/2019/10/monte-carlo-in-practice-finding-the-ideal-iteration-value/" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">Monte Carlo simulation</a>&nbsp;to help predict when a set of cards will be delivered.</p>



<p>What about you? Do you have any experience with Story Points and time estimates? Have you passed through any similar scenario? What’s your opinion about what I shared in this text? Share with us commenting below or in this email&nbsp;<a href="/wp-admin/contagil@plataformatec.com.br">contagil@plataformatec.com.br</a></p><p>The post <a href="/2019/11/relation-between-story-points-and-development-time-lead-time/">Relation between Story Points and Development Time (Lead Time)</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Monte Carlo in Practice: Finding the ideal iteration value</title>
		<link>/2019/10/monte-carlo-in-practice-finding-the-ideal-iteration-value/</link>
		
		<dc:creator><![CDATA[Gabriel Lopes]]></dc:creator>
		<pubDate>Fri, 25 Oct 2019 19:14:59 +0000</pubDate>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Agile]]></category>
		<guid isPermaLink="false">/?p=9410</guid>

					<description><![CDATA[<p>One of the reasons to use any kind of project management methodology is to reduce costs. A delay in a single week of a project creates two different cost types: The first is the cost of the team, since they will need to work another week. The second is the Cost of Delay, which is ... <a class="read-more-link" href="/2019/10/monte-carlo-in-practice-finding-the-ideal-iteration-value/">»</a></p>
<p>The post <a href="/2019/10/monte-carlo-in-practice-finding-the-ideal-iteration-value/">Monte Carlo in Practice: Finding the ideal iteration value</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>One of the reasons to use any kind of project management methodology is to reduce costs.</p>



<p>A delay in a single week of a project creates two different cost types:</p>



<ul><li>The first is the cost of the team, since they will need to work another week.</li><li>The second is the Cost of Delay, which is the income not collected due to the delay. For instance, suppose the new feature this team is working on would generate a daily income of&nbsp;<strong>$100</strong>, the Cost of Delay would be&nbsp;<strong>$700</strong>&nbsp;($100 * 7 days).</li></ul>



<p>Since these costs can be high, using tools that provide more visibility on delivery dates is necessary. One tool that can help solve this problem is the Gantt Chart. With the Gantt Chart it’s possible to identify the most frail points of the project (the critical path) where more effort should be made to prevent delays, since a delay in any step of those points will impact the project as a whole.</p>



<p>Even though this tool is great for some types of projects (normally when there is a low uncertainty level), it’s not ideal for projects where the predictability is low due to the&nbsp;<a href="https://en.wikipedia.org/wiki/Variance" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">variance</a>&nbsp;of the deliverables, as in projects that happen in the field of knowledge (writing a book or software development, for example).</p>



<p>Here at Plataformatec, we have always done our best to make our delivery predictions based on data and ensure they follow proven scientific methodology. The two methods we use the most are:</p>



<ul><li>Linear Progression</li><li>Monte Carlo Simulation</li></ul>



<h2 class="wp-block-heading" id="linear--progression">LINEAR PROGRESSION</h2>



<p>In linear progression, we do data analysis on the delivered work items during some time period (in software development we normally work with weeks) and through the study of this information we come up with the best values for the progression. For example: suppose we have the following historic values of work items by week, as shown below:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="445" src="/wp-content/uploads/2019/11/tp_table-1024x445.png" alt="" class="wp-image-9549" srcset="/wp-content/uploads/2019/11/tp_table-1024x445.png 1024w, /wp-content/uploads/2019/11/tp_table-300x130.png 300w, /wp-content/uploads/2019/11/tp_table-768x334.png 768w, /wp-content/uploads/2019/11/tp_table-1536x668.png 1536w, /wp-content/uploads/2019/11/tp_table.png 1804w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>A value that could be used as a&nbsp;<strong>pessimistic</strong>&nbsp;projection would be to assume a delivery of&nbsp;<strong>1</strong>&nbsp;work item per week, seeing as we’ve had 5 cases where the throughput was&nbsp;<strong>1</strong>&nbsp;or&nbsp;<strong>0</strong>. For the&nbsp;<strong>optimist</strong>&nbsp;projection we could use either the value of&nbsp;<strong>3</strong>&nbsp;or&nbsp;<strong>4</strong>, or even&nbsp;<strong>3.5</strong>, as we’ve had 4 instances where the throughput was&nbsp;<strong>3 or higher</strong>. Lastly, for the&nbsp;<strong>likely</strong>&nbsp;projection, a good value would be&nbsp;<strong>2</strong>, as it’s the&nbsp;<strong>median</strong>&nbsp;and the&nbsp;<strong>mode</strong>&nbsp;of this dataset.</p>



<p>The biggest problem with the linear progression is that we are inputting the values for each scenario, something that can be dangerous if the person operating the linear progression doesn’t have a good grasp of data analytics. Furthermore, linear progression ignores variance. Thus, in work systems with high variance of deliveries, the linear progression tool might not be the best approach.</p>



<h2 class="wp-block-heading" id="monte--carlo">MONTE CARLO</h2>



<p>Another technique we can use is called&nbsp;<strong><a href="https://en.wikipedia.org/wiki/Monte_Carlo_method" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">Monte Carlo</a></strong>, which runs random picks from our historic throughput data to try and find the likelihood of delivery.</p>



<p>I’m having success using this method, however a question that keeps coming to my mind is: “How many interactions are necessary to make the method statistically valuable and the results reliable?”. Looking for an answer to this question, I’ve researched some statistics books, and also the internet, but wasn’t able to find any information that would help.</p>



<p>So I decided to run a study on this subject. Monte Carlo’s objective is to infer the probability of an event, “forcing” it to happen so many times, in order to use the&nbsp;<a href="https://en.wikipedia.org/wiki/Law_of_large_numbers">law of large numbers</a>&nbsp;in our favor. For example, if you flip a coin a thousand times, count how many times it falls as “heads”, and divide by a thousand, you will get an inference of the probability of getting “heads”.</p>



<p>To check the quality of the method, I first ran tests over probabilities for which I already knew the expected results. After that, I started increasing the complexity of the problem, in order to see if there was any correlation between the difficulty of a problem and the number of interactions necessary for the inferred value from Monte Carlo to be as close as possible to the calculated one.</p>



<p>The objective of the tests is to see how many interactions are necessary for the inferred value to be close enough to the calculated value that the gain of running more interactions would be too low to compensate the computer power necessary to run it (for a project probability standpoint an error in the first or second decimal values would be acceptable). I’d like to highlight that this blog post is not a scientific study of the subject, and the objective is to understand through inference a good value for project predictions.</p>



<h2 class="wp-block-heading" id="the--tests">THE TESTS</h2>



<p>The tests were performed using the programing language&nbsp;<strong>R</strong>, which can be downloaded in this&nbsp;<a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://www.r-project.org/" target="_blank">link</a>. If you would rather use an IDE, I recommend using&nbsp;<a href="https://www.rstudio.com/" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">RStudio</a>.</p>



<p>In each test, I’ve run the algorithm&nbsp;<strong>100</strong>&nbsp;times using the following interaction values:&nbsp;<strong>100</strong>&nbsp;(one hundred),&nbsp;<strong>1000</strong>&nbsp;(one thousand),&nbsp;<strong>10000</strong>&nbsp;(ten thousand),&nbsp;<strong>100000</strong>&nbsp;(one hundred thousand),&nbsp;<strong>1000000</strong>&nbsp;(one million),&nbsp;<strong>10000000</strong>&nbsp;(ten million),&nbsp;<strong>100000000</strong>&nbsp;(one hundred million) e&nbsp;<strong>200000000</strong>&nbsp;(two hundred million). The results of these 100 &#8220;rounds&#8221; are then consolidated.</p>



<h3 class="wp-block-heading" id="the--coin">THE COIN</h3>



<p>The first test that I’ve run was the flipping of a single coin. In a coin flip, there is a&nbsp;<strong>50%</strong>&nbsp;chance of it landing on any side, and this is the value we want the Monte Carlo to infer. For that I’ve used the following R code:</p>


<pre class="wp-block-code" aria-describedby="shcb-language-17" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">
FLipCoin  &lt;-  <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(iterations)</span>
</span>{
  <span class="hljs-comment"># Creates  a  vector  with  the  possible  values  for  a  coin  1  =  Heads  and  0  =  Tails</span>
  coin  =  c(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>)
  result  =  <span class="hljs-number">0</span>

  <span class="hljs-comment"># Flips  a  number  of  coins  equal  to  the  interaction  value  and  sum  up  all  the  times  where  the  coin  landed  in  "Heads"</span>
  result  =  sum(sample(coin,  iterations,  replace=T))

  <span class="hljs-comment"># Turns  the  value  in  a  percentage  of  the  coin  flips</span>
  result  =  (result/iterations)  *  <span class="hljs-number">100</span>

  <span class="hljs-keyword">return</span>(result)
}

<span class="hljs-comment"># Initiates  variables</span>
result_vector  =  <span class="hljs-number">0</span>
time_vector  =  <span class="hljs-number">0</span>
control  =  <span class="hljs-number">0</span>

<span class="hljs-comment"># Controls  the  interaction  quantity</span>
iterations  =  <span class="hljs-number">100</span>

<span class="hljs-comment"># Alocates  the  percentual  of  "Heads"  results  in  a  100  size  vector  and  the  execution  time  in  another</span>
<span class="hljs-keyword">while</span>(control  !=  <span class="hljs-number">100</span>)
{
  start_time  =  Sys.time()
  result_vector  =  append(result_vector,  FLipCoin(iterations))  
  finish_time  =  Sys.time()

  time  =  finish_time  -  start_time
  time_vector  =  append(time_vector,  time)  

  control  =  control  +  <span class="hljs-number">1</span>
}

<span class="hljs-comment"># Shows  the  percentual  of  "Heads"</span>
result_vector

<span class="hljs-comment"># Shows  the  execution  times</span>
time_vector

</code></div><small class="shcb-language" id="shcb-language-17"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<p>Changing the values of the iterations and compiling the results, I’ve got the following table:</p>



<ul><li> 
<table id="tablepress-12" class="tablepress tablepress-id-12">
<thead>
<tr class="row-1">
	<th class="column-1">Iterations</th><th class="column-2">Min result</th><th class="column-3">Max result</th><th class="column-4">Expected result</th><th class="column-5">Average result</th><th class="column-6">Average result - Expected result</th><th class="column-7">Result's median</th><th class="column-8">Result's median - Expected</th><th class="column-9">result | Result's   Standard deviation</th>
</tr>
</thead>
<tbody class="row-hover">
<tr class="row-2">
	<td class="column-1"> 100</td><td class="column-2">33.00000</td><td class="column-3">67.00000</td><td class="column-4">50.00000 </td><td class="column-5">50.02000 </td><td class="column-6">0.02000 </td><td class="column-7">50.00000 </td><td class="column-8">0.00000 </td><td class="column-9">5.09368 </td>
</tr>
<tr class="row-3">
	<td class="column-1">1000</td><td class="column-2">43.60000</td><td class="column-3">56.20000 </td><td class="column-4">50.00000 </td><td class="column-5">49.99440 </td><td class="column-6">0.00560 </td><td class="column-7">50.00000 </td><td class="column-8">0.00000 </td><td class="column-9">1.59105 </td>
</tr>
<tr class="row-4">
	<td class="column-1">10000</td><td class="column-2">48.35000</td><td class="column-3">51.78000 </td><td class="column-4">50.00000 </td><td class="column-5">50.01263 </td><td class="column-6">0.01263 </td><td class="column-7">50.02000 </td><td class="column-8">0.02000 </td><td class="column-9">0.51001 </td>
</tr>
<tr class="row-5">
	<td class="column-1">100000</td><td class="column-2">49.58000</td><td class="column-3">51.78000 </td><td class="column-4">50.00000 </td><td class="column-5">49.99110 </td><td class="column-6">0.00890 </td><td class="column-7">49.99350 </td><td class="column-8">0.00650 </td><td class="column-9">0.15805 </td>
</tr>
<tr class="row-6">
	<td class="column-1">1000000 </td><td class="column-2">49.85170</td><td class="column-3">50.15090 </td><td class="column-4">50.00000 </td><td class="column-5">49.99883 </td><td class="column-6">0.00117 </td><td class="column-7">49.99785 </td><td class="column-8">0.00215 </td><td class="column-9">0.04811 </td>
</tr>
<tr class="row-7">
	<td class="column-1">10000000</td><td class="column-2">49.95433 </td><td class="column-3">50.05807 </td><td class="column-4">50.00000 </td><td class="column-5">50.00013 </td><td class="column-6">0.00013 </td><td class="column-7">50.00010 </td><td class="column-8">0.00010 </td><td class="column-9">0.01564 </td>
</tr>
<tr class="row-8">
	<td class="column-1">100000000</td><td class="column-2">49.98435 </td><td class="column-3">50.01637 </td><td class="column-4">50.00000 </td><td class="column-5">50.00004 </td><td class="column-6">0.00004 </td><td class="column-7">49.99989 </td><td class="column-8">0.00011 </td><td class="column-9">0.00516 </td>
</tr>
<tr class="row-9">
	<td class="column-1">200000000</td><td class="column-2">49.98890</td><td class="column-3">50.01195 </td><td class="column-4">50.00000 </td><td class="column-5">49.99981 </td><td class="column-6">0.00019 </td><td class="column-7">49.99987 </td><td class="column-8">0.00013 </td><td class="column-9">0.00345 </td>
</tr>
</tbody>
</table>
<!-- #tablepress-12 from cache --> </li></ul>



<p>In the instance of a simple problem, like the flipping of a single coin, we can see that a good iteration value could be:</p>



<ul><li>between&nbsp;<strong>10M</strong>&nbsp;and&nbsp;<strong>100M</strong>&nbsp;if you are ok with having an error in the&nbsp;<strong>third decimal</strong>,</li><li>between&nbsp;<strong>100k</strong>&nbsp;and&nbsp;<strong>1M</strong>&nbsp;in the&nbsp;<strong>second decimal</strong></li><li>between&nbsp;<strong>1k</strong>&nbsp;and&nbsp;<strong>10k</strong>&nbsp;in the&nbsp;<strong>first decimal</strong>.</li></ul>



<h3 class="wp-block-heading" id="one--die">ONE DICE</h3>



<p>With the coin test it was possible to infer the number of necessary interactions, based on the desired degree of reliability. However a question remains regarding if this behavior changes for more complex problems. Because of that, I’ve run a similar test with a single six-sided die that has a&nbsp;<strong>16,67%</strong>&nbsp;chance of landing on any side.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-18" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">
RollDie  &lt;-  <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(iterations)</span>
</span>{
  <span class="hljs-comment"># Creates  a  vector  with  the  possible  values  of  the  die</span>
  <span class="hljs-keyword">die</span>  =  <span class="hljs-number">1</span>:<span class="hljs-number">6</span>
  result  =  <span class="hljs-number">0</span>

  <span class="hljs-comment"># Alocates  the  die  roll  results</span>
  result  =  sample(<span class="hljs-keyword">die</span>,iterations,replace=T)

  <span class="hljs-comment"># Sum  up  every  instace  where  the  die  landed  on  6</span>
  result  =  sum(result  ==  <span class="hljs-number">6</span>)

​
  <span class="hljs-comment"># Turns  the  value  in  a  percentage  of  the  die  rolls</span>
  result  =  (result/iterations)  *  <span class="hljs-number">100</span>

  <span class="hljs-keyword">return</span>(result)
}

<span class="hljs-comment"># Initiates  variables</span>
result_vector  =  <span class="hljs-number">0</span>
time_vector  =  <span class="hljs-number">0</span>
control  =  <span class="hljs-number">0</span>

<span class="hljs-comment"># Controls  the  interaction  quantity</span>
iterations  =  <span class="hljs-number">100</span>

<span class="hljs-comment"># Alocates  the  percentual  of  "6"  results  in  a  100  size  vector  and  the  execution  time  in  another</span>
<span class="hljs-keyword">while</span>(control  !=  <span class="hljs-number">100</span>)
{
  start_time  =  Sys.time()
  result_vector  =  append(result_vector,  RollDie(iterations))  
  finish_time  =  Sys.time()

​
  time  =  finish_time  -  start_time
  time_vector  =  append(time_vector,  time)  

  control  =  control  +  <span class="hljs-number">1</span>
}

<span class="hljs-comment"># Shows  the  percentual  of  "6"</span>
result_vector

<span class="hljs-comment"># Shows  the  execution  times</span>
time_vector

</code></div><small class="shcb-language" id="shcb-language-18"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<p>Changing the values of the iterations and compiling the results , I’ve got the following table:</p>




<table id="tablepress-12-no-2" class="tablepress tablepress-id-12">
<thead>
<tr class="row-1">
	<th class="column-1">Iterations</th><th class="column-2">Min result</th><th class="column-3">Max result</th><th class="column-4">Expected result</th><th class="column-5">Average result</th><th class="column-6">Average result - Expected result</th><th class="column-7">Result's median</th><th class="column-8">Result's median - Expected</th><th class="column-9">result | Result's   Standard deviation</th>
</tr>
</thead>
<tbody class="row-hover">
<tr class="row-2">
	<td class="column-1"> 100</td><td class="column-2">33.00000</td><td class="column-3">67.00000</td><td class="column-4">50.00000 </td><td class="column-5">50.02000 </td><td class="column-6">0.02000 </td><td class="column-7">50.00000 </td><td class="column-8">0.00000 </td><td class="column-9">5.09368 </td>
</tr>
<tr class="row-3">
	<td class="column-1">1000</td><td class="column-2">43.60000</td><td class="column-3">56.20000 </td><td class="column-4">50.00000 </td><td class="column-5">49.99440 </td><td class="column-6">0.00560 </td><td class="column-7">50.00000 </td><td class="column-8">0.00000 </td><td class="column-9">1.59105 </td>
</tr>
<tr class="row-4">
	<td class="column-1">10000</td><td class="column-2">48.35000</td><td class="column-3">51.78000 </td><td class="column-4">50.00000 </td><td class="column-5">50.01263 </td><td class="column-6">0.01263 </td><td class="column-7">50.02000 </td><td class="column-8">0.02000 </td><td class="column-9">0.51001 </td>
</tr>
<tr class="row-5">
	<td class="column-1">100000</td><td class="column-2">49.58000</td><td class="column-3">51.78000 </td><td class="column-4">50.00000 </td><td class="column-5">49.99110 </td><td class="column-6">0.00890 </td><td class="column-7">49.99350 </td><td class="column-8">0.00650 </td><td class="column-9">0.15805 </td>
</tr>
<tr class="row-6">
	<td class="column-1">1000000 </td><td class="column-2">49.85170</td><td class="column-3">50.15090 </td><td class="column-4">50.00000 </td><td class="column-5">49.99883 </td><td class="column-6">0.00117 </td><td class="column-7">49.99785 </td><td class="column-8">0.00215 </td><td class="column-9">0.04811 </td>
</tr>
<tr class="row-7">
	<td class="column-1">10000000</td><td class="column-2">49.95433 </td><td class="column-3">50.05807 </td><td class="column-4">50.00000 </td><td class="column-5">50.00013 </td><td class="column-6">0.00013 </td><td class="column-7">50.00010 </td><td class="column-8">0.00010 </td><td class="column-9">0.01564 </td>
</tr>
<tr class="row-8">
	<td class="column-1">100000000</td><td class="column-2">49.98435 </td><td class="column-3">50.01637 </td><td class="column-4">50.00000 </td><td class="column-5">50.00004 </td><td class="column-6">0.00004 </td><td class="column-7">49.99989 </td><td class="column-8">0.00011 </td><td class="column-9">0.00516 </td>
</tr>
<tr class="row-9">
	<td class="column-1">200000000</td><td class="column-2">49.98890</td><td class="column-3">50.01195 </td><td class="column-4">50.00000 </td><td class="column-5">49.99981 </td><td class="column-6">0.00019 </td><td class="column-7">49.99987 </td><td class="column-8">0.00013 </td><td class="column-9">0.00345 </td>
</tr>
</tbody>
</table>
<!-- #tablepress-12-no-2 from cache -->



<p>We can see that in this case, the iteration values are the same as for the instance of the coin toss, where a good value could be something between&nbsp;<strong>10M</strong>&nbsp;and&nbsp;100M&nbsp;if you need to have an error in the&nbsp;third decimal, between&nbsp;100k&nbsp;and&nbsp;1M&nbsp;for an error in the&nbsp;second decimal&nbsp;and between&nbsp;1k&nbsp;and&nbsp;10k&nbsp;for an error in the&nbsp;<strong>first decimal</strong>.</p>



<p>This test result shows that, either the complexity of the problem has no influence on the number of interactions or that both problems (coin toss and single die roll) have similar complexity levels.</p>



<p>Analyzing the execution times for both problems, it’s possible to see that they took about the same time. This also corroborates with the hypothesis that they have similar complexity levels.</p>



<h3 class="wp-block-heading" id="two-dice">TWO DICE</h3>



<p>To test the hypothesis that the complexity of the above problems were too close, and this was the reason for the interaction values to be close, I’ve decided to double the complexity of the die roll problem by rolling&nbsp;<strong>two</strong>&nbsp;dice instead of only&nbsp;<strong>one</strong>&nbsp;(it’s important to note that doubling the quantity of functions doesn’t always mean that the complexity order will double as well, as it depends on the&nbsp;Big-O Notation). The highest probability value for two dice is&nbsp;7, with&nbsp;a <strong>16,67%</strong>&nbsp;chance of occurrence.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-19" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">RollsTwoDice &lt;- <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(iterations)</span>
</span>{
  <span class="hljs-comment"># Creates a vector with the possible values of the die</span>
  <span class="hljs-keyword">die</span> = <span class="hljs-number">1</span>:<span class="hljs-number">6</span>
  result = <span class="hljs-number">0</span>
	
  <span class="hljs-comment"># Alocates the die roll results</span>
  first_roll = sample(<span class="hljs-keyword">die</span>,iterations,replace=T)
  second_roll = sample(<span class="hljs-keyword">die</span>,iterations,replace=T)

  <span class="hljs-comment"># Sum the vector values position-wise</span>
  result = first_roll + second_roll

  <span class="hljs-comment"># Sum up every instace where the dice landed on 7</span>
  result = sum(result == <span class="hljs-number">7</span>)

  <span class="hljs-comment"># Turns the value in a percentage of the dice rolls</span>
  result = (result/iterations) * <span class="hljs-number">100</span>

  <span class="hljs-keyword">return</span>(result)
}

<span class="hljs-comment"># Initiates variables</span>
result_vector = <span class="hljs-number">0</span>
time_vector = <span class="hljs-number">0</span>
control = <span class="hljs-number">0</span>

<span class="hljs-comment"># Controls the interaction quantity</span>
iterations = <span class="hljs-number">100</span>

<span class="hljs-comment"># Alocates the percentual of "7" results in a 100 size vector and the execution time in another</span>
<span class="hljs-keyword">while</span>(control != <span class="hljs-number">100</span>)
{
  start_time = Sys.time()
  result_vector = append(result_vector, RollsTwoDice(iterations)) 
  finish_time = Sys.time()

  time = finish_time - start_time
  time_vector = append(time_vector, time) 

  control = control + <span class="hljs-number">1</span>
}

<span class="hljs-comment"># Shows the percentual of "7"</span>
result_vector

<span class="hljs-comment"># Shows the execution times</span>
time_vector
</code></div><small class="shcb-language" id="shcb-language-19"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<p>Changing the values of the iterations and compiling the results, I’ve got the following table:</p>



<table id="tablepress-13" class="tablepress tablepress-id-13">
<thead>
<tr class="row-1">
	<th class="column-1">Iterations</th><th class="column-2">Min result</th><th class="column-3">Max result</th><th class="column-4">Expected result</th><th class="column-5">Average result</th><th class="column-6">Average result - Expected result</th><th class="column-7">Result's median</th><th class="column-8">Result's median - Expected</th><th class="column-9">result | Result's   Standard deviation</th>
</tr>
</thead>
<tbody class="row-hover">
<tr class="row-2">
	<td class="column-1"> 100</td><td class="column-2">6.00000</td><td class="column-3">28.00000</td><td class="column-4">16.66667</td><td class="column-5">16.58100</td><td class="column-6">-0.08567</td><td class="column-7">16.00000</td><td class="column-8">-0.66667</td><td class="column-9">3.64372</td>
</tr>
<tr class="row-3">
	<td class="column-1">1000</td><td class="column-2">13.20000</td><td class="column-3">20.40000</td><td class="column-4">16.66667</td><td class="column-5">16.68500</td><td class="column-6">0.01833</td><td class="column-7">16.60000</td><td class="column-8">-0.06667</td><td class="column-9">1.16949</td>
</tr>
<tr class="row-4">
	<td class="column-1">10000</td><td class="column-2">15.60000</td><td class="column-3">17.94000</td><td class="column-4">16.66667</td><td class="column-5">16.65962</td><td class="column-6">-0.00705</td><td class="column-7">16.67000</td><td class="column-8">0.00333</td><td class="column-9">0.38072</td>
</tr>
<tr class="row-5">
	<td class="column-1">100000</td><td class="column-2">16.22200</td><td class="column-3">17.06200</td><td class="column-4">16.66667</td><td class="column-5">16.66109</td><td class="column-6">-0.00557</td><td class="column-7">16.66500</td><td class="column-8">-0.00167</td><td class="column-9">0.11356</td>
</tr>
<tr class="row-6">
	<td class="column-1">1000000 </td><td class="column-2">16.54960</td><td class="column-3">16.54960</td><td class="column-4">16.66667</td><td class="column-5">16.66616</td><td class="column-6">-0.00050</td><td class="column-7">16.66790</td><td class="column-8">0.00123</td><td class="column-9">0.03650</td>
</tr>
<tr class="row-7">
	<td class="column-1">10000000</td><td class="column-2">16.63294</td><td class="column-3">16.70266</td><td class="column-4">16.66667</td><td class="column-5">16.66607</td><td class="column-6">-0.00060</td><td class="column-7">16.66577</td><td class="column-8">-0.00090</td><td class="column-9">0.01220</td>
</tr>
<tr class="row-8">
	<td class="column-1">100000000</td><td class="column-2">16.65592</td><td class="column-3">16.67948</td><td class="column-4">16.66667</td><td class="column-5">16.66670</td><td class="column-6">0.00004</td><td class="column-7">16.66679</td><td class="column-8">0.00012</td><td class="column-9">0.00372</td>
</tr>
<tr class="row-9">
	<td class="column-1">200000000</td><td class="column-2">16.65787</td><td class="column-3">16.67476</td><td class="column-4">16.66667</td><td class="column-5">16.66671</td><td class="column-6">0.00004</td><td class="column-7">16.66671</td><td class="column-8">0.00004</td><td class="column-9">0.00267</td>
</tr>
</tbody>
</table>
<!-- #tablepress-13 from cache -->



<p>Again we find the same interaction quantity for each error level. In the case of this problem it’s possible to identify that it was more complex since the execution for 200M took on average&nbsp;<strong>7.47 seconds longer</strong>&nbsp;when compared to the single die roll.</p>



<h3 class="wp-block-heading" id="five-dice">FIVE DICE</h3>



<p>The inference that I’ve built until this point is that the complexity of the problem influences very little in the iteration quantities, but to be sure of that, I ran one last test with 5 dice. The highest probability when rolling five dice is the values of&nbsp;<strong>17</strong>&nbsp;and&nbsp;<strong>18</strong>, with&nbsp;<strong>10.03%</strong>&nbsp;probability each.</p>



<p>Since this problem is a lot more complex than the others I’ve decided to run only 10 times each instead of 100.</p>


<pre class="wp-block-code" aria-describedby="shcb-language-20" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php">RollsFiveDice &lt;- <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(iterations)</span>
</span>{
  <span class="hljs-comment"># Creates a vector with the possible values of the die</span>
  dado = <span class="hljs-number">1</span>:<span class="hljs-number">6</span>
  result = <span class="hljs-number">0</span>
	
  <span class="hljs-comment"># Alocates the die roll results</span>
  first_roll = sample(dado,iterations,replace=T)
  second_roll = sample(dado,iterations,replace=T)
  terceira_rolagem = sample(dado,iterations,replace=T)
  quarta_rolagem = sample(dado,iterations,replace=T)
  quinta_rolagem = sample(dado,iterations,replace=T)

  <span class="hljs-comment"># Sum the vector values position-wise</span>
  result = first_roll + second_roll + terceira_rolagem + quarta_rolagem + quinta_rolagem

  <span class="hljs-comment"># Sum up every instace where the dice landed on 18</span>
  result = sum(result == <span class="hljs-number">18</span>)

  <span class="hljs-comment"># Turns the value in a percentage of the dice rolls</span>
  result = (result/iterations) * <span class="hljs-number">100</span>
	
  <span class="hljs-keyword">return</span>(result)
}

<span class="hljs-comment"># Initiates variables</span>
result_vector = <span class="hljs-number">0</span>
time_vector = <span class="hljs-number">0</span>
control = <span class="hljs-number">0</span>

<span class="hljs-comment"># Controls the interaction quantity</span>
iterations = <span class="hljs-number">10</span>

<span class="hljs-comment"># Alocates the percentual of "18" results in a 100 size vector and the execution time in another</span>
<span class="hljs-keyword">while</span>(control != <span class="hljs-number">100</span>)
{
  start_time = Sys.time()
  result_vector = append(result_vector, RollsFiveDice(iterations)) 
  finish_time = Sys.time()

  time = finish_time - start_time
  time_vector = append(time_vector, time) 

  control = control + <span class="hljs-number">1</span>
}

<span class="hljs-comment"># Shows the percentual of "18"</span>
result_vector

<span class="hljs-comment"># Shows the execution times</span>
time_vector
</code></div><small class="shcb-language" id="shcb-language-20"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<p>Changing the values of the iterations and compiling the results, I’ve got the following table:</p>



<table id="tablepress-14" class="tablepress tablepress-id-14">
<thead>
<tr class="row-1">
	<th class="column-1">Iterations</th><th class="column-2">Min result</th><th class="column-3">Max result</th><th class="column-4">Expected result</th><th class="column-5">Average result</th><th class="column-6">Average result - Expected result</th><th class="column-7">Result's median</th><th class="column-8">Result's median - Expected result</th><th class="column-9">Result's  Standard deviation</th>
</tr>
</thead>
<tbody class="row-hover">
<tr class="row-2">
	<td class="column-1"> 100</td><td class="column-2">5.00000</td><td class="column-3">31.00000</td><td class="column-4">16.66667</td><td class="column-5">16.37100</td><td class="column-6">-0.29567</td><td class="column-7">16.00000</td><td class="column-8">-0.66667</td><td class="column-9">3.77487</td>
</tr>
<tr class="row-3">
	<td class="column-1">1000</td><td class="column-2">13.40000</td><td class="column-3">21.80000</td><td class="column-4">16.66667</td><td class="column-5">16.64710</td><td class="column-6">-0.01957</td><td class="column-7">16.60000</td><td class="column-8">-0.06667</td><td class="column-9">1.18550</td>
</tr>
<tr class="row-4">
	<td class="column-1">10000</td><td class="column-2">15.33000</td><td class="column-3">17.77000</td><td class="column-4">16.66667</td><td class="column-5">16.68307</td><td class="column-6">0.01640</td><td class="column-7">16.68500</td><td class="column-8">0.01833</td><td class="column-9">0.38059</td>
</tr>
<tr class="row-5">
	<td class="column-1">100000</td><td class="column-2">16.23100</td><td class="column-3">17.06600</td><td class="column-4">16.66667</td><td class="column-5">16.66546</td><td class="column-6">-0.00120</td><td class="column-7">16.66800</td><td class="column-8">0.00133</td><td class="column-9">0.11597</td>
</tr>
<tr class="row-6">
	<td class="column-1">1000000 </td><td class="column-2">16.54450</td><td class="column-3">16.81170</td><td class="column-4">16.66667</td><td class="column-5">16.66657</td><td class="column-6">-0.00010</td><td class="column-7">16.66860</td><td class="column-8">0.00193</td><td class="column-9">0.03798</td>
</tr>
<tr class="row-7">
	<td class="column-1">10000000</td><td class="column-2">16.62888</td><td class="column-3">16.70282</td><td class="column-4">16.66667</td><td class="column-5">16.66683</td><td class="column-6"> 0.00016</td><td class="column-7">16.66705</td><td class="column-8">0.00038</td><td class="column-9">0.01155</td>
</tr>
<tr class="row-8">
	<td class="column-1">100000000</td><td class="column-2">16.65408</td><td class="column-3">16.67899</td><td class="column-4">16.66667</td><td class="column-5">16.66669</td><td class="column-6">0.00002</td><td class="column-7">16.66673</td><td class="column-8">0.00007</td><td class="column-9">0.00382</td>
</tr>
<tr class="row-9">
	<td class="column-1">200000000</td><td class="column-2">16.65881</td><td class="column-3">16.67455</td><td class="column-4">16.66667</td><td class="column-5">16.66675</td><td class="column-6">0.00009</td><td class="column-7">16.66682</td><td class="column-8">0.00015</td><td class="column-9">0.00258</td>
</tr>
</tbody>
</table>
<!-- #tablepress-14 from cache -->



<p>Once again we can see that the values for the iterations are the same as above. It’s possible to notice that this problem is clearly more complex, as it took&nbsp;<strong>35 seconds longer</strong>&nbsp;when compared to the roll of a single die.</p>



<h2 class="wp-block-heading" id="conclusion">CONCLUSION</h2>



<p>After running those tests, it’s possible to conclude that for the use on project management, a good iteration value would be somewhere between&nbsp;<strong>1k</strong>&nbsp;and&nbsp;<strong>100M</strong>, depending on the error level as shown below:</p>



<ul><li>Error in the first decimal: 1k to 10k</li><li>Error in the second decimal: 100k to 1M</li><li>Error in the third decimal: 10M to 100M</li></ul>



<p>The value that I’ve been using is 3M, for stakeholder reports. However, when I’m running the method for my own analysis, I use a lower value, somewhere between 250k and 750k.</p>



<p>How about you? Have you tried to run Monte Carlo Simulations? How many iterations are you using? Tell us in the comment section below or on Twitter @plataformatec.</p><p>The post <a href="/2019/10/monte-carlo-in-practice-finding-the-ideal-iteration-value/">Monte Carlo in Practice: Finding the ideal iteration value</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Kubernetes and the Erlang VM: orchestration on the large and the small</title>
		<link>/2019/10/kubernetes-and-the-erlang-vm-orchestration-on-the-large-and-the-small/</link>
		
		<dc:creator><![CDATA[José Valim]]></dc:creator>
		<pubDate>Tue, 01 Oct 2019 17:05:27 +0000</pubDate>
				<category><![CDATA[English]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[elixir]]></category>
		<category><![CDATA[kubernetes]]></category>
		<guid isPermaLink="false">/?p=9398</guid>

					<description><![CDATA[<p>If you look at the features listed by Kubernetes (K8s) and compare it to languages that run on the Erlang VM, such as Erlang and Elixir, the impression is that they share many keywords. This sharing often leads to confusion. Do they provide distinct behaviors? Do they overlap? For instance, is there any purpose to Elixir's fault tolerance if Kubernetes also provides self-healing?</p>
<p>The post <a href="/2019/10/kubernetes-and-the-erlang-vm-orchestration-on-the-large-and-the-small/">Kubernetes and the Erlang VM: orchestration on the large and the small</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>If you look at the features listed by Kubernetes (K8s) and compare it to languages that run on the Erlang VM, such as Erlang and Elixir, the impression is that they share many keywords, such as &#8220;self-healing&#8221;, &#8220;horizontal scaling&#8221;, &#8220;distribution&#8221;, etc.</p>



<p>This sharing often leads to confusion. Do they provide distinct behaviors? Do they overlap? For instance, is there any purpose to Elixir&#8217;s fault tolerance if Kubernetes also provides self-healing?</p>



<p>In this article, I will go over many of these topics and show how they are mostly complementary and discuss the rare case where they do overlap.</p>



<h2 class="wp-block-heading">Self-healing</h2>



<p>Kubernetes automatically restarts or replaces containers that fail. It can also kill containers that don’t respond to your user-defined health check. Similarly, in Erlang and Elixir, you structure your code with the help of supervisors, which automatically restart parts of your application in case of failures.</p>



<p>Kubernetes provides fault-tolerance within the cluster, Erlang/Elixir provide it within your application. To understand this better, let&#8217;s take an application that has to talk to a database (or any other external system). Most languages handle this by keeping a pool of database connections.</p>



<p>If your database goes offline, because of a bad configuration or a hardware failure, both the database and the Erlang/Elixir systems will respond negatively to health checks, which would cause Kubernetes to act and potentially relocate them. This is a node-wide failure and Kubernetes got your back.</p>



<p>However, what happens when part of your connections to the database are sporadically failing? For example, imagine your system is under load and you suddenly started running into connection limits, such as MySQL&#8217;s prepared statement limit. This failure likely won&#8217;t cause any health check to fail but your code will fail whenever one of its many connections reach said limit. Can you reason about this error today in your applications? Can you confidently say that the faulty connection will be dropped? Will another connection be started in place of the faulty one? Can you comfortably say this error won&#8217;t cascade in the application bringing the remaining of the connection pool down?</p>



<p>Erlang/Elixir&#8217;s abstractions for fault tolerance allow you to reason about those questions at the language level. It provides a mechanism for you to reason about connections, resources, in-memory state, background workers, etc. You can explicitly say how they are started, how they are shut down, and what should happen when things go wrong. These features can also be extremely helpful in face of partial failures. For example, imagine you have a news website and the live stock ticker is down. Should the website continue running, potentially serving stale data, or should everything crash down? The mental model provided by Erlang/Elixir allows us to reason about these scenarios. And of course, you can always let failures bubble up after a few retries, or even immediately, so it becomes a node-wide failure to be handled by K8s.</p>



<p>In a nutshell, Kubernetes and containers provide isolation and an ability to restart individual nodes when they fail, but it is not a replacement for isolation and fault handling within your own software, regardless of your language of choice. Using K8s and Erlang/Elixir allow you to apply similar self-healing and fault-tolerance principles in the large (cluster) and in the small (language/instance).</p>



<h2 class="wp-block-heading">Service discovery and Distributed Erlang</h2>



<p>The Erlang VM also provides Distributed Erlang, which allows you to exchange messages between different instances running on the same or different machines. In Elixir, this is as easy as:</p>


<pre class="wp-block-code" aria-describedby="shcb-language-21" data-shcb-language-name="PHP" data-shcb-language-slug="php"><div><code class="hljs language-php"><span class="hljs-keyword">for</span> node &lt;- Node.<span class="hljs-keyword">list</span>() <span class="hljs-keyword">do</span>
  <span class="hljs-comment"># Send :hello_world message to named process "MyProcess" in each node</span>
  send {node, MyProcess}, :hello_world
end</code></div><small class="shcb-language" id="shcb-language-21"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">PHP</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">php</span><span class="shcb-language__paren">)</span></small></pre>


<p>When running in distributed mode (which is not a requirement in any way and you need to explicitly enable it), the Erlang VM will automatically serialize and deserialize the data as well as make sure the connection between nodes is alive, but it does not provide any node discovery. It is the programmer responsibility to say exactly where each node is located and connect the nodes together.</p>



<p>Luckily, Kubernetes provides service discovery out of the box. This means that, K8s allows us to fully automate the node discovery, which would otherwise be manual and error prone. Libraries like <a href="https://github.com/bitwalker/libcluster" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">libcluster</a> do exactly that (and rolling your own wouldn&#8217;t be complicated either). This is another great example of where Kubernetes and the Erlang VM complement each other!</p>



<p>However, you may still be wondering, is there a benefit to running Distributed Erlang when Kubernetes&#8217; Service Discovery makes it relatively easy to have systems communicating with each other? Especially when considering RPC protocols such as Thrift, gRPC, and others?</p>



<p>When we are talking about different languages and different systems communicating with each other, picking one of the existing RPC mechanisms is likely the best choice, and they will also work fine with Erlang/Elixir. The scenario where the Erlang VM really shines, in my opinion, is for building homogeneous systems, i.e. when you have multiple deployments of the same container and they exchange information. For example, imagine you are building a real-time application when you want to track which users are in the same chat room, or in the same city block, or in the same mountain track. As users connect and disconnect and as nodes are brought up and down, you could somehow update the database or communicate via a complex RPC mechanism, while carefully watching the cluster for topology changes.</p>



<p>With the Erlang VM, you can just broadcast or exchange this information directly, without having to worry about serialization protocols, connection management, etc, as everything is provided by the VM. All without external dependencies. This is one of the many features that <a href="https://phoenixframework.org/" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">makes Phoenix a breeze to build distributed web-realtime systems</a>.</p>



<h2 class="wp-block-heading">Automated rollouts vs Hot code swapping</h2>



<p>When it comes to deployment, Kubernetes automatically rolls out changes to your application or its configuration, avoiding changing all instances at the same time. At the same time, the Erlang VM supports hot code swapping, which allows you to change the code that is running in production within a single instance without shutting said instance down.</p>



<p>Those two deployments techniques are obviously conflicting. In fact, hot code swapping does not go well in general with the whole idea of immutable containers. Does it mean that Kubernetes and the Erlang VM are a poor fit? Not really, because <strong>you don&#8217;t have to use hot code swapping</strong>. In fact, most people do not. Most Elixir applications are deployed using blue-green, canary, or similar techniques.</p>



<p>The truth about hot code swapping is that it is actually complicated to pull off in practice. Let&#8217;s use the database as an example once again. When you are deploying a new version of your software, whenever you update your database, you should never perform destructive changes. For example, if you want to rename a column, you have to add a new column, migrate the data over, and then remove the column. If you just rename the column, then you will have failures whenever doing rollouts, because you will have two versions of the software running at the same (one using the old column and the other using the new one). In hot code swapping, we have precisely the same issue, except it applies to all states inside your application. Companies that use hot code swapping often report they spend as much time developing the software as testing the upgrades themselves.</p>



<p>Of course, it doesn&#8217;t mean hot code swapping is useless. The Erlang VM development is mostly driven by business needs and there was a legitimate need for hot code swapping. In particular, when building telephone switches, there is never an appropriate moment to shut down an instance for updates, because at any given time a system is full of long running connections, perhaps days or even weeks. So being able to upgrade a live system is extremely helpful. If you have a similar need, then hot code swapping may be an option. Another option is to <a href="https://www.youtube.com/watch?v=5LRDICEETRE" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">have smarter clients and migrate client connections between nodes when deploying</a>.</p>



<p>Hot code swapping can also be used under other circumstances, such as during development to provide live code loading, without a need to restart your server, or to replace smaller components in production that don&#8217;t require replacing the whole instance.</p>



<h2 class="wp-block-heading">Configuration management and Configuration providers</h2>



<p>Another feature provided by both Elixir and Kubernetes is configuration management. However, as seen before, they work at very distinct levels. While Elixir provides a <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://hexdocs.pm/elixir/Config.html" target="_blank">unified API for configuring applications</a>, it is relatively low-level. In a production system, you often want both configuration and secrets to be managed by higher level tools, such as the ones provided by Kubernetes. Luckily, you can incorporate said configuration tools into your deployment workflow with the help of <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://hexdocs.pm/elixir/Config.Provider.html" target="_blank">Configuration Providers</a>. This functionality is part of Elixir releases, which were <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://elixir-lang.org/blog/2019/06/24/elixir-v1-9-0-released/" target="_blank">officially made part of the Elixir language in version 1.9</a>.</p>



<h2 class="wp-block-heading">Stay alert: pod resources</h2>



<p>When provisioning Erlang and Elixir with Kubernetes, it is important to stay alert to one particular configuration: pod resources.</p>



<p>When using other technologies, it is common practice to break a large node into a bunch of small pods/containers. For example, if you have a node with 8 cores, you could allocate half of each CPU to a pod and split the memory equally between them, on a total of 16 pods.</p>



<p>This approach makes sense in many technologies that cannot exploit CPU and I/O concurrency simultaneously. However, the Erlang VM excels at managing system resources and your system will most likely be more efficient if you assign large pods to your Erlang and Elixir applications instead of breaking it apart into a bunch of small ones.</p>



<p> If the Erlang VM is sharing a machine with other applications you may want to consider <a href="https://stressgrid.com/blog/beam_cpu_usage/">reducing busy waiting</a>. By doing so, the VM will optimize for lower CPU usage, making it a better neighbor, but with slightly higher latencies.</p>



<h2 class="wp-block-heading">Summing up</h2>



<p>Kubernetes and the Erlang VM work at distinct levels. Kubernetes orchestrates within a cluster, the Erlang VM orchestrates at the language level within an instance. Fred Hebert summed up this distinction well in a tweet:</p>



<blockquote class="wp-block-quote"><p>Still seeing bad comparisons between kubernetes and <a href="https://twitter.com/hashtag/Erlang?src=hash&amp;ref_src=twsrc%5Etfw" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">#Erlang</a>/OTP. K8s is to OTP what region failover is to k8s. They operate on different layers of abstraction and impact distinct components.<br><br>OTP allows handling partial failures WITHIN an instance, something k8s can&#8217;t help with.— Fred Hebert (@mononcqc) <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://twitter.com/mononcqc/status/1122872187894018048?ref_src=twsrc%5Etfw" target="_blank">April 29, 2019</a></p></blockquote>



<p>If you are using Erlang/Elixir and you wonder how Kubernetes applies compared to other languages, you can use Kubernetes for the Erlang VM as you would with any other technology. Given that Erlang/Elixir software can typically scale both horizontally and vertically, it gives you many options on how you want to allocate your resources within K8s.</p>



<p>On other areas, Kubernetes and the Erlang VM can nicely complement each other, such as using K8s Service Discovery to connect Erlang VM instances. Of course, Distributed Erlang is not a requirement and Erlang/Elixir are great languages even for stateless apps, thanks to its scalability and reliability.</p>



<p>If you are one of the few who really need hot code swapping in production, then the Erlang VM may be one of the best platforms to do so, but keep in mind you will be straying away from the common path in both technologies.</p>



<p>Finally, if you appreciate Kubernetes and its concepts, you may enjoy working with Erlang and Elixir, as they will give you an opportunity to apply similar idioms on the small and on the large.</p>



<p><em>Thanks to Fernando Tapia Rico, Fred Hebert, George Guimarães, Tristan Sloughter, and Wojtek Mach for reviewing this article.</em></p><p>The post <a href="/2019/10/kubernetes-and-the-erlang-vm-orchestration-on-the-large-and-the-small/">Kubernetes and the Erlang VM: orchestration on the large and the small</a> first appeared on <a href="/">Plataformatec Blog</a>.</p>]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
