<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Caffeinated fumblings</title>
    <description>Stray thoughts from Erik Mejer Hansen. Mostly on subjects relating to programming and being a developer, a supporter and trying to not to dent the world too much.
</description>
    <link>http://blog.mejer-hansen.dk/</link>
    <atom:link href="http://blog.mejer-hansen.dk/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Wed, 17 Aug 2022 13:17:08 +0000</pubDate>
    <lastBuildDate>Wed, 17 Aug 2022 13:17:08 +0000</lastBuildDate>
    <generator>Jekyll v3.9.2</generator>
    
      <item>
        <title>Using visualizations to help understanding</title>
        <description>&lt;p&gt;I’ve recently started (re)reading “Principles of Product Development Flow” by Donald G. Reinertsen.
I’ve read it before but it did not stick.
I forgot most of what it had to say and I’m not sure I actually understood much of it the last time around.&lt;/p&gt;

&lt;p&gt;A tactic I’m trying out to better retain what I read is to look out for opportunities to create visualizations.&lt;/p&gt;

&lt;p&gt;For me visualizations are powerful tools to help guide understanding and I’ve been trying to use utilize that power as I read.&lt;/p&gt;

&lt;p&gt;One section of “Principles of Product Development Flow” talks about random processes and uses the following as an example:
Image you flip a coin while keeping a running tally.
If you get heads you add one from your tally and if get tails you subtract one.&lt;/p&gt;

&lt;p&gt;Reinertsen then continues:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;In general, even numerate people (such as engineers and scientists) have limited intuition for the behavior of random processes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sounds like a good opportunity for a visualization!&lt;/p&gt;

&lt;p&gt;Lets draw the running tally of the coin flips as we run trough the random process.
The length of the process shown below 685.
Once a process has run trough its 685 steps we start a new process and begin drawing it on top of the old result.&lt;/p&gt;

&lt;div id=&quot;fig1&quot;&gt;
    &lt;script type=&quot;module&quot; src=&quot;https://erikmejerhansen.github.io/coin-flips/index.b76fa335.js&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;Sure enough!
That graph did not match my intuition.
My expectation was that the graph would continuously hover around the zero line.
But it doesn’t!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Boo For my intuition!
Hoorah for visualizations!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The fun with random process does not stop there though, because Reinertsen continues:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Although the most likely value of the cumulative sum is zero, this value becomes less likely with time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sounds like it’s time for histograms!
My idea was to run a lot of the coin flip random processes and plot the frequency of results.&lt;/p&gt;

&lt;p&gt;For each histogram below a random process (of the length indicated in the captions) is run for every frame, the result saved and the histogram updated.&lt;/p&gt;

&lt;p&gt;You should see the distribution slowly settle down and it becomes visually obvious that the longer the sequence the lower the likelihood of hitting zero - even though zero is still the most likely result.
The distribution flattens out.&lt;/p&gt;

&lt;div id=&quot;fig2&quot;&gt;
    &lt;script type=&quot;module&quot; src=&quot;https://erikmejerhansen.github.io/coin-flips/index.2cbf189c.js&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;h4 id=&quot;why-i-think-this-helps&quot;&gt;Why I Think This Helps&lt;/h4&gt;

&lt;p&gt;Creating a visualization offers me an opportunity to work trough the text and understand it well enough to turn it into a visualization.
 I can’t code visualizations for what I don’t understand.&lt;/p&gt;

&lt;p&gt;And, I’m hoping, that will help me better retain what I read.&lt;/p&gt;
</description>
        <pubDate>Wed, 17 Aug 2022 00:00:00 +0000</pubDate>
        <link>http://blog.mejer-hansen.dk/2022/08/17/Ssing-p5-sketches-to-guide-understanding.html</link>
        <guid isPermaLink="true">http://blog.mejer-hansen.dk/2022/08/17/Ssing-p5-sketches-to-guide-understanding.html</guid>
        
        
      </item>
    
      <item>
        <title>Are we pair programming too much?</title>
        <description>&lt;p&gt;The team I’m part of had been working towards making pair programming the default mode of work, when one of the team members asked: “Are we pair programming too much?”.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“It’s at least twice as fast as when everyone works on their own”&lt;/em&gt; is something I’ve heard, it’s something I’ve said and it’s something I’ve always just sort of taken for solid fact. We couldn’t be doing too much pair programming if it’s the most efficient way of working.&lt;/p&gt;

&lt;p&gt;But it is though? The answer may be that it’s nowhere as simple as that. In a review of 18 studies&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; the conclusion was:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Our meta-analysis suggest that pair programming is not uniformly &lt;strong&gt;beneficial or effective&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The review of pair programing looked at the effectiveness of pair programming on:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Duration&lt;/strong&gt;: The calendar time it takes to complete a task&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Effort&lt;/strong&gt;: The joint effort used to complete a task&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Quality&lt;/strong&gt;: The quality of the work, by looking at passed tests, grades and other metrics&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The results of the review can be summarized as: Pair programming gives you a a small improvement on quality and a medium improvement in duration, but you pay for those with a medium negative effect of effort.&lt;/p&gt;

&lt;p&gt;The negative effect on effort means that we less back from pair programming than if we just let everyone work on their own.&lt;/p&gt;

&lt;p&gt;Seems like if we take the research at its word then perhaps, we are indeed pair programming too much? But what’s going on and is there something we can do to improve the situation? Or at least supply some guidance on when pair programming is likely to be the most effective?&lt;/p&gt;

&lt;p&gt;Part of the reason for the results and a potential source of guidance may be found in the phenomenon of social loafing.&lt;/p&gt;

&lt;h2 id=&quot;social-loafing&quot;&gt;Social Loafing&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Loaf: to avoid activity, especially work&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Social loafing is the phenomenon that people tend to exert less effort when working collaboratively than they would have if they had worked on the same task alone.&lt;/p&gt;

&lt;p&gt;The classical example is that of pulling on a rope to lift a weight - you might expect two people to be able to pull twice as hard and three people to lift three times as hard.&lt;/p&gt;

&lt;p&gt;That turns out not to be the case: &lt;strong&gt;You get less joint effort than you’d expect from simple addition of what the individuals are capable on their own.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s worth noting that this is separate from any coordination loss you might expect.&lt;/p&gt;

&lt;h3 id=&quot;size-of-the-effect&quot;&gt;Size of the Effect&lt;/h3&gt;

&lt;p&gt;How big of an effect is social loafing? “Social Loafing: A Meta-Analytic Review and Theoretical Integration”&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; on which I’m leaning heavily on terms it as:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;within the middle range of effects in the domain of social behavior&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More formally the review found an effect size of 0.44 expressed in terms of &lt;a href=&quot;https://www.statisticshowto.com/cohens-d/&quot;&gt;Cohen’s D&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m going to tread very carefully here because I’m by no means a statistician, but Cohen’s D puts a value on how big an effect is - more specifically how big of a difference there is between the mean values of two groups. In this case the two groups are the group working alone and the group working together. A Cohen’s D value of 1 means that the groups differ by 1 standard deviation.&lt;/p&gt;

&lt;p&gt;This does not at once make 0.44 more intuitively understandable but an effect size 0.44 falls between a “small” and a “medium” size as per the rule of thumb interpretation of effect sizes suggested by Cohen. Medium being “probably big enough to be noticed by the naked eye”.&lt;/p&gt;

&lt;p&gt;I’ll go out on a limb and summarize that to mean: &lt;strong&gt;The effect is there, and it is large enough for us to care about.&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;but-i-dont-loaf&quot;&gt;But I don’t loaf!&lt;/h3&gt;

&lt;p&gt;About now you might have the same objection that I had: “I definitely don’t loaf!”.&lt;/p&gt;

&lt;p&gt;Well, I’m sorry to say but you probably do - it’s just that you may not be aware of it. In experiments where participants were asked to self-report on their effort, they tended to report a similar level of effort as when working alone when they in fact had not.&lt;/p&gt;

&lt;p&gt;So, we’re either unaware or unwilling to admit that we loaf.&lt;/p&gt;

&lt;h3 id=&quot;but-programming-is-different&quot;&gt;But Programming is Different!&lt;/h3&gt;

&lt;p&gt;The effect has also been proven to be robust across a range of activities from the simple physical task of pulling on a robe, to shouting, brainstorming, to maze solving, to evaluation of information, to typing and pushing buttons.&lt;/p&gt;

&lt;p&gt;I think we would be misleading ourselves if we think programming to be except from the effects of social loafing.&lt;/p&gt;

&lt;h3 id=&quot;what-affects-social-loafing&quot;&gt;What Affects Social Loafing?&lt;/h3&gt;

&lt;p&gt;So social loafing is a thing and most if not all of us do it. Now what?&lt;/p&gt;

&lt;p&gt;Social loafing does not occur at an equal strength for all tasks nor does it under all circumstances but instead seems to be affected by several factors.&lt;/p&gt;

&lt;p&gt;Can knowledge of these factors help us in deciding when to pair program. I think they can or at least some of them can be helpful in guiding us when we build teams and try to steer our engineering culture.&lt;/p&gt;

&lt;p&gt;I’ll skip the discussion of factors related to gender and ethnicity (women tend loaf less and so does people from eastern cultures). I’ll also skip as factors that I think are detrimental to building great teams and cultures (for example we loaf less when we think our coworkers will do a bad job). Instead, I’ll focus on the factors I believe gel well with build great teams.&lt;/p&gt;

&lt;p&gt;Go check out the &lt;a href=&quot;https://www.researchgate.net/publication/209410290_Social_Loafing_A_Meta-Analytic_Review_and_Theoretical_Integration&quot;&gt;article&lt;/a&gt; if your curious to know all the factors.&lt;/p&gt;

&lt;h4 id=&quot;task-valance&quot;&gt;Task Valance&lt;/h4&gt;

&lt;p&gt;We loaf less when we feel we’re working on tasks that are intrinsically important.
This shouldn’t be much of a surprise.&lt;/p&gt;

