summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--_build/content/articles/dont-let-it-crash.asciidoc141
-rw-r--r--articles/cowboy-2.0.0-pre.4/index.html2
-rw-r--r--articles/cowboy2-qs/index.html2
-rw-r--r--articles/dont-let-it-crash/index.html281
-rw-r--r--articles/erlang-scalability/index.html2
-rw-r--r--articles/erlang-validate-utf8/index.html2
-rw-r--r--articles/erlang.mk-and-relx/index.html2
-rw-r--r--articles/erlanger-playbook-september-2015-update/index.html2
-rw-r--r--articles/erlanger-playbook/index.html2
-rw-r--r--articles/farwest-funded/index.html2
-rw-r--r--articles/index.html34
-rw-r--r--articles/index.xml184
-rw-r--r--articles/january-2014-status/index.html2
-rw-r--r--articles/ml-archives/index.html2
-rw-r--r--articles/on-open-source/index.html2
-rw-r--r--articles/page/2/index.html17
-rw-r--r--articles/ranch-1.3/index.html2
-rw-r--r--articles/ranch-ftp/index.html2
-rw-r--r--articles/the-story-so-far/index.html2
-rw-r--r--articles/tictactoe/index.html2
-rw-r--r--articles/website-update/index.html2
-rw-r--r--articles/xerl-0.1-empty-modules/index.html2
-rw-r--r--articles/xerl-0.2-two-modules/index.html2
-rw-r--r--articles/xerl-0.3-atomic-expressions/index.html2
-rw-r--r--articles/xerl-0.4-expression-separator/index.html2
-rw-r--r--articles/xerl-0.5-intermediate-module/index.html2
-rw-r--r--docs/en/erlang.mk/1/guide/app.asciidoc11
-rw-r--r--docs/en/erlang.mk/1/guide/app/index.html9
-rw-r--r--donate/index.html2
-rw-r--r--index.html2
-rw-r--r--index.xml281
-rw-r--r--services/index.html2
-rw-r--r--sitemap.xml7
33 files changed, 774 insertions, 239 deletions
diff --git a/_build/content/articles/dont-let-it-crash.asciidoc b/_build/content/articles/dont-let-it-crash.asciidoc
new file mode 100644
index 00000000..f4f15c79
--- /dev/null
+++ b/_build/content/articles/dont-let-it-crash.asciidoc
@@ -0,0 +1,141 @@
++++
+date = "2017-01-22T00:00:00+01:00"
+title = "Don't let it crash"
+
++++
+
+We have a specific mindset when writing Erlang
+programs. We focus on the normal execution of the
+program and don't handle most of the errors that may
+occur. We sometimes call this normal execution the
+'happy path'.
+
+The general pattern behind writing only for the
+'happy path', letting the VM catch errors (writing
+them to a log for future consumption) and then
+having a supervisor restart the processes that
+failed from a clean state, has a name. We call it
+'let it crash'; and it drives many of our design
+decisions.
+
+It's a really great way to program and the results
+are fantastic compared to most other programming
+languages. And yet, 'let it crash' barely convinced
+anyone that they should use Erlang. Why would that
+be?
+
+You may already know that Cowboy is capable of
+handling at least 2 million Websocket connections
+on a single server. This is in large part thanks
+to the capabilities of the VM. Still, 2 million
+is good, much better than most other servers can
+do.
+
+Cowboy is not just a Websocket server; it's also
+an HTTP and HTTP/2 server, and it handles many
+related features like long polling or the parsing
+of most request headers.
+
+Can you guess how large the Cowboy codebase is,
+without looking at the source?
+
+Do make sure you have a clear answer in your mind
+before you go check.
+
+Good, you are back. Now what were the results? If
+I am correct, you overestimated the size of Cowboy.
+Cowboy is in fact about five thousand lines of code.
+You probably thought it was at least ten thousand.
+About eighty percent of readers will have
+overestimated the size of Cowboy. And you did only
+because I mentioned it can handle millions of
+Websocket connections.
+
+Numerous studies show this effect. Just mentioning
+the large number already prepared your mind to think
+in that direction. Repeating the number made you
+focus even more on it. Then the question asked for
+a number, which ended up larger than the reality.
+
+The same effect can be applied to negotiation for
+example. You generally want to start by giving your
+offer (and not let the other party initiate) and
+you want to give a really large number first. You
+can also prepare your customer by mentioning an even
+larger number in the previous discussion.
+
+And it's not just numbers either. An experiment
+showed that just by looking at an image of clouds,
+customers of a pillow store were buying pillows
+more comfortable (and more expensive) than those
+who didn't see that image.
+
+This is the power of associations. It is covered in
+much larger detail in the books
+https://www.amazon.com/Influence-Psychology-Persuasion-Robert-Cialdini/dp/006124189X[Influence]
+and
+https://www.amazon.com/Pre-Suasion-Revolutionary-Way-Influence-Persuade/dp/1501109790[Pre-suasion].
+I highly recommend reading those and applying what
+you learn to your daily life. I'm definitely not
+a professional psychologist so take this post with
+a grain of salt.
+
+When selling Erlang, whether we are selling it to
+a customer or trying to convince a developer friend
+to start using it, we often talk about how Erlang
+'lets you sleep at night', that it is auto healing
+and always gets fantastic uptimes.
+
+And then we talk about 'let it crash'.
+
+And we describe what it means.
+
+We might as well just say that Erlang crashes a lot
+and then take the door. It would have the same effect.
+It doesn't even stop at programs crashing. You know
+what else crashes? Cars, planes, trains. Often with
+disastrous consequences. Is that really the message
+we want to convey?
+
+They even https://img.youtube.com/vi/oEUBW2lCkIk/0.jpg[printed it on a t-shirt]!
+Keep calm and let it crash. It's the kind of t-shirt
+you probably shouldn't wear in an airport, and for good
+reasons. A few people did, then realized what they were
+wearing and were not too smug about it.
+
+And yet this is how we sell Erlang.
+
+A better way would be to focus on the positives, of
+course, but also to make sure that those positives
+are phrased in a way that prevents bad associations
+to be formed in people's minds.
+
+Instead of 'let it crash', you can say that Erlang
+has 'auto healing mechanisms'. Healing is a good
+thing and accurately describes what happens in the
+system.
+
+Should you need to go into more details, you will
+probably want to avoid 'recover from crashes' and
+instead say 'recover from exceptions'. Exceptions
+are a pretty neutral word and, should you explain
+what you mean by that, you can talk about exceptions
+that occur for reasons unrelated to Erlang, like
+hardware failure or network instability.
+
+The trick is to always use positive words and
+phrases to describe Erlang, and to use external
+factors to explain how Erlang deals with failures.
+Never mention the failures internal to Erlang
+systems unless you are asked specifically, in
+which case you can say that the auto healing
+applies to all exceptions.
+
+The 'let it crash' philosophy is great when
+learning Erlang or when writing fault-tolerant
+systems. But it's not going to convince anyone
+to use it unless they were already looking for
+it.
+
+Do you like this post? Tell me on Twitter. I might
+make more.
diff --git a/articles/cowboy-2.0.0-pre.4/index.html b/articles/cowboy-2.0.0-pre.4/index.html
index 092ea08e..3ce369fb 100644
--- a/articles/cowboy-2.0.0-pre.4/index.html
+++ b/articles/cowboy-2.0.0-pre.4/index.html
@@ -194,6 +194,8 @@ added back.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/cowboy2-qs/index.html b/articles/cowboy2-qs/index.html
index da450bf8..42343c77 100644
--- a/articles/cowboy2-qs/index.html
+++ b/articles/cowboy2-qs/index.html
@@ -233,6 +233,8 @@ thoughts that went into this rather than just the conclusion.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/dont-let-it-crash/index.html b/articles/dont-let-it-crash/index.html
new file mode 100644
index 00000000..9fe54196
--- /dev/null
+++ b/articles/dont-let-it-crash/index.html
@@ -0,0 +1,281 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="description" content="">
+ <meta name="author" content="Loïc Hoguin based on a design from (Soft10) Pol Cámara">
+
+ <meta name="generator" content="Hugo 0.17" />
+
+ <title>Nine Nines: Don&#39;t let it crash</title>
+
+ <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic' rel='stylesheet' type='text/css'>
+
+ <link href="/css/bootstrap.min.css" rel="stylesheet">
+ <link href="/css/99s.css" rel="stylesheet">
+
+ <link rel="shortcut icon" href="/img/ico/favicon.ico">
+ <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/img/ico/apple-touch-icon-114.png">
+ <link rel="apple-touch-icon-precomposed" sizes="72x72" href="/img/ico/apple-touch-icon-72.png">
+ <link rel="apple-touch-icon-precomposed" href="/img/ico/apple-touch-icon-57.png">
+
+
+</head>
+
+
+<body class="">
+ <header id="page-head">
+ <div id="topbar" class="container">
+ <div class="row">
+ <div class="span2">
+ <h1 id="logo"><a href="/" title="99s">99s</a></h1>
+ </div>
+ <div class="span10">
+
+ <div id="side-header">
+ <nav>
+ <ul>
+ <li class="active"><a title="Hear my thoughts" href="/articles">Articles</a></li>
+ <li><a title="Watch my talks" href="/talks">Talks</a></li>
+ <li><a title="Read the docs" href="/docs">Documentation</a></li>
+ <li><a title="Request my services" href="/services">Consulting & Training</a></li>
+ </ul>
+ </nav>
+ <ul id="social">
+ <li>
+ <a href="https://github.com/ninenines" title="Check my Github repositories"><img src="/img/ico_github.png" data-hover="/img/ico_github_alt.png" alt="Github"></a>
+ </li>
+ <li>
+ <a title="Keep in touch!" href="http://twitter.com/lhoguin"><img src="/img/ico_microblog.png" data-hover="/img/ico_microblog_alt.png"></a>
+ </li>
+ <li>
+ <a title="Contact me" href="mailto:[email protected]"><img src="/img/ico_mail.png" data-hover="/img/ico_mail_alt.png"></a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+</header>
+
+<div id="contents">
+<div class="container">
+<div class="row">
+<div class="span9 maincol">
+
+<article class="blog_item">
+<header>
+ <h1 class="lined-header"><span>Don&#39;t let it crash</span></h1>
+ <p class="date">
+ <span class="day">22</span>
+ <span class="month">Jan</span>
+ </p>
+</header>
+
+<div class="paragraph"><p>We have a specific mindset when writing Erlang
+programs. We focus on the normal execution of the
+program and don&#8217;t handle most of the errors that may
+occur. We sometimes call this normal execution the
+<em>happy path</em>.</p></div>
+<div class="paragraph"><p>The general pattern behind writing only for the
+<em>happy path</em>, letting the VM catch errors (writing
+them to a log for future consumption) and then
+having a supervisor restart the processes that
+failed from a clean state, has a name. We call it
+<em>let it crash</em>; and it drives many of our design
+decisions.</p></div>
+<div class="paragraph"><p>It&#8217;s a really great way to program and the results
+are fantastic compared to most other programming
+languages. And yet, <em>let it crash</em> barely convinced
+anyone that they should use Erlang. Why would that
+be?</p></div>
+<div class="paragraph"><p>You may already know that Cowboy is capable of
+handling at least 2 million Websocket connections
+on a single server. This is in large part thanks
+to the capabilities of the VM. Still, 2 million
+is good, much better than most other servers can
+do.</p></div>
+<div class="paragraph"><p>Cowboy is not just a Websocket server; it&#8217;s also
+an HTTP and HTTP/2 server, and it handles many
+related features like long polling or the parsing
+of most request headers.</p></div>
+<div class="paragraph"><p>Can you guess how large the Cowboy codebase is,
+without looking at the source?</p></div>
+<div class="paragraph"><p>Do make sure you have a clear answer in your mind
+before you go check.</p></div>
+<div class="paragraph"><p>Good, you are back. Now what were the results? If
+I am correct, you overestimated the size of Cowboy.
+Cowboy is in fact about five thousand lines of code.
+You probably thought it was at least ten thousand.
+About eighty percent of readers will have
+overestimated the size of Cowboy. And you did only
+because I mentioned it can handle millions of
+Websocket connections.</p></div>
+<div class="paragraph"><p>Numerous studies show this effect. Just mentioning
+the large number already prepared your mind to think
+in that direction. Repeating the number made you
+focus even more on it. Then the question asked for
+a number, which ended up larger than the reality.</p></div>
+<div class="paragraph"><p>The same effect can be applied to negotiation for
+example. You generally want to start by giving your
+offer (and not let the other party initiate) and
+you want to give a really large number first. You
+can also prepare your customer by mentioning an even
+larger number in the previous discussion.</p></div>
+<div class="paragraph"><p>And it&#8217;s not just numbers either. An experiment
+showed that just by looking at an image of clouds,
+customers of a pillow store were buying pillows
+more comfortable (and more expensive) than those
+who didn&#8217;t see that image.</p></div>
+<div class="paragraph"><p>This is the power of associations. It is covered in
+much larger detail in the books
+<a href="https://www.amazon.com/Influence-Psychology-Persuasion-Robert-Cialdini/dp/006124189X">Influence</a>
+and
+<a href="https://www.amazon.com/Pre-Suasion-Revolutionary-Way-Influence-Persuade/dp/1501109790">Pre-suasion</a>.
+I highly recommend reading those and applying what
+you learn to your daily life. I&#8217;m definitely not
+a professional psychologist so take this post with
+a grain of salt.</p></div>
+<div class="paragraph"><p>When selling Erlang, whether we are selling it to
+a customer or trying to convince a developer friend
+to start using it, we often talk about how Erlang
+<em>lets you sleep at night</em>, that it is auto healing
+and always gets fantastic uptimes.</p></div>
+<div class="paragraph"><p>And then we talk about <em>let it crash</em>.</p></div>
+<div class="paragraph"><p>And we describe what it means.</p></div>
+<div class="paragraph"><p>We might as well just say that Erlang crashes a lot
+and then take the door. It would have the same effect.
+It doesn&#8217;t even stop at programs crashing. You know
+what else crashes? Cars, planes, trains. Often with
+disastrous consequences. Is that really the message
+we want to convey?</p></div>
+<div class="paragraph"><p>They even <a href="https://img.youtube.com/vi/oEUBW2lCkIk/0.jpg">printed it on a t-shirt</a>!
+Keep calm and let it crash. It&#8217;s the kind of t-shirt
+you probably shouldn&#8217;t wear in an airport, and for good
+reasons. A few people did, then realized what they were
+wearing and were not too smug about it.</p></div>
+<div class="paragraph"><p>And yet this is how we sell Erlang.</p></div>
+<div class="paragraph"><p>A better way would be to focus on the positives, of
+course, but also to make sure that those positives
+are phrased in a way that prevents bad associations
+to be formed in people&#8217;s minds.</p></div>
+<div class="paragraph"><p>Instead of <em>let it crash</em>, you can say that Erlang
+has <em>auto healing mechanisms</em>. Healing is a good
+thing and accurately describes what happens in the
+system.</p></div>
+<div class="paragraph"><p>Should you need to go into more details, you will
+probably want to avoid <em>recover from crashes</em> and
+instead say <em>recover from exceptions</em>. Exceptions
+are a pretty neutral word and, should you explain
+what you mean by that, you can talk about exceptions
+that occur for reasons unrelated to Erlang, like
+hardware failure or network instability.</p></div>
+<div class="paragraph"><p>The trick is to always use positive words and
+phrases to describe Erlang, and to use external
+factors to explain how Erlang deals with failures.
+Never mention the failures internal to Erlang
+systems unless you are asked specifically, in
+which case you can say that the auto healing
+applies to all exceptions.</p></div>
+<div class="paragraph"><p>The <em>let it crash</em> philosophy is great when
+learning Erlang or when writing fault-tolerant
+systems. But it&#8217;s not going to convince anyone
+to use it unless they were already looking for
+it.</p></div>
+<div class="paragraph"><p>Do you like this post? Tell me on Twitter. I might
+make more.</p></div>
+
+</article>
+</div>
+
+<div class="span3 sidecol">
+<h3>More articles</h3>
+<ul id="articles-nav" class="extra_margin">
+
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
+ <li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
+
+ <li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
+
+ <li><a href="https://ninenines.eu/articles/ml-archives/">Mailing list archived</a></li>
+
+ <li><a href="https://ninenines.eu/articles/website-update/">Website update</a></li>
+
+ <li><a href="https://ninenines.eu/articles/erlanger-playbook-september-2015-update/">The Erlanger Playbook September 2015 Update</a></li>
+
+ <li><a href="https://ninenines.eu/articles/erlanger-playbook/">The Erlanger Playbook</a></li>
+
+ <li><a href="https://ninenines.eu/articles/erlang-validate-utf8/">Validating UTF-8 binaries with Erlang</a></li>
+
+ <li><a href="https://ninenines.eu/articles/on-open-source/">On open source</a></li>
+
+ <li><a href="https://ninenines.eu/articles/the-story-so-far/">The story so far</a></li>
+
+ <li><a href="https://ninenines.eu/articles/cowboy2-qs/">Cowboy 2.0 and query strings</a></li>
+
+ <li><a href="https://ninenines.eu/articles/january-2014-status/">January 2014 status</a></li>
+
+ <li><a href="https://ninenines.eu/articles/farwest-funded/">Farwest got funded!</a></li>
+
+ <li><a href="https://ninenines.eu/articles/erlang.mk-and-relx/">Build Erlang releases with Erlang.mk and Relx</a></li>
+
+ <li><a href="https://ninenines.eu/articles/xerl-0.5-intermediate-module/">Xerl: intermediate module</a></li>
+
+ <li><a href="https://ninenines.eu/articles/xerl-0.4-expression-separator/">Xerl: expression separator</a></li>
+
+ <li><a href="https://ninenines.eu/articles/erlang-scalability/">Erlang Scalability</a></li>
+
+ <li><a href="https://ninenines.eu/articles/xerl-0.3-atomic-expressions/">Xerl: atomic expressions</a></li>
+
+ <li><a href="https://ninenines.eu/articles/xerl-0.2-two-modules/">Xerl: two modules</a></li>
+
+ <li><a href="https://ninenines.eu/articles/xerl-0.1-empty-modules/">Xerl: empty modules</a></li>
+
+ <li><a href="https://ninenines.eu/articles/ranch-ftp/">Build an FTP Server with Ranch in 30 Minutes</a></li>
+
+ <li><a href="https://ninenines.eu/articles/tictactoe/">Erlang Tic Tac Toe</a></li>
+
+</ul>
+
+<h3>Feedback</h3>
+<p>Feel free to <a href="mailto:[email protected]">email us</a>
+if you found any mistake or need clarification on any of the
+articles.</p>
+
+</div>
+</div>
+</div>
+</div>
+
+ <footer>
+ <div class="container">
+ <div class="row">
+ <div class="span6">
+ <p id="scroll-top"><a href="#">↑ Scroll to top</a></p>
+ <nav>
+ <ul>
+ <li><a href="mailto:[email protected]" title="Contact us">Contact us</a></li><li><a href="https://github.com/ninenines/ninenines.github.io" title="Github repository">Contribute to this site</a></li>
+ </ul>
+ </nav>
+ </div>
+ <div class="span6 credits">
+ <p><img src="/img/footer_logo.png"></p>
+ <p>Copyright &copy; Loïc Hoguin 2012-2016</p>
+ </div>
+ </div>
+ </div>
+ </footer>
+
+
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
+ <script src="/js/bootstrap-carousel.js"></script>
+ <script src="/js/bootstrap-dropdown.js"></script>
+ <script src="/js/custom.js"></script>
+ </body>
+</html>
+
diff --git a/articles/erlang-scalability/index.html b/articles/erlang-scalability/index.html
index 46871c4d..04a4c42f 100644
--- a/articles/erlang-scalability/index.html
+++ b/articles/erlang-scalability/index.html
@@ -218,6 +218,8 @@ concurrently.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/erlang-validate-utf8/index.html b/articles/erlang-validate-utf8/index.html
index 6940ae6b..cc0068ce 100644
--- a/articles/erlang-validate-utf8/index.html
+++ b/articles/erlang-validate-utf8/index.html
@@ -269,6 +269,8 @@ http://www.gnu.org/software/src-highlite -->
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/erlang.mk-and-relx/index.html b/articles/erlang.mk-and-relx/index.html
index 0173f34a..0a966c02 100644
--- a/articles/erlang.mk-and-relx/index.html
+++ b/articles/erlang.mk-and-relx/index.html
@@ -172,6 +172,8 @@ containing all the flags to pass to the Erlang VM, for example
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/erlanger-playbook-september-2015-update/index.html b/articles/erlanger-playbook-september-2015-update/index.html
index cb472372..0b8026b9 100644
--- a/articles/erlanger-playbook-september-2015-update/index.html
+++ b/articles/erlanger-playbook-september-2015-update/index.html
@@ -97,6 +97,8 @@ will be used to allow me to work on open source full time.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/erlanger-playbook/index.html b/articles/erlanger-playbook/index.html
index b8345523..4ec81c34 100644
--- a/articles/erlanger-playbook/index.html
+++ b/articles/erlanger-playbook/index.html
@@ -150,6 +150,8 @@ You will receive updates to the book for free as soon as they are available.</p>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/farwest-funded/index.html b/articles/farwest-funded/index.html
index def68b84..a3ec6011 100644
--- a/articles/farwest-funded/index.html
+++ b/articles/farwest-funded/index.html
@@ -105,6 +105,8 @@ can help!</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/index.html b/articles/index.html
index b1edcd8a..9e473f54 100644
--- a/articles/index.html
+++ b/articles/index.html
@@ -74,6 +74,23 @@
<article class="blog_item">
<header>
+ <h2><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></h2>
+ <p class="date">
+ <span class="day">22</span>
+ <span class="month">Jan</span>
+ </p>
+ </header>
+
+ <p>We have a specific mindset when writing Erlang programs. We focus on the normal execution of the program and don&#8217;t handle most of the errors that may occur. We sometimes call this normal execution the happy path.
+ The general pattern behind writing only for the happy path, letting the VM catch errors (writing them to a log for future consumption) and then having a supervisor restart the processes that failed from a clean state, has a name.</p>
+
+ <p style="text-align:right">
+ <a class="read_more" href="https://ninenines.eu/articles/dont-let-it-crash/">Read More</a>
+ </p>
+ </article>
+
+ <article class="blog_item">
+ <header>
<h2><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></h2>
<p class="date">
<span class="day">03</span>
@@ -415,23 +432,6 @@
</p>
</article>
- <article class="blog_item">
- <header>
- <h2><a href="https://ninenines.eu/articles/ranch-ftp/">Build an FTP Server with Ranch in 30 Minutes</a></h2>
- <p class="date">
- <span class="day">14</span>
- <span class="month">Nov</span>
- </p>
- </header>
-
- <p>Last week I was speaking at the London Erlang Factory Lite where I presented a live demonstration of building an FTP server using Ranch. As there was no slide, you should use this article as a reference instead.
- The goal of this article is to showcase how to use Ranch for writing a network protocol implementation, how Ranch gets out of the way to let you write the code that matters, and the common techniques used when writing servers.</p>
-
- <p style="text-align:right">
- <a class="read_more" href="https://ninenines.eu/articles/ranch-ftp/">Read More</a>
- </p>
- </article>
-
<nav class="pagination" role="pagination">
diff --git a/articles/index.xml b/articles/index.xml
index 40507060..dbb9bb8f 100644
--- a/articles/index.xml
+++ b/articles/index.xml
@@ -6,10 +6,131 @@
<description>Recent content in Articles-rsses on Nine Nines</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
- <lastBuildDate>Tue, 03 Jan 2017 00:00:00 +0100</lastBuildDate>
+ <lastBuildDate>Sun, 22 Jan 2017 00:00:00 +0100</lastBuildDate>
<atom:link href="https://ninenines.eu/articles/index.xml" rel="self" type="application/rss+xml" />
<item>
+ <title>Don&#39;t let it crash</title>
+ <link>https://ninenines.eu/articles/dont-let-it-crash/</link>
+ <pubDate>Sun, 22 Jan 2017 00:00:00 +0100</pubDate>
+
+ <guid>https://ninenines.eu/articles/dont-let-it-crash/</guid>
+ <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;We have a specific mindset when writing Erlang
+programs. We focus on the normal execution of the
+program and don&amp;#8217;t handle most of the errors that may
+occur. We sometimes call this normal execution the
+&lt;em&gt;happy path&lt;/em&gt;.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The general pattern behind writing only for the
+&lt;em&gt;happy path&lt;/em&gt;, letting the VM catch errors (writing
+them to a log for future consumption) and then
+having a supervisor restart the processes that
+failed from a clean state, has a name. We call it
+&lt;em&gt;let it crash&lt;/em&gt;; and it drives many of our design
+decisions.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;It&amp;#8217;s a really great way to program and the results
+are fantastic compared to most other programming
+languages. And yet, &lt;em&gt;let it crash&lt;/em&gt; barely convinced
+anyone that they should use Erlang. Why would that
+be?&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;You may already know that Cowboy is capable of
+handling at least 2 million Websocket connections
+on a single server. This is in large part thanks
+to the capabilities of the VM. Still, 2 million
+is good, much better than most other servers can
+do.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Cowboy is not just a Websocket server; it&amp;#8217;s also
+an HTTP and HTTP/2 server, and it handles many
+related features like long polling or the parsing
+of most request headers.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Can you guess how large the Cowboy codebase is,
+without looking at the source?&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Do make sure you have a clear answer in your mind
+before you go check.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Good, you are back. Now what were the results? If
+I am correct, you overestimated the size of Cowboy.
+Cowboy is in fact about five thousand lines of code.
+You probably thought it was at least ten thousand.
+About eighty percent of readers will have
+overestimated the size of Cowboy. And you did only
+because I mentioned it can handle millions of
+Websocket connections.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Numerous studies show this effect. Just mentioning
+the large number already prepared your mind to think
+in that direction. Repeating the number made you
+focus even more on it. Then the question asked for
+a number, which ended up larger than the reality.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The same effect can be applied to negotiation for
+example. You generally want to start by giving your
+offer (and not let the other party initiate) and
+you want to give a really large number first. You
+can also prepare your customer by mentioning an even
+larger number in the previous discussion.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And it&amp;#8217;s not just numbers either. An experiment
+showed that just by looking at an image of clouds,
+customers of a pillow store were buying pillows
+more comfortable (and more expensive) than those
+who didn&amp;#8217;t see that image.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is the power of associations. It is covered in
+much larger detail in the books
+&lt;a href=&#34;https://www.amazon.com/Influence-Psychology-Persuasion-Robert-Cialdini/dp/006124189X&#34;&gt;Influence&lt;/a&gt;
+and
+&lt;a href=&#34;https://www.amazon.com/Pre-Suasion-Revolutionary-Way-Influence-Persuade/dp/1501109790&#34;&gt;Pre-suasion&lt;/a&gt;.
+I highly recommend reading those and applying what
+you learn to your daily life. I&amp;#8217;m definitely not
+a professional psychologist so take this post with
+a grain of salt.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;When selling Erlang, whether we are selling it to
+a customer or trying to convince a developer friend
+to start using it, we often talk about how Erlang
+&lt;em&gt;lets you sleep at night&lt;/em&gt;, that it is auto healing
+and always gets fantastic uptimes.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And then we talk about &lt;em&gt;let it crash&lt;/em&gt;.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And we describe what it means.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;We might as well just say that Erlang crashes a lot
+and then take the door. It would have the same effect.
+It doesn&amp;#8217;t even stop at programs crashing. You know
+what else crashes? Cars, planes, trains. Often with
+disastrous consequences. Is that really the message
+we want to convey?&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;They even &lt;a href=&#34;https://img.youtube.com/vi/oEUBW2lCkIk/0.jpg&#34;&gt;printed it on a t-shirt&lt;/a&gt;!
+Keep calm and let it crash. It&amp;#8217;s the kind of t-shirt
+you probably shouldn&amp;#8217;t wear in an airport, and for good
+reasons. A few people did, then realized what they were
+wearing and were not too smug about it.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And yet this is how we sell Erlang.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;A better way would be to focus on the positives, of
+course, but also to make sure that those positives
+are phrased in a way that prevents bad associations
+to be formed in people&amp;#8217;s minds.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Instead of &lt;em&gt;let it crash&lt;/em&gt;, you can say that Erlang
+has &lt;em&gt;auto healing mechanisms&lt;/em&gt;. Healing is a good
+thing and accurately describes what happens in the
+system.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Should you need to go into more details, you will
+probably want to avoid &lt;em&gt;recover from crashes&lt;/em&gt; and
+instead say &lt;em&gt;recover from exceptions&lt;/em&gt;. Exceptions
+are a pretty neutral word and, should you explain
+what you mean by that, you can talk about exceptions
+that occur for reasons unrelated to Erlang, like
+hardware failure or network instability.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The trick is to always use positive words and
+phrases to describe Erlang, and to use external
+factors to explain how Erlang deals with failures.
+Never mention the failures internal to Erlang
+systems unless you are asked specifically, in
+which case you can say that the auto healing
+applies to all exceptions.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The &lt;em&gt;let it crash&lt;/em&gt; philosophy is great when
+learning Erlang or when writing fault-tolerant
+systems. But it&amp;#8217;s not going to convince anyone
+to use it unless they were already looking for
+it.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Do you like this post? Tell me on Twitter. I might
+make more.&lt;/p&gt;&lt;/div&gt;
+</description>
+ </item>
+
+ <item>
<title>Cowboy 2.0 pre-release 4</title>
<link>https://ninenines.eu/articles/cowboy-2.0.0-pre.4/</link>
<pubDate>Tue, 03 Jan 2017 00:00:00 +0100</pubDate>
@@ -1527,66 +1648,5 @@ http://www.gnu.org/software/src-highlite --&gt;
</description>
</item>
- <item>
- <title>Xerl: expression separator</title>
- <link>https://ninenines.eu/articles/xerl-0.4-expression-separator/</link>
- <pubDate>Fri, 01 Mar 2013 00:00:00 +0100</pubDate>
-
- <guid>https://ninenines.eu/articles/xerl-0.4-expression-separator/</guid>
- <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;As promised we are adding an expression separator this time.
-This will be short and easy.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;In the tokenizer we only need to add a line recognizing the
-comma as a valid token.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;listingblock&#34;&gt;
-&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite --&gt;
-&lt;pre&gt;&lt;tt&gt;, &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; {&lt;span style=&#34;color: #FF6600&#34;&gt;token&lt;/span&gt;, {&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;,&#39;&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;TokenLine&lt;/span&gt;}}&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Then we need to change the following lines in the parser:&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;listingblock&#34;&gt;
-&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite --&gt;
-&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt;]&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;
-&lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt; | &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$2&#39;&lt;/span&gt;]&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And add a comma between the expressions on the second line:&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;listingblock&#34;&gt;
-&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite --&gt;
-&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt;]&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;
-&lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;,&#39;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt; | &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$3&#39;&lt;/span&gt;]&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;That takes care of everything except the optional trailing
-comma at the end of our lists of expressions. We just need an
-additional rule to take care of this.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;listingblock&#34;&gt;
-&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite --&gt;
-&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;color: #FF6600&#34;&gt;exprs&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;expr&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;&#39;,&#39;&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color: #FF6600&#34;&gt;&#39;$1&#39;&lt;/span&gt;]&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;That&amp;#8217;s it.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Wondering why we don&amp;#8217;t have this optional trailing comma in
-Erlang considering how easy it was and the number of people
-complaining about it? Yeah, me too. But that&amp;#8217;s for someone else
-to answer.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Another change I want to talk about is a simple modification
-of the compiler code to use an &lt;code&gt;#env{}&lt;/code&gt; record for
-tracking state instead of passing around individual variables.
-This will be required later on when we make modules into proper
-expressions so I thought it was a good idea to anticipate.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;ulist&#34;&gt;&lt;ul&gt;
-&lt;li&gt;
-&lt;p&gt;
-&lt;a href=&#34;https://github.com/extend/xerl/blob/0.4/&#34;&gt;View the source&lt;/a&gt;
-&lt;/p&gt;
-&lt;/li&gt;
-&lt;/ul&gt;&lt;/div&gt;
-</description>
- </item>
-
</channel>
</rss> \ No newline at end of file
diff --git a/articles/january-2014-status/index.html b/articles/january-2014-status/index.html
index 24fc69a2..da0a5b8d 100644
--- a/articles/january-2014-status/index.html
+++ b/articles/january-2014-status/index.html
@@ -224,6 +224,8 @@ the sponsoring idea, anything really! Thanks.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/ml-archives/index.html b/articles/ml-archives/index.html
index 41a87cb2..6284b2d5 100644
--- a/articles/ml-archives/index.html
+++ b/articles/ml-archives/index.html
@@ -94,6 +94,8 @@ underlying problem in the project or its documentation.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/on-open-source/index.html b/articles/on-open-source/index.html
index 66387794..a21b30eb 100644
--- a/articles/on-open-source/index.html
+++ b/articles/on-open-source/index.html
@@ -201,6 +201,8 @@ of your company&#8217;s money.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/page/2/index.html b/articles/page/2/index.html
index 694bed10..b7448109 100644
--- a/articles/page/2/index.html
+++ b/articles/page/2/index.html
@@ -74,6 +74,23 @@
<article class="blog_item">
<header>
+ <h2><a href="https://ninenines.eu/articles/ranch-ftp/">Build an FTP Server with Ranch in 30 Minutes</a></h2>
+ <p class="date">
+ <span class="day">14</span>
+ <span class="month">Nov</span>
+ </p>
+ </header>
+
+ <p>Last week I was speaking at the London Erlang Factory Lite where I presented a live demonstration of building an FTP server using Ranch. As there was no slide, you should use this article as a reference instead.
+ The goal of this article is to showcase how to use Ranch for writing a network protocol implementation, how Ranch gets out of the way to let you write the code that matters, and the common techniques used when writing servers.</p>
+
+ <p style="text-align:right">
+ <a class="read_more" href="https://ninenines.eu/articles/ranch-ftp/">Read More</a>
+ </p>
+ </article>
+
+ <article class="blog_item">
+ <header>
<h2><a href="https://ninenines.eu/articles/tictactoe/">Erlang Tic Tac Toe</a></h2>
<p class="date">
<span class="day">17</span>
diff --git a/articles/ranch-1.3/index.html b/articles/ranch-1.3/index.html
index 6286a77d..8e182a0e 100644
--- a/articles/ranch-1.3/index.html
+++ b/articles/ranch-1.3/index.html
@@ -166,6 +166,8 @@ that need fixing sooner rather than later.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/ranch-ftp/index.html b/articles/ranch-ftp/index.html
index 307deea8..f20cefcc 100644
--- a/articles/ranch-ftp/index.html
+++ b/articles/ranch-ftp/index.html
@@ -294,6 +294,8 @@ binary protocol implementations in just a few lines of code.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/the-story-so-far/index.html b/articles/the-story-so-far/index.html
index 9d01ab67..2e6d1db6 100644
--- a/articles/the-story-so-far/index.html
+++ b/articles/the-story-so-far/index.html
@@ -308,6 +308,8 @@ project and make sure it doesn&#8217;t happen again.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/tictactoe/index.html b/articles/tictactoe/index.html
index a96fda88..dfeff96b 100644
--- a/articles/tictactoe/index.html
+++ b/articles/tictactoe/index.html
@@ -167,6 +167,8 @@ of writing algorithms to do things.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/website-update/index.html b/articles/website-update/index.html
index 9f20a0ba..aa890a89 100644
--- a/articles/website-update/index.html
+++ b/articles/website-update/index.html
@@ -141,6 +141,8 @@ upgrading JS libraries.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/xerl-0.1-empty-modules/index.html b/articles/xerl-0.1-empty-modules/index.html
index d8c103d3..1fb11ce7 100644
--- a/articles/xerl-0.1-empty-modules/index.html
+++ b/articles/xerl-0.1-empty-modules/index.html
@@ -222,6 +222,8 @@ the next few articles.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/xerl-0.2-two-modules/index.html b/articles/xerl-0.2-two-modules/index.html
index b5979ee5..9651e83a 100644
--- a/articles/xerl-0.2-two-modules/index.html
+++ b/articles/xerl-0.2-two-modules/index.html
@@ -227,6 +227,8 @@ though, so let&#8217;s get back to it after we add more.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/xerl-0.3-atomic-expressions/index.html b/articles/xerl-0.3-atomic-expressions/index.html
index d34c591e..32e6fc1c 100644
--- a/articles/xerl-0.3-atomic-expressions/index.html
+++ b/articles/xerl-0.3-atomic-expressions/index.html
@@ -231,6 +231,8 @@ do that.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/xerl-0.4-expression-separator/index.html b/articles/xerl-0.4-expression-separator/index.html
index 55c68ce1..039ff166 100644
--- a/articles/xerl-0.4-expression-separator/index.html
+++ b/articles/xerl-0.4-expression-separator/index.html
@@ -136,6 +136,8 @@ expressions so I thought it was a good idea to anticipate.</p></div>
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/articles/xerl-0.5-intermediate-module/index.html b/articles/xerl-0.5-intermediate-module/index.html
index c12c6ce7..be22f0d4 100644
--- a/articles/xerl-0.5-intermediate-module/index.html
+++ b/articles/xerl-0.5-intermediate-module/index.html
@@ -214,6 +214,8 @@ http://www.gnu.org/software/src-highlite -->
<h3>More articles</h3>
<ul id="articles-nav" class="extra_margin">
+ <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don&#39;t let it crash</a></li>
+
<li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li>
<li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li>
diff --git a/docs/en/erlang.mk/1/guide/app.asciidoc b/docs/en/erlang.mk/1/guide/app.asciidoc
index 229ce973..94f8eb1a 100644
--- a/docs/en/erlang.mk/1/guide/app.asciidoc
+++ b/docs/en/erlang.mk/1/guide/app.asciidoc
@@ -284,6 +284,17 @@ include erlang.mk
ERLC_OPTS := $(filter-out -Werror,$(ERLC_OPTS))
----
+==== ERLC_ASN1_OPTS
+
+`ERLC_ASN1_OPTS` can be used to pass compiler options when compiling
+ASN.1 files. Please refer to the
+http://erlang.org/doc/man/asn1ct.html[asn1ct manual] for the full list.
+
+By default, Erlang.mk will leave this empty.
+
+You can redefine this variable in your Makefile.
+Please see the `ERLC_OPTS` section for instructions.
+
==== ERLC_EXCLUDE
`ERLC_EXCLUDE` can be used to exclude some modules from the
diff --git a/docs/en/erlang.mk/1/guide/app/index.html b/docs/en/erlang.mk/1/guide/app/index.html
index b6fbf4f7..b05e48c4 100644
--- a/docs/en/erlang.mk/1/guide/app/index.html
+++ b/docs/en/erlang.mk/1/guide/app/index.html
@@ -471,6 +471,15 @@ sets, by defining ERLC_OPTS after including Erlang.mk using the
<div class="content"></div></div>
</div>
<div class="sect3">
+<h4 id="_erlc_asn1_opts">ERLC_ASN1_OPTS</h4>
+<div class="paragraph"><p><code>ERLC_ASN1_OPTS</code> can be used to pass compiler options when compiling
+ASN.1 files. Please refer to the
+<a href="http://erlang.org/doc/man/asn1ct.html">asn1ct manual</a> for the full list.</p></div>
+<div class="paragraph"><p>By default, Erlang.mk will leave this empty.</p></div>
+<div class="paragraph"><p>You can redefine this variable in your Makefile.
+Please see the <code>ERLC_OPTS</code> section for instructions.</p></div>
+</div>
+<div class="sect3">
<h4 id="_erlc_exclude">ERLC_EXCLUDE</h4>
<div class="paragraph"><p><code>ERLC_EXCLUDE</code> can be used to exclude some modules from the
compilation. It&#8217;s there for handling special cases, you should
diff --git a/donate/index.html b/donate/index.html
index 7db11691..c3e254e8 100644
--- a/donate/index.html
+++ b/donate/index.html
@@ -105,6 +105,8 @@ and Erlang.mk is fantastic:</p></div>
+
+
<div class="sect2">
<h3 id="_like_my_work_donate">Like my work? Donate!</h3>
<div class="paragraph"><p>Donate to Loïc Hoguin because his work on Cowboy
diff --git a/index.html b/index.html
index fee4f682..2c6eadcb 100644
--- a/index.html
+++ b/index.html
@@ -263,6 +263,8 @@
+
+
<div class="paragraph"><p>The Erlanger Playbook is now available!<br />
<a href="/articles/erlanger-playbook">Buy now</a> — <a href="/services">Become a Cowboy project sponsor</a></p></div>
diff --git a/index.xml b/index.xml
index 6d4b70a1..31704d83 100644
--- a/index.xml
+++ b/index.xml
@@ -6,10 +6,131 @@
<description>Recent content on Nine Nines</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
- <lastBuildDate>Tue, 03 Jan 2017 00:00:00 +0100</lastBuildDate>
+ <lastBuildDate>Sun, 22 Jan 2017 00:00:00 +0100</lastBuildDate>
<atom:link href="https://ninenines.eu/index.xml" rel="self" type="application/rss+xml" />
<item>
+ <title>Don&#39;t let it crash</title>
+ <link>https://ninenines.eu/articles/dont-let-it-crash/</link>
+ <pubDate>Sun, 22 Jan 2017 00:00:00 +0100</pubDate>
+
+ <guid>https://ninenines.eu/articles/dont-let-it-crash/</guid>
+ <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;We have a specific mindset when writing Erlang
+programs. We focus on the normal execution of the
+program and don&amp;#8217;t handle most of the errors that may
+occur. We sometimes call this normal execution the
+&lt;em&gt;happy path&lt;/em&gt;.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The general pattern behind writing only for the
+&lt;em&gt;happy path&lt;/em&gt;, letting the VM catch errors (writing
+them to a log for future consumption) and then
+having a supervisor restart the processes that
+failed from a clean state, has a name. We call it
+&lt;em&gt;let it crash&lt;/em&gt;; and it drives many of our design
+decisions.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;It&amp;#8217;s a really great way to program and the results
+are fantastic compared to most other programming
+languages. And yet, &lt;em&gt;let it crash&lt;/em&gt; barely convinced
+anyone that they should use Erlang. Why would that
+be?&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;You may already know that Cowboy is capable of
+handling at least 2 million Websocket connections
+on a single server. This is in large part thanks
+to the capabilities of the VM. Still, 2 million
+is good, much better than most other servers can
+do.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Cowboy is not just a Websocket server; it&amp;#8217;s also
+an HTTP and HTTP/2 server, and it handles many
+related features like long polling or the parsing
+of most request headers.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Can you guess how large the Cowboy codebase is,
+without looking at the source?&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Do make sure you have a clear answer in your mind
+before you go check.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Good, you are back. Now what were the results? If
+I am correct, you overestimated the size of Cowboy.
+Cowboy is in fact about five thousand lines of code.
+You probably thought it was at least ten thousand.
+About eighty percent of readers will have
+overestimated the size of Cowboy. And you did only
+because I mentioned it can handle millions of
+Websocket connections.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Numerous studies show this effect. Just mentioning
+the large number already prepared your mind to think
+in that direction. Repeating the number made you
+focus even more on it. Then the question asked for
+a number, which ended up larger than the reality.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The same effect can be applied to negotiation for
+example. You generally want to start by giving your
+offer (and not let the other party initiate) and
+you want to give a really large number first. You
+can also prepare your customer by mentioning an even
+larger number in the previous discussion.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And it&amp;#8217;s not just numbers either. An experiment
+showed that just by looking at an image of clouds,
+customers of a pillow store were buying pillows
+more comfortable (and more expensive) than those
+who didn&amp;#8217;t see that image.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is the power of associations. It is covered in
+much larger detail in the books
+&lt;a href=&#34;https://www.amazon.com/Influence-Psychology-Persuasion-Robert-Cialdini/dp/006124189X&#34;&gt;Influence&lt;/a&gt;
+and
+&lt;a href=&#34;https://www.amazon.com/Pre-Suasion-Revolutionary-Way-Influence-Persuade/dp/1501109790&#34;&gt;Pre-suasion&lt;/a&gt;.
+I highly recommend reading those and applying what
+you learn to your daily life. I&amp;#8217;m definitely not
+a professional psychologist so take this post with
+a grain of salt.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;When selling Erlang, whether we are selling it to
+a customer or trying to convince a developer friend
+to start using it, we often talk about how Erlang
+&lt;em&gt;lets you sleep at night&lt;/em&gt;, that it is auto healing
+and always gets fantastic uptimes.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And then we talk about &lt;em&gt;let it crash&lt;/em&gt;.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And we describe what it means.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;We might as well just say that Erlang crashes a lot
+and then take the door. It would have the same effect.
+It doesn&amp;#8217;t even stop at programs crashing. You know
+what else crashes? Cars, planes, trains. Often with
+disastrous consequences. Is that really the message
+we want to convey?&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;They even &lt;a href=&#34;https://img.youtube.com/vi/oEUBW2lCkIk/0.jpg&#34;&gt;printed it on a t-shirt&lt;/a&gt;!
+Keep calm and let it crash. It&amp;#8217;s the kind of t-shirt
+you probably shouldn&amp;#8217;t wear in an airport, and for good
+reasons. A few people did, then realized what they were
+wearing and were not too smug about it.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And yet this is how we sell Erlang.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;A better way would be to focus on the positives, of
+course, but also to make sure that those positives
+are phrased in a way that prevents bad associations
+to be formed in people&amp;#8217;s minds.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Instead of &lt;em&gt;let it crash&lt;/em&gt;, you can say that Erlang
+has &lt;em&gt;auto healing mechanisms&lt;/em&gt;. Healing is a good
+thing and accurately describes what happens in the
+system.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Should you need to go into more details, you will
+probably want to avoid &lt;em&gt;recover from crashes&lt;/em&gt; and
+instead say &lt;em&gt;recover from exceptions&lt;/em&gt;. Exceptions
+are a pretty neutral word and, should you explain
+what you mean by that, you can talk about exceptions
+that occur for reasons unrelated to Erlang, like
+hardware failure or network instability.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The trick is to always use positive words and
+phrases to describe Erlang, and to use external
+factors to explain how Erlang deals with failures.
+Never mention the failures internal to Erlang
+systems unless you are asked specifically, in
+which case you can say that the auto healing
+applies to all exceptions.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The &lt;em&gt;let it crash&lt;/em&gt; philosophy is great when
+learning Erlang or when writing fault-tolerant
+systems. But it&amp;#8217;s not going to convince anyone
+to use it unless they were already looking for
+it.&lt;/p&gt;&lt;/div&gt;
+&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Do you like this post? Tell me on Twitter. I might
+make more.&lt;/p&gt;&lt;/div&gt;
+</description>
+ </item>
+
+ <item>
<title>Cowboy 2.0 pre-release 4</title>
<link>https://ninenines.eu/articles/cowboy-2.0.0-pre.4/</link>
<pubDate>Tue, 03 Jan 2017 00:00:00 +0100</pubDate>
@@ -1132,163 +1253,5 @@ project and make sure it doesn&amp;#8217;t happen again.&lt;/p&gt;&lt;/div&gt;
</description>
</item>
- <item>
- <title>Cowboy 2.0 and query strings</title>
- <link>https://ninenines.eu/articles/cowboy2-qs/</link>
- <pubDate>Wed, 20 Aug 2014 00:00:00 +0100</pubDate>
-
- <guid>https://ninenines.eu/articles/cowboy2-qs/</guid>
- <description>&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Now that Cowboy 1.0 is out, I can spend some of my time thinking
-about Cowboy 2.0 that will be released soon after Erlang/OTP 18.0.
-This entry discusses the proposed changes to query string handling
-in Cowboy.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Cowboy 2.0 will respond to user wishes by simplifying the interface
-of the &lt;code&gt;cowboy_req&lt;/code&gt; module. Users want two things: less
-juggling with the Req variable, and more maps. Maps is the only
-dynamic key/value data structure in Erlang that we can match directly
-to extract values, allowing users to greatly simplify their code as
-they don&amp;#8217;t need to call functions to do everything anymore.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Query strings are a good candidate for maps. It&amp;#8217;s a list of
-key/values, so it&amp;#8217;s pretty obvious we can win a lot by using maps.
-However query strings have one difference with maps: they can have
-duplicate keys.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;How are we expected to handle duplicate keys? There&amp;#8217;s no standard
-behavior. It&amp;#8217;s up to applications. And looking at what is done in
-the wild, there&amp;#8217;s no de facto standard either. While some ignore
-duplicate keys (keeping the first or the last they find), others
-require duplicate keys to end with &lt;code&gt;[]&lt;/code&gt; to automatically
-put the values in a list, or even worse, languages like PHP even
-allow you to do things like &lt;code&gt;key[something][other]&lt;/code&gt; and
-create a deep structure for it. Finally some allow any key to have
-duplicates and just gives you lists of key/values.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Cowboy so far had functions to retrieve query string values one
-value at a time, and if there were duplicates it would return the
-first it finds. It also has a function returning the entire list
-with all duplicates, allowing you to filter it to get all of them,
-and another function that returns the raw query string.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;What are duplicates used for? Not that many things actually.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;One use of duplicate keys is with HTML forms. It is common practice
-to give all related checkboxes the same name so you get a list of
-what&amp;#8217;s been checked. When nothing is checked, nothing is sent at all,
-the key is not in the list.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Another use of duplicate keys is when generating forms. A good
-example of that would be a form that allows uploading any number
-of files. When you add a file, client-side code adds another field
-to the form. Repeat up to a certain limit.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And that&amp;#8217;s about it. Of note is that HTML radio elements share
-the same name too, but only one key/value is sent, so they are not
-relevant here.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Normally this would be the part where I tell you how we solve
-this elegantly. But I had doubts. Why? Because there&amp;#8217;s no good
-solutions to solving only this particular problem.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I then stopped thinking about duplicate keys for a minute and
-started to think about the larger problem.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Query strings are input data. They take a particular form,
-and may be sent as part of the URI or as part of the request
-body. We have other kinds of input data. We have headers and
-cookies and the request body in various forms. We also have
-path segments in URIs.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;What do you do with input data? Well you use it to do
-something. But there is one thing that you almost always do
-(and if you don&amp;#8217;t, you really should): you validate it and
-you map it into Erlang terms.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Cowboy left the user take care of validation and conversion
-into Erlang terms so far. Rather, it left the user take care
-of it everywhere except one place. Guess where? That&amp;#8217;s right,
-bindings.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;If you define routes with bindings then you have the option
-to provide constraints. Constraints can be used to do two things:
-validate the data and convert it in a more appropriate term. For
-example if you use the &lt;code&gt;int&lt;/code&gt; constraint, Cowboy will
-make sure the binding is an integer, and will replace the value
-with the integer representation so that you can use it directly.
-In this particular case it not only routes the URI, but also
-validates and converts the bindings directly.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This is very relevant in the case of our duplicate keys,
-because if we have a list with duplicates of a key, chances
-are we want to convert that into a list of Erlang terms, and
-also make sure that all the elements in this list are expected.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The answer to this particular problem is simple. We need a
-function that will parse the query string and apply constraints.
-But this is not all, there is one other problem to be solved.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The other problem is that for the user some keys are mandatory
-and some are optional. Optional keys include the ones that
-correspond to HTML checkboxes: if the key for one or more
-checkbox is missing from the query string, we still want to
-have an empty list in our map so we can easily match. Matching
-maps is great, but not so much when values might be missing,
-so we have to normalize this data a little.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This problem is solved by allowing a default value. If the
-key is missing and a default exists, set it. If no default
-exists, then the key was mandatory and we want to crash.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I therefore make a proposal for changing the query string
-interface to three functions.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The first function already exists, it is &lt;code&gt;cowboy_req:qs(Req)&lt;/code&gt;
-and it returns only the query string binary. No more Req returned.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The second function is a renaming of &lt;code&gt;cowboy_req:qs_vals(Req)&lt;/code&gt;
-to something more explicit: &lt;code&gt;cowboy_req:parse_qs(Req)&lt;/code&gt;.
-The new name implies that a parsing operation is done. It was implicit
-and cached before. It will be explicit and not cached anymore now.
-Again, no more Req returned.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;The third function is the one I mentioned above. I think
-the interface &lt;code&gt;cowboy_req:match_qs(Req, Fields)&lt;/code&gt; is
-most appropriate. It returns a normalized map that is the same
-regardless of optional fields being provided with the request,
-allowing for easy matching. It crashes if something went wrong.
-Still no Req returned.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I feel that this three function interface provides everything
-one would need to comfortably write applications. You can get
-low level and get the query string directly; you can get a list
-of key/value binaries without any additional processing and do it
-on your own; or you can get a processed map that contains Erlang
-terms ready to be used.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;I strongly believe that by democratizing the constraints to
-more than just bindings, but also to query string, cookies and
-other key/values in Cowboy, we can allow the developer to quickly
-and easily go from HTTP request to Erlang function calls. The
-constraints are reusable functions that can serve as guards
-against unwanted data, providing convenience in the process.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;Your handlers will not look like an endless series of calls
-to get and convert the input data, they will instead be just
-one call at the beginning followed by the actual application
-logic, thanks to constraints and maps.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;listingblock&#34;&gt;
-&lt;div class=&#34;content&#34;&gt;&lt;!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite --&gt;
-&lt;pre&gt;&lt;tt&gt;&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;handle&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Req&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;State&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt;
- #{&lt;span style=&#34;color: #FF6600&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color: #009900&#34;&gt;Name&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;email&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color: #009900&#34;&gt;Email&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;choices&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color: #009900&#34;&gt;ChoicesList&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;remember_me&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color: #009900&#34;&gt;RememberMe&lt;/span&gt;} &lt;span style=&#34;color: #990000&#34;&gt;=&lt;/span&gt;
- &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;cowboy_req:match_qs&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Req&lt;/span&gt;, [
- &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000080&#34;&gt;name&lt;/span&gt;&lt;/span&gt;, {&lt;span style=&#34;color: #FF6600&#34;&gt;email&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;email&lt;/span&gt;},
- {&lt;span style=&#34;color: #FF6600&#34;&gt;choices&lt;/span&gt;, &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;fun&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;check_choices&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #993399&#34;&gt;1&lt;/span&gt;, []},
- {&lt;span style=&#34;color: #FF6600&#34;&gt;remember_me&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;boolean&lt;/span&gt;, &lt;span style=&#34;color: #000080&#34;&gt;false&lt;/span&gt;}]),
- &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;save_choices&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Name&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Email&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;ChoicesList&lt;/span&gt;),
- &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;if&lt;/span&gt;&lt;/span&gt; &lt;span style=&#34;color: #009900&#34;&gt;RememberMe&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;create_account&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #009900&#34;&gt;Name&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Email&lt;/span&gt;); &lt;span style=&#34;color: #000080&#34;&gt;true&lt;/span&gt; &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #FF6600&#34;&gt;ok&lt;/span&gt; &lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #0000FF&#34;&gt;end&lt;/span&gt;&lt;/span&gt;,
- {&lt;span style=&#34;color: #FF6600&#34;&gt;ok&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;Req&lt;/span&gt;, &lt;span style=&#34;color: #009900&#34;&gt;State&lt;/span&gt;}&lt;span style=&#34;color: #990000&#34;&gt;.&lt;/span&gt;
-
-&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;check_choices&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color: #FF0000&#34;&gt;&#34;blue&#34;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; {&lt;span style=&#34;color: #000080&#34;&gt;true&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;blue&lt;/span&gt;};
-&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;check_choices&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color: #FF0000&#34;&gt;&#34;red&#34;&lt;/span&gt;&lt;span style=&#34;color: #990000&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; {&lt;span style=&#34;color: #000080&#34;&gt;true&lt;/span&gt;, &lt;span style=&#34;color: #FF6600&#34;&gt;red&lt;/span&gt;};
-&lt;span style=&#34;font-weight: bold&#34;&gt;&lt;span style=&#34;color: #000000&#34;&gt;check_choices&lt;/span&gt;&lt;/span&gt;(&lt;span style=&#34;color: #990000&#34;&gt;_&lt;/span&gt;) &lt;span style=&#34;color: #990000&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #000080&#34;&gt;false&lt;/span&gt;;&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;(Don&amp;#8217;t look too closely at the structure yet.)&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;As you can see in the above snippet, it becomes really easy
-to go from query string to values. You can also use the map
-directly as it is guaranteed to only contain the keys you
-specified, any extra key is not returned.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;This would I believe be a huge step up as we can now
-focus on writing applications instead of translating HTTP
-calls. Cowboy can now take care of it.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;And to conclude, this also solves our duplicate keys
-dilemma, as they now automatically become a list of binaries,
-and this list is then checked against constraints that
-will fail if they were not expecting a list. And in the
-example above, it even converts the values to atoms for
-easier manipulation.&lt;/p&gt;&lt;/div&gt;
-&lt;div class=&#34;paragraph&#34;&gt;&lt;p&gt;As usual, feedback is more than welcome, and I apologize
-for the rocky structure of this post as it contains all the
-thoughts that went into this rather than just the conclusion.&lt;/p&gt;&lt;/div&gt;
-</description>
- </item>
-
</channel>
</rss> \ No newline at end of file
diff --git a/services/index.html b/services/index.html
index e2c1d536..1ebc9586 100644
--- a/services/index.html
+++ b/services/index.html
@@ -190,6 +190,8 @@ the same restrictions apply.</p></div>
+
+
<div class="sect2">
<h3 id="_like_my_work_donate">Like my work? Donate!</h3>
<div class="paragraph"><p>Donate to Loïc Hoguin because his work on Cowboy
diff --git a/sitemap.xml b/sitemap.xml
index 2a0c4d64..d70c57e2 100644
--- a/sitemap.xml
+++ b/sitemap.xml
@@ -3,7 +3,12 @@
<url>
<loc>https://ninenines.eu/</loc>
- <lastmod>2017-01-03T00:00:00+01:00</lastmod>
+ <lastmod>2017-01-22T00:00:00+01:00</lastmod>
+ </url>
+
+ <url>
+ <loc>https://ninenines.eu/articles/dont-let-it-crash/</loc>
+ <lastmod>2017-01-22T00:00:00+01:00</lastmod>
</url>
<url>