&lt;p&gt;What may come as a surprise is that it is likely that we are sensitive to how others feel and talk about a task.&lt;/p&gt;

&lt;p&gt;Therefore: Don’t talk down the importance of tasks. Not only are you likely to bring some you own performance, but you’ll likely bring down the performance of those working with you.&lt;/p&gt;

&lt;p&gt;While the reverse effect also exists (that is you can talk a task up and get increased performance) I’d be hesitant to use it. Instead, I’d save pair programming to talks that are actually interesting and important.&lt;/p&gt;

&lt;h4 id=&quot;task-complexity&quot;&gt;Task complexity&lt;/h4&gt;

&lt;p&gt;The complexity of the task at hand plays a role on social loafing. We loaf more on simple tasks than on complex tasks.&lt;/p&gt;

&lt;p&gt;On complex tasks the effect of social loafing may even be reversed, and individuals put more effort into collaborative working than they would working on their own.&lt;/p&gt;

&lt;h4 id=&quot;uniqueness-of-individual-input&quot;&gt;Uniqueness of Individual Input&lt;/h4&gt;

&lt;p&gt;We loaf less when we feel we bring something unique to the table.&lt;/p&gt;

&lt;p&gt;While unsurprising it is still worth keeping in mind, especially when doing novice-expert pairs where the novice might feel that their input is redundant.&lt;/p&gt;

&lt;p&gt;Stressing that learning and gaining familiarity with the codebase (and not just task solving) is the focus in novice-expert pairs might help keep the motivation up in that specific context.&lt;/p&gt;

&lt;h4 id=&quot;team-cohesiveness-and-identity&quot;&gt;Team Cohesiveness and Identity&lt;/h4&gt;

&lt;p&gt;Team cohesiveness and and feeling of identity plays a strong role in social loafing.&lt;/p&gt;

&lt;p&gt;This is probably the best news of this article: Strong teams may be able to more or less completely eliminate the effect of social loafing.&lt;/p&gt;

&lt;h4 id=&quot;group-size&quot;&gt;Group Size&lt;/h4&gt;

&lt;p&gt;Social loafing increases with group size. The bigger the group the larger the effect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Take away:&lt;/strong&gt; Mob sessions are at a higher risk of social loafing, so reserve them for situations where the other factors play in your favor.&lt;/p&gt;

&lt;h2 id=&quot;closing-thoughts&quot;&gt;Closing thoughts&lt;/h2&gt;

&lt;p&gt;The next time someone asks me about the reasonability of doing pair programming I think I’ll change may answer from “It’s at least twice as fast” to:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“I believe that pair programming is a worthwhile investment in knowledge sharing, team building and learning - but for some tasks it will be an investment”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I still strongly believe that pair programming is worth the investment, but I also believe that we should be honest about it being an investment.&lt;/p&gt;

&lt;p&gt;We invest effort and get back knowledge sharing that help reduce the risk of knowledge silos.&lt;/p&gt;

&lt;p&gt;We invest effort and (when it works well) we help build a more cohesive team.&lt;/p&gt;

&lt;p&gt;We invest effort and increase learning.&lt;/p&gt;

&lt;p&gt;But a silver bullet it is not, and it comes with its own set of constraints. Knowing the factors that affect social loafing can help you make a conscious decision on when to do pair programming and get more out of the pair programming you do.&lt;/p&gt;

&lt;h3 id=&quot;key-takeaways&quot;&gt;Key Takeaways&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Social loafing scales with group size: Be especially mindful of the effect when doing mob programming&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Strong team cohesiveness is the strongest factor affecting social loafing&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Focus on the complex tasks: Quality improves with pair programming on complex tasks and complexity affects social loafing&lt;/p&gt;

  &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.researchgate.net/publication/222408325_The_effectiveness_of_pair_programming_A_meta-analysis&quot;&gt;The effectiveness of pair programming: A meta-analysis&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.researchgate.net/publication/209410290_Social_Loafing_A_Meta-Analytic_Review_and_Theoretical_Integration&quot;&gt;Social Loafing: A Meta-Analytic Review and Theoretical Integration&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 08 Aug 2021 21:00:00 +0000</pubDate>
        <link>http://blog.mejer-hansen.dk/2021/08/08/are-we-pair-programming-too-much.html</link>
        <guid isPermaLink="true">http://blog.mejer-hansen.dk/2021/08/08/are-we-pair-programming-too-much.html</guid>
        
        
      </item>
    
      <item>
        <title>Materiale lavet til Coding Pirates Horsens [In Danish]</title>
        <description>&lt;p&gt;Undervisning er svært, virkeligt svært. Det har været min primære erfaring efter knap to sæsoner hos Coding Pirates Horsens.&lt;/p&gt;

&lt;h2 id=&quot;minecraft&quot;&gt;Minecraft&lt;/h2&gt;
&lt;p&gt;Første forsøg var at skrive et hæfte om at lave mods til Minecraft via JavaScript. Tanken var at ungerne kunne læse lidt, løse opgaver, få hjælp når det var svært.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/minecraft/minecraft_eksploderende_kyllinger.pdf&quot;&gt;&lt;img src=&quot;/assets/minecraft_cover.png&quot; alt=&quot;Cover af Eksploderende kyllinger&quot; class=&quot;center-image
&quot; style=&quot;height: 30em&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Forløbet skulle vare fire uger, og så skulle de videre til næste forløb. Det fungerede tåleligt, specielt delen hvor “programmeringen” foregik direkte i Minecraft.&lt;/p&gt;

&lt;p&gt;Så kom sæson to. Nu skulle der kød på så fortsætterne følte de kom fremad. De skulle lave et Battle Royale mod i Minecraft. Dele af forløbet gik godt; Det var sjovt at lave tryllestave (eller fisk) der skød med ildkugler og fik modstanderen til at flyve op i luften.
Men forløbet mindede om klassisk klasserumsundervisning, og det har ungerne allerede haft rigeligt af når de møder op klokken fem på en varm eftermiddag.&lt;/p&gt;

&lt;p&gt;Forløbet var for svært og de begyndte at kede sig. Det skriftlige element kom i vejen. Det er svært at få skrevet et for-loop rigtigt, der går kludder i parenteserne og fejlbeskederne er uforståelige. 
Der må prøves noget nyt.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/minecraft/minecraft_eksploderende_kyllinger.pdf&quot;&gt; Hæftet kan i øvrigt ses her.&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;flipped-classroom-og-gamemaker&quot;&gt;Flipped Classroom og GameMaker&lt;/h2&gt;

&lt;p&gt;Det nye forsøg er inspireret af &lt;a href=&quot;https://en.wikipedia.org/wiki/Flipped_classroom&quot;&gt;Flipped Classroom&lt;/a&gt;. 
Der er skiftet til GameMaker. Bogen er smidt ud til fordel for små YouTube videoer. Det er nemmere at gå til, man kommer hurtigere frem og man kan fokusere på andre ting end programmering. Man kan lege med graffik, lyd, level-design og masser af andre ting. Og med GameMakers Drag-and-drop programmering fjernes en stor del af det skriftlige element der kom i vejen for Minecraft forløbet.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gfo2_uT1hYM&quot;&gt;&lt;img src=&quot;/assets/gm_1.png&quot; alt=&quot; I gang med GameMaker: Episode #1 &quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=4QprKktDT2M&quot;&gt;&lt;img src=&quot;/assets/gm_2.png&quot; alt=&quot; I gang med GameMaker: Episode #2 &quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=3A1LVO1yWCo&quot;&gt;&lt;img src=&quot;/assets/gm_3.png&quot; alt=&quot; I gang med GameMaker: Episode #3 &quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=XmmM4mX68ps&quot;&gt;&lt;img src=&quot;/assets/gm_4.png&quot; alt=&quot; I gang med GameMaker: Episode #4 &quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=fWYFhfZRyuE&quot;&gt;&lt;img src=&quot;/assets/gm_5.png&quot; alt=&quot; I gang med GameMaker: Episode #5 &quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 16 May 2017 15:00:00 +0000</pubDate>
        <link>http://blog.mejer-hansen.dk/2017/05/16/Materiale-til-coding-pirates-horsens.html</link>
        <guid isPermaLink="true">http://blog.mejer-hansen.dk/2017/05/16/Materiale-til-coding-pirates-horsens.html</guid>
        
        
      </item>
    
      <item>
        <title>Adding a Elm compilation to you Mix project</title>
        <description>&lt;p&gt;We’ve been using cowboy for some time at work for writing small REST-endpoints and lately &lt;a href=&quot;http://elm-lang.org&quot;&gt; Elm &lt;/a&gt; as been added to the mix to provide front-ends for those endpoints.&lt;/p&gt;

&lt;p&gt;At the beginning the work flow was to compile the Elm assets, copy the result to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;priv/&lt;/code&gt; in our cowboy projects and let cowboy serve them from there. That work flow feelt a bit clunky. If you made changes to both the cowboy handlers and the Elm code you would have to run both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;elm make&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix compile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To make that work flow a bit more smooth we have integrated the Elm compile cycle into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix compile&lt;/code&gt;. You can see the end result here: &lt;a href=&quot;https://hex.pm/packages/elm_compile&quot;&gt;elm-compile&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you’re just looking an easy way to integrate Elm into your mix projects just stop reading now and follow the link above. If on the other hand you’re interested in how to add external compilers to a mix project read on.&lt;/p&gt;

&lt;h2 id=&quot;two-approaches&quot;&gt;Two approaches&lt;/h2&gt;
&lt;p&gt;There are two approaches to adding Elm compilation to your Mix project: Override &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix compile&lt;/code&gt; with an alias or add Elm compilation to the list of compilers used by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix compile&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;an-aside-on-writing-your-own-mix-tasks&quot;&gt;An aside on writing your own Mix tasks&lt;/h3&gt;
&lt;p&gt;Both approaches will require us to write our own Mix tasks. Luckily thats easy.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A Mix task can be defined by simply using Mix.Task in a module starting with Mix.Tasks. and defining the run/1 function:
– &lt;a href=&quot;https://hexdocs.pm/mix/Mix.Task.html&quot;&gt;Mix.Task behaviour docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It basically boils down to createing a module in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mix.Task&lt;/code&gt; namespace, adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;use Mix.Task&lt;/code&gt; and implementing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run(args)&lt;/code&gt; as required by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mix.Task&lt;/code&gt; behaviour. You can find an example &lt;a href=&quot;https://github.com/ErikMejerHansen/elm_compile/blob/master/lib/mix/task/elm_compile.ex&quot;&gt; here &lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;using-aliases&quot;&gt;Using aliases&lt;/h2&gt;
&lt;p&gt;If you’ve already encountered Mix aliases if you’ve ever created a &lt;a href=&quot;http://www.phoenixframework.org/&quot;&gt;Phoenix&lt;/a&gt;. If you look at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix.exs&lt;/code&gt; file in a Phoenix project you’ll see the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.....&lt;/span&gt;
     &lt;span class=&quot;ss&quot;&gt;version:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.....&lt;/span&gt;
     &lt;span class=&quot;ss&quot;&gt;elixir:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.....&lt;/span&gt;
     &lt;span class=&quot;ss&quot;&gt;elixirc_paths:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.....&lt;/span&gt;
     &lt;span class=&quot;ss&quot;&gt;aliases:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aliases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
     &lt;span class=&quot;ss&quot;&gt;deps:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aliases&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ecto.setup&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ecto.create&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ecto.migrate&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;run priv/repo/seeds.exs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
     &lt;span class=&quot;s2&quot;&gt;&quot;ecto.reset&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ecto.drop&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ecto.setup&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
     &lt;span class=&quot;s2&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ecto.create --quiet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ecto.migrate&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here they are using aliases to create convenience tasks like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ecto.setup&lt;/code&gt; that creates, migrate and seeds the database.&lt;/p&gt;

&lt;p&gt;But you can also use aliases to &lt;em&gt;override existing&lt;/em&gt; Mix tasks. So given that we have created a Mix task in the ‘Mix.Tasks.Compile.Elm’ module you could create the following alias:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aliases&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;compile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;compile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;compile.elm&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We are in essence telling mix to first run its normal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compile&lt;/code&gt; and afterwards run the Elm compile task. Mix aliases are awesome and can be really helpful in smoothing out your work flow. But overriding the compile task is perhaps not the best use of aliases.&lt;/p&gt;

&lt;h2 id=&quot;adding-a-compiler&quot;&gt;Adding a compiler&lt;/h2&gt;
&lt;p&gt;The other alternative is to place you task in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mix.Tasks.Compile.Elm&lt;/code&gt; namespace and then adding it to the list of Mix compilers.&lt;/p&gt;

&lt;p&gt;Again: Take a look at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix.exs&lt;/code&gt; file from a Phoenix project. Under the project definition you’ll spot the following: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compilers: [:phoenix, :gettext] ++ Mix.compilers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;They are adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:phoenix&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:gettext&lt;/code&gt; to the compilers run by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix compile&lt;/code&gt;. Modify that to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compilers: Mix.compilers ++ [:elm]&lt;/code&gt; and you’re good to go.&lt;/p&gt;
</description>
        <pubDate>Wed, 22 Mar 2017 20:00:00 +0000</pubDate>
        <link>http://blog.mejer-hansen.dk/2017/03/22/Adding-a-compiler-to-your-mix-project.html</link>
        <guid isPermaLink="true">http://blog.mejer-hansen.dk/2017/03/22/Adding-a-compiler-to-your-mix-project.html</guid>
        
        
      </item>
    
      <item>
        <title>Building your own GenServer</title>
        <description>&lt;p&gt;Sometimes it’s a good learning experience to try and reimplement some of the functionality that a standard library provides.
So how much does it take to reimplement the simple parts of a GenServer?&lt;/p&gt;

&lt;h1 id=&quot;the-simple-parts&quot;&gt;The simple parts&lt;/h1&gt;
&lt;p&gt;A GenServer provides you with a lot of functionality out of the box:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The goal of a GenServer is to abstract the “receive” loop for developers, automatically handling system messages, support code change, synchronous calls and more &lt;br /&gt;
– &lt;a href=&quot;http://elixir-lang.org/docs/stable/elixir/GenServer.html&quot;&gt;The GenServer docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s focus on implementing the “receive” loop, synchronous calls and making sure that it fits in Supervision tree.&lt;/p&gt;

&lt;p&gt;We’re going to more or less implement the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stack&lt;/code&gt; example from the GenServer &lt;a href=&quot;http://elixir-lang.org/docs/stable/elixir/GenServer.html&quot;&gt;docs&lt;/a&gt; but without using a GenServer.&lt;/p&gt;

&lt;h1 id=&quot;creating-the-project-and-the-first-stack-module&quot;&gt;Creating the project and the first Stack module&lt;/h1&gt;
&lt;p&gt;We need a project to get us started and we’re going to need a supervisor. So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix new stack --sup&lt;/code&gt; is is.&lt;/p&gt;

&lt;p&gt;Start out simple by defining the interface we want. We’ll need &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pop&lt;/code&gt; functions to be a stack. And if we want to start the stack as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;worker&lt;/code&gt; child of the appliction Supervisor we’ll also need a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_link&lt;/code&gt; function.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SimpleStack&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;the-start_link-function&quot;&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_link&lt;/code&gt; function&lt;/h1&gt;

&lt;p&gt;We’re not going for anything like a full re-implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenServer&lt;/code&gt; so let’s try and keep our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_link&lt;/code&gt; as simple as possible.
Reading over the &lt;a href=&quot;http://elixir-lang.org/docs/v1.0/elixir/GenServer.html#start_link/3&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_link/3&lt;/code&gt; docs&lt;/a&gt; and looking at the possible return values we see that we´re supposed to return a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{:ok, pid}&lt;/code&gt; tuple with the pid of the server.&lt;/p&gt;

&lt;p&gt;Start out by adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SimpleStack&lt;/code&gt; to the Supervisor in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stack&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;  &lt;span class=&quot;n&quot;&gt;children&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# Starts a worker by calling: Stack.Worker.start_link(arg1, arg2, arg3)&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# worker(Stack.Worker, [arg1, arg2, arg3]),&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SimpleStack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Running the application now (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix run&lt;/code&gt;) will result in a error:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;k&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Mix&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; Could not start application stack: Stack.start&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;:normal, &lt;span class=&quot;o&quot;&gt;[])&lt;/span&gt; returned an error: shutdown: failed to start child: SimpleStack
&lt;span class=&quot;k&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;EXIT&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; nil&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So let’s start working on that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_link&lt;/code&gt; function. Should be simple enough: We just need to start a new process with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spawn_link&lt;/code&gt; and return it’s pid.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SimpleStack&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;kn&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spawn_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Started&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Let’s try running that again: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix run --no-halt&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;21:14:16.783 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;debug] Started

21:14:16.783 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;debug] Started

21:14:16.783 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;debug] Started

21:14:16.783 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;debug] Started&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Well, that didn’t work. But what is going on? Try adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_restarts: 10&lt;/code&gt; to the options sent to the supervisor like so:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# for other strategies and supported options&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;strategy:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:one_for_one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Supervisor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;max_restarts:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;Supervisor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then run the application again. Now we get our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[debug] Started&lt;/code&gt; ten times. So the supervisor keeps calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_link&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Time to fire up &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iex&lt;/code&gt; and do some digging:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Erlang/OTP 19 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;erts-8.1] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;64-bit] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;smp:8:8] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;async-threads:10] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;hipe] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kernel-poll:false] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;dtrace]

Interactive Elixir &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.3.1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; - press Ctrl+C to &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type &lt;/span&gt;h&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; ENTER &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
iex&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1&lt;span class=&quot;o&quot;&gt;)&amp;gt;&lt;/span&gt; pid &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; spawn_link&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;fn &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; -&amp;gt; IO.puts &lt;span class=&quot;s2&quot;&gt;&quot;Started&quot;&lt;/span&gt; end&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Started
&lt;span class=&quot;c&quot;&gt;#PID&amp;lt;0.82.0&amp;gt;&lt;/span&gt;
iex&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2&lt;span class=&quot;o&quot;&gt;)&amp;gt;&lt;/span&gt; Process.alive? pid
&lt;span class=&quot;nb&quot;&gt;false
&lt;/span&gt;iex&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3&lt;span class=&quot;o&quot;&gt;)&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Ah! Out process stops as soon as its done its work. The supervisor sees this and then restarts the process and keeps doing it until it reaches its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_restarts&lt;/code&gt; limit.&lt;/p&gt;

&lt;h1 id=&quot;the-receive-loop&quot;&gt;The receive loop&lt;/h1&gt;
&lt;p&gt;Processes communicate via messages and each process has its own mailbox. We can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;receive do end&lt;/code&gt; statement to wait for messages to arrive at our mailbox. First let’s start out by listening for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:pop&lt;/code&gt; message that we’ll use to support the pop functionality of our stack.&lt;/p&gt;

&lt;p&gt;I’ve changed the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spaw_link&lt;/code&gt; statement so that we can move the receive loop into its own function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spawn_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__MODULE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:receiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[]])&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#Add something here...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;


  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;receiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;receive&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Unexpected messaged received&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;receiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;receiver&lt;/code&gt; function implements the receive loop. It gets initialized with an empty list.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;receive&lt;/code&gt; statement lets us patterne match on incomming messages.
We handle a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{:push, element}&lt;/code&gt; message by adding the new element to the front of the list and after doing so we call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;receiver&lt;/code&gt; recursively to wait for the next message.&lt;/p&gt;

&lt;h1 id=&quot;pushing&quot;&gt;Pushing&lt;/h1&gt;
&lt;p&gt;Next up is implementing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push/1&lt;/code&gt; function in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SimpleStack&lt;/code&gt; module.
We know that we need to send a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{:push, element}&lt;/code&gt; message to the process we created in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_link&lt;/code&gt;. But how do we find the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pid&lt;/code&gt; of that process again?&lt;/p&gt;

&lt;p&gt;You know how you can register a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenServer&lt;/code&gt; with a name by calling something like this: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenServer.start_link(Stack, [:hello], name: MyStack)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Turns out that giving a process a name is a pretty useful feature, and a feature that is provided by &lt;a href=&quot;http://elixir-lang.org/docs/v1.2/elixir/Process.html#register/2&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Process.register/2&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Great, well extend the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_link&lt;/code&gt; function to use that.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spawn_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__MODULE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:receiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[]])&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And now the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push/1&lt;/code&gt; function can easily send a message to the process with: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;send(:stack, {:push, element})&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And so we have a simple form of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenServer.cast&lt;/code&gt;.&lt;/p&gt;

&lt;h1 id=&quot;returning-a-response&quot;&gt;Returning a response&lt;/h1&gt;
&lt;p&gt;The last thing we need to be able handle synchronous calls.
Again we do this by sending messages. We’ll define a new message: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{:pop, pid}&lt;/code&gt;.
So besides telling that we want to perform a pop on the stack we’ll also send along the PID of the process to send the result to.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Send the pop message with the PID of the current process.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()})&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# And wait for the response&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;receive&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Unexpected messaged received&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;receiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;receive&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;caller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;

      &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;caller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;tail&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Unexpected messaged received&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;receiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The calling function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pop/0&lt;/code&gt; starts by sending the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:pop&lt;/code&gt; message. It finds its own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PID&lt;/code&gt; by calling &lt;a href=&quot;http://elixir-lang.org/docs/v1.2/elixir/Kernel.html#self/1&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self()&lt;/code&gt;&lt;/a&gt;.
Then it waits for the response message with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;receive&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:pop&lt;/code&gt; message is handled we take the first element, send it to the calling process and then recursively call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;receiver/1&lt;/code&gt; function with the popped stack.&lt;/p&gt;

&lt;p&gt;And there we have the synchronous call we wanted. You can find the &lt;a href=&quot;https://github.com/ErikMejerHansen/SimpleStack&quot;&gt;completed code here&lt;/a&gt; if you want to play around with it.&lt;/p&gt;
</description>
        <pubDate>Mon, 24 Oct 2016 20:00:00 +0000</pubDate>
        <link>http://blog.mejer-hansen.dk/2016/10/24/Build-your-own-GenServer.html</link>
        <guid isPermaLink="true">http://blog.mejer-hansen.dk/2016/10/24/Build-your-own-GenServer.html</guid>
        
        
      </item>
    
      <item>
        <title>Unexpected message</title>
        <description>&lt;p&gt;Do you know on which process the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_link&lt;/code&gt; function of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenServer&lt;/code&gt; in Elixir is run? &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenServer&lt;/code&gt; is one of the central building blocks often turned to when building something in Elixir but the above question is not something I had ever really given any thought.&lt;/p&gt;

&lt;p&gt;I knew that you had to be mindful of which process is doing the work when working with &lt;a href=&quot;/2016/02/18/Why-workers.html&quot;&gt;agents&lt;/a&gt; but had somehow missed that the same might be the case with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenServers&lt;/code&gt;.&lt;/p&gt;

&lt;h1 id=&quot;background&quot;&gt;Background&lt;/h1&gt;
&lt;p&gt;I’ve been playing around with &lt;a href=&quot;http://nerves-project.org&quot;&gt;nerves&lt;/a&gt;, a Raspberry Pi and an Arduino board. One the things I was trying to do was to read messages sent from the Arduino to the Pi over USB. &lt;br /&gt;
The &lt;a href=&quot;https://hex.pm/packages/nerves_uart&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nerves_uart&lt;/code&gt;&lt;/a&gt; makes it simple to read lines from USB and to receive those lines as as messages. So the plan was to setup a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenServer&lt;/code&gt; to start &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nerves_uart&lt;/code&gt; and to receive the messages from it.&lt;/p&gt;

&lt;h1 id=&quot;unexpected-messages&quot;&gt;Unexpected messages&lt;/h1&gt;
&lt;p&gt;The first attempt at the code to start &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nerves_uart&lt;/code&gt; and receive the messages looked a bit like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HelloNerves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Messages&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;GenServer&lt;/span&gt;
  &lt;span class=&quot;kn&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Start the Nerves.UART GenServer&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Nerves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UART&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# We want to listen to the USB plugged in at &quot;ttyACM0&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# and use newlines as a separator for the data.&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Nerves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UART&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ttyACM0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;speed:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;active:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;framing:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Nerves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UART&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Framing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;separator:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;no&quot;&gt;GenServer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__MODULE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handle_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:nerves_uart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_serial_port_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Got info: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:noreply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelloNerves.Messages&lt;/code&gt; is then started with as a worker with  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;worker(HelloNerves.Messages, [])&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Compile, upload to the Raspberry PI, sit back and watch the data flow.&lt;/p&gt;

&lt;h1 id=&quot;unintended-recipient&quot;&gt;Unintended recipient&lt;/h1&gt;
&lt;p&gt;Well, not quite as it turns out. Because instead of the loging of the data I expected I started seeing the following error message instead: &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Supervisor received unexpected message {:nerves_uart, &quot;ttyACM0&quot;, &quot;400&quot;}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s dig into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nerves_uart&lt;/code&gt; source and see if we can find the source of our troubles.
The source for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nerves.UART GenServer&lt;/code&gt; can be found here: &lt;a href=&quot;https://github.com/nerves-project/nerves_uart/blob/8a867e7e29d1739075f2d03cea2095fcb9e65132/lib/nerves_uart.ex&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If we look at the function that handles the &lt;a href=&quot;https://github.com/nerves-project/nerves_uart/blob/8a867e7e29d1739075f2d03cea2095fcb9e65132/lib/nerves_uart.ex#L295&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;open&lt;/code&gt; call&lt;/a&gt; that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pid&lt;/code&gt; of the calling function gets stored in the state as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;controlling_process&lt;/code&gt;. And messages are sent to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;controlling_process&lt;/code&gt;, but why do these messages end up at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Supervisor&lt;/code&gt;?&lt;/p&gt;

&lt;h2 id=&quot;the-call-sequence&quot;&gt;The call sequence&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelloNerves.Messages&lt;/code&gt; is started with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;worker()&lt;/code&gt; statement causing  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelloNerves.Messages.start_link&lt;/code&gt; to be called which then in turn calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nerves.UART.start_link&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In overview something like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;HelloNerves.ex -&amp;gt; HelloNerves.Messages.start_link -&amp;gt; Nerves.UART.start_link&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nerves.UART.start_link&lt;/code&gt; was in fact called from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Supervisor&lt;/code&gt; process. Which in then makes it the recipient of messages from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nerves.UART&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-solution&quot;&gt;The solution&lt;/h2&gt;

&lt;p&gt;Digging trough first the Elixir and then the Erlang the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenServer&lt;/code&gt; documentation revealed the following in the description of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init/1&lt;/code&gt; function:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;this function is called by the new process to initialize&lt;/p&gt;

  &lt;p&gt;– &lt;a href=&quot;http://erlang.org/doc/man/gen_server.html#Module:init-1&quot;&gt;STDLIB Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The point here being that while the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelloNerves.Messages.start_link&lt;/code&gt; function is run on the Supervisors process the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init/1&lt;/code&gt; function is called on the newly spawned process for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelloNerves.Messages&lt;/code&gt; GenServer.&lt;/p&gt;

&lt;p&gt;So if I want to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nerves.UART.start_link&lt;/code&gt; from process of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelloNerves.Messages GenServer&lt;/code&gt; it has to be done from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init/1&lt;/code&gt; callback.&lt;/p&gt;

&lt;p&gt;This leads to the following rewrite:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HelloNerves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Messages&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;GenServer&lt;/span&gt;
  &lt;span class=&quot;kn&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Nerves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UART&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Nerves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UART&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;speed:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;active:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;framing:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Nerves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UART&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Framing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;separator:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;nerves_pid:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Nerves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UART&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;no&quot;&gt;GenServer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__MODULE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ttyACM0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handle_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:nerves_uart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_serial_port_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Got info: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:noreply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;In hindsight it seems obvious that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_link&lt;/code&gt; would be run on the callers process. But it took me a fair while to figure out that it was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init/1&lt;/code&gt; I was looking for. &lt;br /&gt;
Coming from a mainly OOP background I think that there is a lot of hidden complexity lurking here not stemming from anything but lack of experience.&lt;/p&gt;
</description>
        <pubDate>Mon, 24 Oct 2016 20:00:00 +0000</pubDate>
        <link>http://blog.mejer-hansen.dk/2016/10/24/A-dive-into-GenServer.html</link>
        <guid isPermaLink="true">http://blog.mejer-hansen.dk/2016/10/24/A-dive-into-GenServer.html</guid>
        
        
      </item>
    
      <item>
        <title>REST services in Elixir with Cowboy</title>
        <description>&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy_rest&lt;/code&gt; makes it easy to build REST services with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is inspired by &lt;a href=&quot;https://github.com/webmachine/webmachine&quot;&gt;webmachine&lt;/a&gt;&lt;sup id=&quot;fnref:webmachine&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:webmachine&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;,  services in Elixir. In this blog I’ll give a quick example of how to create a couple of simple resources and lastly touch on a few of the downsides of using it.&lt;/p&gt;

&lt;p&gt;Where plug might be seen as a way to describe how to do a transformation of the request into the response, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy_rest&lt;/code&gt; lets your describe the characteristics of your resource and then let &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy_rest&lt;/code&gt; decide on how to reply to the request.&lt;/p&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;the request is handled as a state machine with many optional callbacks describing the resource and modifying the machine’s behavior&lt;/p&gt;

  &lt;p&gt;– &lt;a href=&quot;https://ninenines.eu/docs/en/cowboy/1.0/guide/rest_handlers/&quot;&gt;The cowboy docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This makes for a nicely declarative way of describing your resources as you’ll hopefully see below. It provides a lot of help (or at least, opinions) in providing correct replies.&lt;/p&gt;

&lt;p&gt;You can find the code used in this blog &lt;a href=&quot;https://github.com/ErikMejerHansen/REST-service-examples&quot;&gt;here&lt;/a&gt; (alongside parallel implementations in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Phoenix&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Webmachine&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;the-first-resource&quot;&gt;The first resource&lt;/h2&gt;
&lt;p&gt;Lets start by creating a new Elixir project using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--sup&lt;/code&gt; flag to get a supervisor for our project:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mix new cowboy_rest_example &lt;span class=&quot;nt&quot;&gt;--sup&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For the rest of this blog I’ll assume you ran the command above and thus named the project &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy_rest_example&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;getting-cowboy-up-and-running&quot;&gt;Getting :cowboy up and running&lt;/h2&gt;
&lt;p&gt;We now need to get :cowboy up and running. Open the file containing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start/2&lt;/code&gt; Application callback: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lib/cowboy_rest_example.ex&lt;/code&gt;.
Add the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#Dispatcher ~ router&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dispatch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Dispatch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                                &lt;span class=&quot;ss&quot;&gt;env:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;dispatch:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The first two arguments &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:http&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;100&lt;/code&gt; tells &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; to listen to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http&lt;/code&gt; connections (the other option being &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:https&lt;/code&gt;) and to start 100 &lt;a href=&quot;https://hex.pm/packages/ranch&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ranch&lt;/code&gt;&lt;/a&gt; acceptors. The choice of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;100&lt;/code&gt; was more or less arbitrary and I can’t offer much advice as to this setting.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env: [dispatch: dispatch]&lt;/code&gt; sets the dispatcher (aka router) for our resources, we’ll get to that in a moment. &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[port: 8000]&lt;/code&gt; tells cowboy to listen to port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;8000&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;dispatching&quot;&gt;Dispatching&lt;/h2&gt;
&lt;p&gt;One of the options we supplied to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; was a dispatch table that we’ll define in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CowboyRestExample.Dispatch&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Routes in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; are defined as a list of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{host, [routes]}&lt;/code&gt; tuples. Most likely you’ll want to set the host to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:_&lt;/code&gt; meaning match everything. But you could use the host part to match on different subdomains (see: the &lt;a href=&quot;https://ninenines.eu/docs/en/cowboy/1.0/guide/routing/&quot;&gt;routing&lt;/a&gt; section of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; documentation for more information).&lt;/p&gt;

&lt;p&gt;We’ll start out with a dispatch table that looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Dispatch&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Routes in cowboy are {host, [paths]} tuples&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#The :_ atom causes cowboy_router to match any host.&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:cowboy_router&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()}])&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I’ve moved the routes/paths out into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;routes&lt;/code&gt; function. Paths are defined as a three element tuple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{path_match, handler, options}&lt;/code&gt;.
So in the above example we have told &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; to let &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CowboyRestExample.Hello&lt;/code&gt; handle any requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;/&quot;&lt;/code&gt; (and we’ve supplied no options to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CowboyRestExample.Hello&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;the-hello-world-handler&quot;&gt;The “Hello, world” handler&lt;/h2&gt;
&lt;p&gt;Time to write our first handler. Create a file for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CowboyRestExample.Hello&lt;/code&gt; module.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Hello&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:upgrade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy_rest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;h1&amp;gt;Hello, World&amp;lt;/h1&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init&lt;/code&gt; method is the first callback we get from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; when handling requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;/&quot;&lt;/code&gt;. Here we tell &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; that we want to perform a protocol upgrade to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:cowboy_rest&lt;/code&gt;. In essence we’re telling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; that our handler will respond to the callbacks used by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy_rest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As stated in the introduction introduction request will be handled as a state-machine and the callbacks we respond to change the behavior alters the behaviour of that state-machine. But we don’t have to respond to every call! The callbacks all have reasonable defaults. &lt;br /&gt;
So for now we can get away with just implementing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to_html&lt;/code&gt; function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;h1&amp;gt;Hello, World&amp;lt;/h1&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Every callback from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:cowboy_rest&lt;/code&gt; will take the same form. The function will receive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;request&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;state&lt;/code&gt; arguments to the function and it’ll respond with a tuple consisting of its reply and the request and state tuples.&lt;/p&gt;

&lt;p&gt;If you start your project now with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix run --no-halt&lt;/code&gt; and open &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:8000&lt;/code&gt; in a browser you should see the traditional “Hell, World” greeting.&lt;/p&gt;

&lt;p&gt;But what if we wanted a json response?
Try &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl -I --request GET --url http://localhost:8000/ --header 'accept: application/json'&lt;/code&gt; in terminal.
You’ll get the following response:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;HTTP/1.1 406 Not Acceptable
server: Cowboy
&lt;span class=&quot;nb&quot;&gt;date&lt;/span&gt;: Sat, 15 Oct 2016 10:05:14 GMT
content-length: 0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So our resource does not support replying with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;application/json&lt;/code&gt;, lets fix that.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;content_types_provided&lt;/code&gt; callback is how we define what content-types our resource supports.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content_types_provided&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;text/html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:to_html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;application/json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Our response here (aside from request and state which we’ll always have to return) is a list of tuples, each tuple containing a content-type and the name of the function that can generate the response in that content-type.
Lets add the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to_json&lt;/code&gt; function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Poison&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;hello:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;world&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Restart &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; after making the changes (take a look at &lt;a href=&quot;https://hex.pm/packages/remix&quot;&gt;remix&lt;/a&gt; if you find it annoying restarting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; after each change).
Run that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl&lt;/code&gt; command again:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl --request GET --url http://localhost:8000/ --header 'accept: application/json'&lt;/code&gt;. Note that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-I&lt;/code&gt; argument has been removed.    &lt;br /&gt;
Sucess! We now have our JSON response. We can now also understand why earlier it was sufficient to just implement the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to_html&lt;/code&gt; function. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy_rest&lt;/code&gt; defaults to serving &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;html&lt;/code&gt; by calling the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to_html&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;What happens if you don’t set an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accept&lt;/code&gt; header? And what happens if you change the order of the tuples in our reply from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;content_types_provided&lt;/code&gt;?  &lt;br /&gt;
Answer: If no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accept&lt;/code&gt; header is present in the request &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy_rest&lt;/code&gt; chooses to reply with the first content-type in the content_types_provided list.&lt;/p&gt;

&lt;h2 id=&quot;the-todo-handler&quot;&gt;The “Todo” handler&lt;/h2&gt;
&lt;p&gt;Lets extend the example with new resource for getting a list of todos and creating a todos. &lt;br /&gt;
First the dispatcher is extended and then the resource gets defined in its own module.&lt;/p&gt;

&lt;h3 id=&quot;extending-the-dispatcher&quot;&gt;Extending the dispatcher&lt;/h3&gt;
&lt;p&gt;Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{&quot;/todo&quot;, CowboyRestExample.TodoResource, []}&lt;/code&gt; the list of routes in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CowboyRestExample.Dispatch.routes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next create the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CowboyRestExample.TodoResource&lt;/code&gt; module as below:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;TodoResource&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:upgrade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy_rest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rest_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{}}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There is a new callback here: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rest_init&lt;/code&gt;. Its the first callback the resource gets after doing a protocol upgrade to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:cowboy_rest&lt;/code&gt;.
It allows us to set the initial state and return it as the last element of the response tuple, here its initialized as a empty map.&lt;/p&gt;

&lt;p&gt;We only want to respond with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;json&lt;/code&gt; so add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;content_types_accepted&lt;/code&gt; that makes that true:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;p&quot;&gt;{[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;application/json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:from_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we want to be able to get the list Todos. These will be fetched from a MySql database using ecto. I wont show the setup here but take a look at the github repo &lt;a href=&quot;https://github.com/ErikMejerHansen/REST-service-examples&quot;&gt;here&lt;/a&gt; if you want the details.&lt;/p&gt;

&lt;p&gt;We now have a choice to make: What reply do we want if there are no todos? Empty list or a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;404&lt;/code&gt; status code?
Here we’ll use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;404&lt;/code&gt; status code because it allows me to introduce the next callback: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resource_exists&lt;/code&gt;. Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt; from this function will yield a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;404&lt;/code&gt; reply. It also makes for a nice place to actually fetch the Todos from the database.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resource_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Repo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;todos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:todos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;todos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In essence we’re pulling all the todos from the database and adding it to our state map under the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:todos&lt;/code&gt; key.
Now that we have a list of Todos in our state we can transform those into JSON in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to_json&lt;/code&gt; function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;todos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;todos&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Enum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%{&lt;/span&gt;
              &lt;span class=&quot;ss&quot;&gt;todo:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&amp;amp;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;ss&quot;&gt;created:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&amp;amp;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inserted_at&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Poison&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;todos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And with that we have our list Todo resource done.&lt;/p&gt;

&lt;h2 id=&quot;posting-a-todo&quot;&gt;Posting a Todo&lt;/h2&gt;
&lt;p&gt;But a Todo example isn’t worth its salt if you can’t add todos.
In order to do that we need define two additional callbacks and add a function saving the new todo to the database.&lt;/p&gt;

&lt;p&gt;If you try and send a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST&lt;/code&gt; at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/todo&lt;/code&gt; right now you’ll get a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;405 Method not allowed&lt;/code&gt; response back. To fix that add the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed_methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;GET&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;HEAD&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;OPTIONS&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
 &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We now supports &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST&lt;/code&gt;. Trying another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST&lt;/code&gt; at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/todo&lt;/code&gt; will result in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;415 Unsupported Media Type&lt;/code&gt; response because we haven’t told &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:cowboy_rest&lt;/code&gt; that we want to accept &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;application/json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;content_types_accepted&lt;/code&gt; callback allows us to state what content-types we accept.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content_types_accepted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;{[{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'application/json'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:from_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:from_json&lt;/code&gt; function also needs defining:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy_req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Poison&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Repo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;subject:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;todo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The first line of that function reads the body of the request. And here we stumble onto one of the quirks of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; all functions on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:cowboy_req&lt;/code&gt; will return a request tuple which may or may not differ from the one passed to it. As the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:cowboy&lt;/code&gt; docs state:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Whenever Req is returned, you must use this returned value and ignore any previous you may have had. This value contains various state informations which are necessary for Cowboy to do some lazy evaluation or cache results where appropriate.&lt;/p&gt;

  &lt;p&gt;– &lt;a href=&quot;https://ninenines.eu/docs/en/cowboy/1.0/manual/cowboy_req/index.html&quot;&gt;The cowboy docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The the second line uses &lt;a href=&quot;https://hex.pm/packages/poison&quot;&gt;Poison&lt;/a&gt; to decode the request body into a map.  &lt;br /&gt;
The third line inserts a new Todo into the database. &lt;br /&gt;
And finally the fourth line tells &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:cowboy_rest&lt;/code&gt; that we succeeded.&lt;/p&gt;

&lt;p&gt;If you try posting now you’ll get at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;204 No Content&lt;/code&gt; response. Huh? I was expecting a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;201 Created&lt;/code&gt; response. &lt;br /&gt;
Well it turns out you should set a location header in the response when sending a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;201&lt;/code&gt; status code.&lt;/p&gt;

&lt;p&gt;Luckily that is easily fixed:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy_req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Poison&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Repo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;subject:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;todo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy_req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/todo/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We need to know the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;host&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt; so that we can construct a link for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;location&lt;/code&gt; header. Then we can extend our reply to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{true, &quot;#{host}/todo/#{todo.id}&quot;}&lt;/code&gt;. That is: “Yes, we could understand the body you sent us and you can find the result over there”.&lt;/p&gt;

&lt;p&gt;Try posting again. What? &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;303 See other&lt;/code&gt;? &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;303&lt;/code&gt; is what you would send if your service prevented duplicates by pointing the client at the preexisting version of what they tried to create.  &lt;br /&gt;
And sure enough our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resource_exists&lt;/code&gt; did return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; indicating that the resource did already exist.&lt;/p&gt;

&lt;p&gt;Ok, time to fix that.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resource_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy_req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;todos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Repo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;todos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;todos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:todos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;todos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So if the request is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST&lt;/code&gt; or there are no Todos we’ll return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt; otherwise return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt;. You might be tempted to try and use pattern matching you match different &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resource_exists&lt;/code&gt; implementations based on the request method. But unfortunately the request argument is a humongous tuple that does not lend itself easily to pattern matching.&lt;/p&gt;

&lt;p&gt;Lets try that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST&lt;/code&gt; again. Bingo! A nice and shiny &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;201 Created&lt;/code&gt; response!&lt;/p&gt;

&lt;h2 id=&quot;getting-a-single-todo&quot;&gt;Getting a single Todo&lt;/h2&gt;
&lt;p&gt;One final resource: Getting a single Todo. &lt;br /&gt;
Again extend the dispatcher add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{&quot;/todo/:id&quot;, CowboyRestExample.TodoResource, []}&lt;/code&gt; to the routes.&lt;/p&gt;

&lt;p&gt;If you have done any projects in &lt;a href=&quot;http://phoenixframework.org&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Phoenix&lt;/code&gt;&lt;/a&gt; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:id&lt;/code&gt; syntax should seem familiar. Its tells &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:cowboy&lt;/code&gt; to bind any value after &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/todo/&lt;/code&gt; to the id &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:id&lt;/code&gt; so that we may fetch is in our resource.&lt;/p&gt;

&lt;p&gt;Now create the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CowboyRestExample.SingleTodoResource&lt;/code&gt; module:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SingleTodoResource&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Repo&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:upgrade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy_rest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rest_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{}}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed_methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;GET&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;HEAD&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;OPTIONS&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resource_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy_req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Repo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_integer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content_types_provided&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;application/json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Poison&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%{&lt;/span&gt;
              &lt;span class=&quot;ss&quot;&gt;todo:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;ss&quot;&gt;created:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inserted_at&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The formula should seem familiar now: Upgrade the protocol to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:cowboy_rest&lt;/code&gt;, fetch the todo in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resource_exists&lt;/code&gt; and transform it to JSON in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to_json&lt;/code&gt;. But aren’t things getting a bit repetitive and thus drawing focus away from the differences between the two Todo resources?&lt;/p&gt;

&lt;p&gt;Lets define a module with some defaults:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Defaults&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;defmacro&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__using__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;quote&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;@behaviour&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DefaultBehaviour&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Repo&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:upgrade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy_rest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rest_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{}}&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content_types_provided&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;application/json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_authorized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auth_header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cowboy_req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;authorization&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth_header&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth_header&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;:undefined&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Basic&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:rights&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Everything&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forbidden&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;defoverridable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;forbidden:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CowboyRestExample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DefaultBehaviour&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;@callback&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If we now add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;use CowboyRestExample.Defaults&lt;/code&gt; we now skip implementing the callbacks for the functions that won’t differ across resources thus drawing out the differences between our resources. We have also defined some safe defaults for the security related &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_authorized&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forbidden&lt;/code&gt; callbacks. In effect denying access to a resource unless we explicitly grant access. &lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;defoverridable [forbidden: 2]&lt;/code&gt; allows the different resources to override the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forbidden&lt;/code&gt; callback (which would not be possible if we did not add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;defoverridable&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;As a final touch we add a very simple behaviour: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CowboyRestExample.DefaultBehaviour&lt;/code&gt; which just defines our own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to_json&lt;/code&gt; callback. This is here to help our future selves. If we forget to implement a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to_json&lt;/code&gt; function in a resource that uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CowboyRestExample.Defaults&lt;/code&gt; we’ll get a nice compiler warning reminding us to do so.&lt;/p&gt;

&lt;p&gt;You can find the final code on &lt;a href=&quot;https://github.com/ErikMejerHansen/REST-service-examples&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And that brings us to the end of the example.&lt;/p&gt;

&lt;h2 id=&quot;why-not-just-use-phoenix&quot;&gt;Why not just use Phoenix?&lt;/h2&gt;
&lt;p&gt;Phoenix is a valid choice for doing REST service. At &lt;a href=&quot;http://www.opentelehealth.com&quot;&gt;work&lt;/a&gt; we have our first two Phoenix service moving into production just about now). And we really, &lt;em&gt;really&lt;/em&gt; like Phoenix. But experience of building our first two services has given us the chance to evaluate if Phoenix is right for us.&lt;/p&gt;

&lt;h3 id=&quot;is-the-plug-model-right-for-us&quot;&gt;Is the plug model right for us?&lt;/h3&gt;
&lt;p&gt;They way we handle requests seems like an ill fit for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plug&lt;/code&gt; model.
We have to do authentication, authorization and JSON schema validation of every request received to our APIs. &lt;br /&gt;
Authorization is the same across resources so thats not the problem, but authentication differs across resource and method (for instance one user might have access creating a give resource but not altering it). So we end up with constructs like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:authorize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;permissions:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Read: Sessions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:list_by_team&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:authorize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;permissions:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Create: Sessions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:authorize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;permissions:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Update: Sessions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:authorize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;permissions:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Delete: Sessions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We have much the same situation with performing JSON schema validations.&lt;/p&gt;

&lt;h3 id=&quot;we-dont-use-templates-channels-nor-i18n&quot;&gt;We don’t use templates, channels nor i18n&lt;/h3&gt;
&lt;p&gt;We’re building APIs (that we then build web apps on top of) and as a consequence we’re not using templates, channels nor i18n. So there’s a lot of Phoenix we’re not using.&lt;/p&gt;

&lt;h2 id=&quot;batteries-not-included&quot;&gt;Batteries not included&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy_rest&lt;/code&gt; is not without its drawbacks among which are:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;No logging: By default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt; performs no logging, so you’ll have to figure out your own&lt;/li&gt;
  &lt;li&gt;Erlang stacktraces: You’ll have to learn to read Erlang stacktraces. Which takes some getting used to.&lt;/li&gt;
  &lt;li&gt;Way less creature comforts: Phoenix does a lot to help the developer along. Automatic recompilation, &lt;em&gt;great&lt;/em&gt; getting started guides, and excellently helpful error messages. Cowboy has none of that.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;performance&quot;&gt;Performance?&lt;/h2&gt;
&lt;p&gt;Performance has not been a factor for looking beyond Phoenix. Phoenix is plenty fast. &lt;br /&gt;
But below you’ll find a graph comparing Posting a Todo, getting a single Todo, getting a list of 10 todos and getting the “Hello, World” resource across &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cowboy&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Webmachine&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Phoenix&lt;/code&gt;. &lt;br /&gt;
Test were conducted using &lt;a href=&quot;https://github.com/wg/wrk&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wrk&lt;/code&gt;&lt;/a&gt; running with 300 connections. &lt;br /&gt;
Wrk, MySql and phoenix/cowboy/webmachine are all running on the same machine (a Mid 2015 MacBook Pro). &lt;br /&gt;
Don’t read to much into the results - in real life most likely everything &lt;em&gt;but&lt;/em&gt; phoenix/cowboy/webmachine is going to dominate the response times.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/req_per_sec.png&quot; alt=&quot;Requests per second: Cowboy, Webmachine, Phoenix&quot; /&gt;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:webmachine&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;I highly recommend reading the blog series by Sean Cribbs on webmachine found &lt;a href=&quot;http://seancribbs.com/&quot;&gt;here&lt;/a&gt; if you’re unfamiliar with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;webmachine&lt;/code&gt;) &lt;a href=&quot;#fnref:webmachine&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 16 Oct 2016 14:00:00 +0000</pubDate>
        <link>http://blog.mejer-hansen.dk/2016/10/16/REST-services-in-Elixir-with-Cowboy.html</link>
        <guid isPermaLink="true">http://blog.mejer-hansen.dk/2016/10/16/REST-services-in-Elixir-with-Cowboy.html</guid>
        
        
      </item>
    
      <item>
        <title>Elixir, Phoenix and workers, part 2: Why use workers</title>
        <description>&lt;p&gt;Before I start diving into different worker/job-scheduler libraries it might be wise to take a look at why
I think workers are needed.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Just to recap: Clients send JSON to the server. That JSON has to be transformed into XML and sent to a third party system (while maintaining the correct order of the messages).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But why not just do the work directly in the controller or in an agent?
First and foremost we need to ensure that the message order is preserved. The consequence is that we can’t send a reply to the client before we’re done processing the message. Otherwise we run the risk of messages overtaking each other.&lt;/p&gt;

&lt;p&gt;But how much of an impact does it have on performance if we were to do the work in the controller or an agent?
I tried adding between 100 and 0 milliseconds of delay to the controller and the agent.
Without any delay in the controller the server is able to handle around 450,000 requests/min dropping down to just over 50,000 requests/min for 100 ms of extra delay. That isn’t too surprising.&lt;/p&gt;

&lt;p&gt;Ok - but handing the work of to an Agent would do the trick right? It can keep state across all the requests and ensure messages are handled in order and because we’re handing it off to the agent performance shouldn’t suffer.&lt;/p&gt;

&lt;p&gt;Well no performance wont &lt;em&gt;just&lt;/em&gt; suffer - the server will keel over and die.&lt;/p&gt;

&lt;p&gt;But what is happening with the agent? Even adding 1 ms of extra delay has a significant impact on the performance of the server. What is going on?
If you take a look at some of the &lt;a href=&quot;http://elixir-lang.org/getting-started/mix-otp/agent.html&quot;&gt;documentation for agents&lt;/a&gt; you’ll run across this sentence:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Everything that is inside the function we passed to the agent happens in the agent process”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agents are for keeping state - which means that messages passed to an agent are processed in order. So any delay caused by any of the requests to the server will hurt all following requests. And the consequences are clear.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/reqests-min-vs-delay.png&quot; alt=&quot;Requests per minute plotted against delays added to controller or agent&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So using an Agent won’t work. Doing the work in the controller runs the risk of not preserving message order (the same would be true of Tasks).&lt;/p&gt;

&lt;p&gt;So workers it is. Next time.&lt;/p&gt;
</description>
        <pubDate>Thu, 18 Feb 2016 14:00:00 +0000</pubDate>
        <link>http://blog.mejer-hansen.dk/2016/02/18/Why-workers.html</link>
        <guid isPermaLink="true">http://blog.mejer-hansen.dk/2016/02/18/Why-workers.html</guid>
        
        
      </item>
    
      <item>
        <title>Elixir, Phoenix and workers, part 1: The setup</title>
        <description>&lt;p&gt;This is the first post in a series looking at Elixir, Phoenix and a few different worker/job-scheduler libraries for a very specific use-case.&lt;/p&gt;

&lt;p&gt;The use-case is not made out of whole cloth but a lot of details have been abstracted way.
The use-case is as follows: A bunch of clients send JSON messages to a web server. The messages a converted into XML and forwarded to a third party system (over which we have no control).&lt;br /&gt;
There is one rule we absolutely cannot break: The order of the messages is important. One message from a given client cannot overtake another and skipping messages is also not allowed.&lt;/p&gt;

&lt;p&gt;The idea of this blog series is to first build something to act as the third party system and a simple Phoenix based web server to receive JSON messages from the clients.
The next parts of the series will then look at different worker/job-scheduler libraries and see if they can be made to work for this specific use-case.&lt;/p&gt;

&lt;p&gt;Before we start looking at the parts we’ll need before looking at the first worker there is one point I’d like to stress: &lt;em&gt;Im just starting out with Elixir and Phoenix&lt;/em&gt;.
So this is going to be a learning experience for me and you should take everything with a grain of salt&lt;sup id=&quot;fnref:foot&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:foot&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-necessary-parts&quot;&gt;The necessary parts&lt;/h2&gt;
&lt;p&gt;This time I’ll focus on the bits need before we can start testing out different workers.
The bits are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A web server for receiving messages from the clients&lt;/li&gt;
  &lt;li&gt;Something to act as the third party system&lt;/li&gt;
  &lt;li&gt;Something to act as a bunch of clients&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;the-web-server-phoenix&quot;&gt;The web server (Phoenix)&lt;/h3&gt;
&lt;p&gt;I’ll be using &lt;a href=&quot;http://www.phoenixframework.org/&quot;&gt;Phoenix&lt;/a&gt; for building the simple web services used by the clients.
The server will receive JSON messages that looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Some client&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;sequenceNumber&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;sample&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There will be a simple controller for receiving these messages and handing them off to a appropriate worker.
If the client remembers to set its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;content-type&lt;/code&gt; header to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;application/json&lt;/code&gt; the JSON will be parsed and be made available to the relevant controller method in its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;params&lt;/code&gt; that it receives as its second argument.&lt;/p&gt;

&lt;p&gt;Now it makes good sense to map the received JSON into Elixir structs as a way to sanitize received data. In this case the structs looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ExternalSystemMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Message&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ExternalSystemMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MessageData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;as:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MessageData&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;defstruct&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;client:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;data:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MessageData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ExternalSystemMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MessageData&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;defstruct&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;sequenceNumber:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;data:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The newly constructed struct is then sent to workers that will handle forwarding the message to the Agent acting as the third party system.&lt;/p&gt;

&lt;p&gt;One thing I ran into was mapping from JSON to these structs proved harder than expected. Elixir has the &lt;a href=&quot;http://elixir-lang.org/docs/stable/elixir/Kernel.html#struct!/2&quot;&gt;Kernel.struct!/2&lt;/a&gt; function that can take a map and map it into a specified struct. But there is one caveat that is not immediately apparent from the docs: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct!/2&lt;/code&gt; only maps from keys that are atoms.&lt;/p&gt;

&lt;p&gt;Phoenix uses &lt;a href=&quot;https://github.com/devinus/poison&quot;&gt;Poison&lt;/a&gt; for parsing JSON into maps and Poison does have an option us create maps where the keys are atoms. So why doesn’t Phoenix utilize that option? &lt;a href=&quot;https://engineering.appcues.com/2016/02/02/too-many-dicts.html&quot;&gt;Turns out theres a very good reason for that&lt;/a&gt;: Atoms in Elixir are not garbage collected. So if Poison was setup to provide maps with keys that were atoms it would open up the server a denial of service attack aiming to exhaust memory.&lt;/p&gt;

&lt;h3 id=&quot;the-third-party-system-an-agent&quot;&gt;The third party system (An Agent)&lt;/h3&gt;

&lt;p&gt;The primary characteristic of the third party system is that &lt;em&gt;it does not like it&lt;/em&gt; when the messages it receives from any given client are out of order.
In order to emulate this behavior we need something that keep state across several requests.
The Elixir docs state that “Agents are a simple abstraction around state.”. So an Agent would seem to fit the bill perfectly.&lt;/p&gt;

&lt;p&gt;Agent is seeded with an empty map as its initial state and usage of the Agent is wrapped in module hiding away the details.
The full code for the modules is:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ExternalSystemMock&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ExternalSystemMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;as:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Message&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ExternalSystemMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MessageData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;as:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MessageData&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Agent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;receive_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;agent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;client:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;data:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MessageData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;sequenceNumber:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sequenceNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;data:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}})&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;updater&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sequenceNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&amp;amp;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;no&quot;&gt;Agent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;agent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;updater&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newSequenceNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;MatchError&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;match error&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastSeenSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastSeenSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastSeenSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastSeenSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Missed message&quot;&lt;/span&gt;

      &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastSeenSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastSeenSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Skipped message&quot;&lt;/span&gt;

      &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastSeenSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastSeenSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newSequenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Message repeat&quot;&lt;/span&gt;

      &lt;span class=&quot;p&quot;&gt;%{}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#new client&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newSequenceNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The real meat is in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;update/3&lt;/code&gt; function. Guard expressions ensure that if any sequence is repeated, skipped or received out of order the Agent raises an exception. Raising an unhanded exception from a Agent will cause it to die.
This is important because it will make it much easier do detect if any of the worker libraries we look at later on make any changes to the order of the messages.&lt;/p&gt;

&lt;h3 id=&quot;the-clients-wrk&quot;&gt;The clients (wrk)&lt;/h3&gt;
&lt;p&gt;We need something to act as a bunch of clients. I had intended to use &lt;a href=&quot;http://gatling.io&quot;&gt;Gatling&lt;/a&gt; which I’ve used before with some success. But Gatling gave out before the server did and reported response times what seemed way to high.&lt;/p&gt;

&lt;p&gt;So I turned to &lt;a href=&quot;https://github.com/wg/wrk&quot;&gt;wrk&lt;/a&gt; instead (and seemed up to the job).
The small Lua script below sets up a small test. Each client will send fifty messages with increasing sequence numbers and then sends final halt messages (and then the message repeats).&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lua&quot; data-lang=&quot;lua&quot;&gt;&lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;threads&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;threadCounter&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;nb&quot;&gt;table.insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;threads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestHeaders&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;requestHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;application/json&quot;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clientName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;threadCounter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;-&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/api/data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;{\&quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;:\&quot;&quot; ..  clientName .. &quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;,\&quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;: {\&quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sequenceNumber&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;:&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;, \&quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;: [1,2,3,4]}}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/api/data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestHeaders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;{\&quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;halt&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;: true, \&quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;:\&quot;&quot; ..  clientName .. &quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;table.concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Just as a side node: Before adding any workers and running both wrk and Phoenix on the same machine Phoenix seems to top out at around 440000 requests per minute.
I’ll use this as the baseline going forward.&lt;/p&gt;

&lt;h3 id=&quot;next-time&quot;&gt;Next time&lt;/h3&gt;

&lt;p&gt;Next time I’ll take a look at the first worker library and give an explanation as to why a worker is necessary at all.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:foot&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;But if you spot something stupid please let me know. &lt;a href=&quot;#fnref:foot&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 14 Feb 2016 16:38:00 +0000</pubDate>
        <link>http://blog.mejer-hansen.dk/2016/02/14/Elixir-Phoenix-workers-part-1.html</link>
        <guid isPermaLink="true">http://blog.mejer-hansen.dk/2016/02/14/Elixir-Phoenix-workers-part-1.html</guid>
        
        
      </item>
    
      <item>
        <title>How to do support if you don’t value your customers</title>
        <description>&lt;p&gt;&lt;em&gt;With helpful examples from Oracle and Philips.&lt;/em&gt;&lt;br /&gt;
I see customer support as having a polarizing effect: It will either loose you customers or win you fans.
But winning fans via customer support takes time and effort and will only work if you actually care about your customers.&lt;/p&gt;

&lt;p&gt;I’ve been on the receiving end of an uncaring support organization more times than I care to remember and I think I’ve spotted a few patterns emerge from those experiences that I’d like to share.&lt;/p&gt;

&lt;p&gt;First I’ll give to examples of experiences with uncaring support.
You can skip the next two sections and just jump right ahead to the conclusion if you wish (it’s mostly just me blowing of steam anyway)&lt;/p&gt;

&lt;p&gt;#Example 1: Oracle (circa: 2010)&lt;/p&gt;

&lt;p&gt;A few years back I was working on a project that was mostly just SOAP messages passing trough an Oracle Enterprise Service Bus.
Basically the Service Bus would receive XML documents where parts of the document where signed. The service bus would pull out the signed parts stick them into other xml documents
and forward them to the recipient. Bread and butter stuff for a service bus.&lt;/p&gt;

&lt;p&gt;But then the recipients started complaining of broken XML signatures. And true enough it did seem that the Service bus was breaking signatures. Specifically a component in the service bus called XMLBeans.
It was breaking the signatures by moving around namespace declarations in a way that broke the signatures.&lt;/p&gt;

&lt;p&gt;Problem spotted and likely cause found we turned to Oracle support. Since we could point to the exact component that was causing problem and had build a small bit of code reproducing the problem then it shouldn’t be to hard get support to accept the bug and provide a solution.&lt;/p&gt;

&lt;p&gt;Well… turns out…&lt;/p&gt;

&lt;p&gt;When submitting a support request you had to fill around 20 fields with information about product versions, OS version and all kinds semi relevant information.
Ok, that does make some sense. But you had to fill out those fields every single time you wrote a comment or answered at questions. Every. Single. Time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern number one&lt;/strong&gt;: Make your customer jump trough hoops.&lt;br /&gt;
In order to teeming masses at bay make sure it takes a lot of effort to get support. This is a war of attrition and the more hoops you have the quicker the customer will surrender.&lt;/p&gt;

&lt;p&gt;Hoops sufficiently jumped we got the first reply from Oracle support.
“Hi. Please install this patch and see if it fixes the problem”.
The release note for that patch does not mention anything about our problem but we’ll give a shot. Didn’t fix the problem.&lt;br /&gt;
&lt;strong&gt;Pattern number two&lt;/strong&gt;: Try and look like you’re doing something.&lt;/p&gt;

&lt;p&gt;But make sure the customer has to do the actual work. Customers just love it when it seems like you’re helping. Just make sure you don’t actually have to do any work. Supplying random software updates work great!&lt;/p&gt;

&lt;p&gt;So we got back to Oracle and told them that the patch did not work. And so they suggested that we try installing another patch.
We did. It did not work.&lt;/p&gt;

&lt;p&gt;Back to Oracle that then suggested we install the first patch we gave them.&lt;br /&gt;
&lt;strong&gt;Pattern number three&lt;/strong&gt;: Never read the full context. Only ever read the newest comment – remember you have 23746 other tickets to get trough today.&lt;/p&gt;

&lt;p&gt;Back to Oracle which then told us that we we’re using xml signatures wrongly.&lt;br /&gt;
&lt;strong&gt;Pattern number four&lt;/strong&gt;: Make sure supporters can ask questions that take a lot of effort to answer.&lt;/p&gt;

&lt;p&gt;So we reread the XML signature specs and the XML canonicalization specs. We went and got a second opinion.
We then spend hours explaining why it should work to a host of different supporters.&lt;br /&gt;
&lt;strong&gt;Pattern number five&lt;/strong&gt;: Don’t become personally involved. You might end up actually caring.&lt;/p&gt;

&lt;p&gt;Oracle then suggested we stop using XML signatures.&lt;br /&gt;
&lt;strong&gt;Pattern number six&lt;/strong&gt;: Try to convince the customer that they don’t really need that feature.&lt;/p&gt;

&lt;p&gt;Oracle then said: The error is not in a component we made.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern number seven&lt;/strong&gt;: Shift the blame. If you can get the customer to go elsewhere with his problem then you won.
Sure it’s in a component that is part of our product – but we did not write that component. Go talk to those guys.&lt;/p&gt;

&lt;p&gt;But then after &lt;em&gt;two years&lt;/em&gt; we finally got the patch we needed.&lt;/p&gt;

&lt;p&gt;#Example 2: Philips (2015-2016)&lt;/p&gt;

&lt;p&gt;This second example is from the consumer space. I went and bought a Philips TV (Model: 50/PUS6809/12. Do not by that TV.).
It quickly turned out to have a host of problems:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Randomly turning on 3D mode&lt;/li&gt;
  &lt;li&gt;Randomly turn down the contrast by 50%&lt;/li&gt;
  &lt;li&gt;Show “Certificate expired” error messages that cannot be dismissed&lt;/li&gt;
  &lt;li&gt;Unable to wake up from Stand-By&lt;/li&gt;
  &lt;li&gt;Suddenly Hobbit stopped working.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the dummy I am I turned to support instead of just returning the TV.&lt;/p&gt;

&lt;p&gt;Philips: Please install this update (that has nothing to do with any of the errors you are experiencing)&lt;br /&gt;
&lt;strong&gt;Pattern number two:&lt;/strong&gt; Try and look like you’re doing something&lt;/p&gt;

&lt;p&gt;Philips: Please “reinstall your TV” loosing all your settings in the process.&lt;br /&gt;
&lt;strong&gt;Pattern number one:&lt;/strong&gt; Make your customer jump trough hoops.&lt;/p&gt;

&lt;p&gt;Philips: The TV stations changed the way they are doing HbbTv.&lt;br /&gt;
&lt;strong&gt;Pattern number seven:&lt;/strong&gt; Shift the blame.&lt;/p&gt;

&lt;p&gt;Philips: Please provide screenshots of the errors and please provide information on signal strength for all your channels.&lt;br /&gt;
&lt;strong&gt;Pattern number four:&lt;/strong&gt; Make sure supporters can ask questions that take a lot of effort to answer.&lt;/p&gt;

&lt;p&gt;Philips: Try turning off HbbTV&lt;br /&gt;
&lt;strong&gt;Pattern number six:&lt;/strong&gt; Try to convince the customer that they don’t really need that feature.&lt;/p&gt;

&lt;p&gt;Philips: Ok, just one more question.&lt;br /&gt;
&lt;strong&gt;Pattern number eight:&lt;/strong&gt; Feign progress. At some point the customer is going to get angry. That means you’re close to winning the war of attrition. So pretend to have only a few more questions.
But make sure you have plenty of hoops left for the customer to jump tough.&lt;/p&gt;

&lt;p&gt;Eventually I gave up after dealing with Philips support for three months.&lt;/p&gt;

&lt;p&gt;#Conclusion&lt;/p&gt;

&lt;p&gt;In case you skipped the last two sections I’ll summarize the patterns for doing horrible support:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Make your customer jump trough hoops&lt;/li&gt;
  &lt;li&gt;Try and look like you’re doing something&lt;/li&gt;
  &lt;li&gt;Never read the full context. Only ever read the newest comment&lt;/li&gt;
  &lt;li&gt;Make sure supporters can ask questions that take a lot of effort to answer&lt;/li&gt;
  &lt;li&gt;Don’t become personally involved. You might end up actually caring.&lt;/li&gt;
  &lt;li&gt;Try to convince the customer that they don’t really need that feature.&lt;/li&gt;
  &lt;li&gt;Shift the blame.&lt;/li&gt;
  &lt;li&gt;Feign progress.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Neither Oracle nor Philips are dumb organizations. They have just figured out that you only need their support after they have made their sale.
That means support is just something that eats into their margins.&lt;/p&gt;

&lt;p&gt;Obviously if people were to ask me if they should use an Oracle Enterprise Service Bus or by a Philips TV I would advice against it.
And equally obviously is not hurting them enough or they would have changed their tactics.&lt;/p&gt;

&lt;p&gt;But if you’re a small business and each individual customer actually has an impact on your business I would suggest you reverse the patterns outlined above:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Make getting support as easy as possible&lt;/li&gt;
  &lt;li&gt;Do something to help the customer&lt;/li&gt;
  &lt;li&gt;Know the full context before answering the customer.&lt;/li&gt;
  &lt;li&gt;Make sure the customer has to work as little as possible&lt;/li&gt;
  &lt;li&gt;Do become personally involved. Actually care.&lt;/li&gt;
  &lt;li&gt;Take responsibility for your features.&lt;/li&gt;
  &lt;li&gt;Own up to your mistakes.&lt;/li&gt;
  &lt;li&gt;Provide honest status updates.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Ending on a up note: It’s been 4 years since I last used a service bus and I now watch way less TV.&lt;/em&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 27 Jan 2016 19:39:48 +0000</pubDate>
        <link>http://blog.mejer-hansen.dk/2016/01/27/how-to-do-support-if-you-dont-value-your-customers.html</link>
        <guid isPermaLink="true">http://blog.mejer-hansen.dk/2016/01/27/how-to-do-support-if-you-dont-value-your-customers.html</guid>
        
        
      </item>
    
  </channel>
</rss>
