<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andrei Gaspar</title>
    <description>The latest articles on DEV Community by Andrei Gaspar (@gasparandr).</description>
    <link>https://dev.to/gasparandr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F242271%2Fceee2d99-8f3a-45b0-b893-0e041584005c.jpg</url>
      <title>DEV Community: Andrei Gaspar</title>
      <link>https://dev.to/gasparandr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gasparandr"/>
    <language>en</language>
    <item>
      <title>Node.js Resiliency Concepts: Recovery and Self-Healing</title>
      <dc:creator>Andrei Gaspar</dc:creator>
      <pubDate>Thu, 01 Oct 2020 13:11:21 +0000</pubDate>
      <link>https://dev.to/appsignal/node-js-resiliency-concepts-recovery-and-self-healing-4a99</link>
      <guid>https://dev.to/appsignal/node-js-resiliency-concepts-recovery-and-self-healing-4a99</guid>
      <description>&lt;p&gt;In an ideal world where we reached 100% test coverage, our error handling was flawless,&lt;br&gt;
and all our failures were handled gracefully — in a world where all our systems reached perfection,&lt;br&gt;
we wouldn't be having this discussion.&lt;/p&gt;

&lt;p&gt;Yet, here we are. Earth, 2020. By the time you read this sentence,&lt;br&gt;
somebody's server failed in production. A moment of silence for the processes we lost.&lt;/p&gt;

&lt;p&gt;In this post, I'll go through some concepts and tools which will make your servers more resilient and boost your process management skills.&lt;/p&gt;
&lt;h2&gt;
  
  
  Node Index.js
&lt;/h2&gt;

&lt;p&gt;Starting with Node.js — especially if you're new to working with servers — you'll probably want&lt;br&gt;
to run your app on the remote production server the very same way you're running it in development.&lt;/p&gt;

&lt;p&gt;Install Node.js, clone the repo, give it an &lt;code&gt;npm install&lt;/code&gt;, and a &lt;code&gt;node index.js&lt;/code&gt; (or &lt;code&gt;npm start&lt;/code&gt;) to spin it all up.&lt;/p&gt;

&lt;p&gt;I remember this seeming like a bulletproof plan for me starting out. If it works, why fix it, right?&lt;/p&gt;

&lt;p&gt;My code would run into errors during development, resulting in crashes,&lt;br&gt;
but I fixed those bugs on the spot — so the code on the server is uncorrupted.&lt;br&gt;
It cannot crash. Once it starts up, that server is there to stay until the heat death of the universe.&lt;/p&gt;

&lt;p&gt;Well, as you probably suspect, that was not the case.&lt;/p&gt;

&lt;p&gt;I was facing two main problems that didn't cross my mind back then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens if the VM/Host restarts?&lt;/li&gt;
&lt;li&gt;Servers crash... That's like, their second most popular attribute.
If they weren't &lt;em&gt;serving&lt;/em&gt; anything, we would call them crashers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Wolverine vs T-1000
&lt;/h2&gt;

&lt;p&gt;Recovery can be tackled in many different ways. There are convenient solutions&lt;br&gt;
to restart our server after crashes, and there are more sophisticated approaches&lt;br&gt;
to make it indestructible in production.&lt;/p&gt;

&lt;p&gt;Both Wolverine and the T-1000 can take a good beating, but their complexity and recovery rate are very different.&lt;/p&gt;

&lt;p&gt;We're looking for distinct qualities based on the environment we're running in.&lt;br&gt;
For development, the goal is convenience. For production, it's usually resilience.&lt;/p&gt;

&lt;p&gt;We're going to start with the simplest form of recovery and then slowly work our way up&lt;br&gt;
to elaborate orchestration solutions.&lt;/p&gt;

&lt;p&gt;It is up to you how much effort you'd like to invest in your implementation,&lt;br&gt;
but it never hurts having more tools at your disposal, so if this spikes your interest,&lt;br&gt;
fasten your seatbelt, and let's dive in!&lt;/p&gt;
&lt;h2&gt;
  
  
  Solving Problems as They Arise
&lt;/h2&gt;

&lt;p&gt;You're coding away, developing your amazing server.&lt;/p&gt;

&lt;p&gt;After every couple of lines, you switch tabs and nudge it with a &lt;code&gt;node index&lt;/code&gt; or &lt;code&gt;npm start&lt;/code&gt;.&lt;br&gt;
This cycle of constant switching and nudging becomes crushingly tedious after a while.&lt;/p&gt;

&lt;p&gt;Wouldn't it be nice if it would just restart on its own after you changed the code?&lt;/p&gt;

&lt;p&gt;This is where lightweight packages like &lt;a href="https://www.npmjs.com/package/nodemon"&gt;Nodemon&lt;/a&gt;&lt;br&gt;
and Node.js &lt;a href="https://www.npmjs.com/package/supervisor"&gt;Supervisor&lt;/a&gt; come into play.&lt;br&gt;
You can install them with one line of code and start using them with the next.&lt;/p&gt;

&lt;p&gt;To install Nodemon, simply type the below command in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; nodemon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, just substitute the &lt;code&gt;node&lt;/code&gt; command you've been using&lt;br&gt;
with the new &lt;code&gt;nodemon&lt;/code&gt; command that you now have access to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nodemon index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can install Node.js Supervisor with a similar approach, by typing the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; supervisor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, once installed you can just use the &lt;code&gt;supervisor&lt;/code&gt; prefix to run your app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;supervisor index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nodemon and Supervisor are both as useful as they are popular, with the main difference&lt;br&gt;
being that Nodemon will require you to make file changes to restart your process,&lt;br&gt;
while Supervisor can restart your process when it crashes.&lt;/p&gt;

&lt;p&gt;Your server is on the right track. Development speed quadrupled.&lt;/p&gt;

&lt;p&gt;These packages do a great job covering development pain-points&lt;br&gt;
and they are pretty configurable as well. But the difficulties we are facing in development&lt;br&gt;
rarely overlap the ones we're facing in production.&lt;/p&gt;

&lt;p&gt;When you deploy to the remote server, it feels like sending your kid to college as an overprotective parent.&lt;br&gt;
You want to know your server is healthy, safe, and eats all its veggies.&lt;/p&gt;

&lt;p&gt;You'd like to know what problem it faced when it crashed — if it crashed. You want it to be in good hands.&lt;/p&gt;

&lt;p&gt;Well, good news! This is where process managers come into the picture. They can babysit your server in production.&lt;/p&gt;
&lt;h2&gt;
  
  
  Process Management
&lt;/h2&gt;

&lt;p&gt;When you run your app, a &lt;a href="https://en.wikipedia.org/wiki/Process_(computing)"&gt;process&lt;/a&gt; is created.&lt;/p&gt;

&lt;p&gt;While running it in development, you would usually open a terminal window and type a command in there.&lt;br&gt;
A &lt;em&gt;foreground&lt;/em&gt; process is created and your app is running.&lt;/p&gt;

&lt;p&gt;Now, if you would close that terminal window, your app would close with it.&lt;br&gt;
You'll also notice that the terminal window is blocked.&lt;br&gt;
You cannot enter another command before you close the process with &lt;code&gt;Ctrl + C&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The drawback is that the app is tied to the terminal window,&lt;br&gt;
but you're also able to read all the logs and errors that the process is throwing.&lt;br&gt;
So it's a glass half full.&lt;/p&gt;

&lt;p&gt;However, on your production server, you'll want to run in the background,&lt;br&gt;
but then you'll lose the convenience of visibility. Frustration is assured.&lt;/p&gt;

&lt;p&gt;Process management is tedious.&lt;/p&gt;

&lt;p&gt;Luckily, we have process managers! They are processes that manage other processes for us.&lt;br&gt;
So meta! But ridiculously convenient.&lt;/p&gt;
&lt;h3&gt;
  
  
  PM2
&lt;/h3&gt;

&lt;p&gt;The most popular process manager for Node.js is called &lt;a href="https://pm2.keymetrics.io/"&gt;pm2&lt;/a&gt;,&lt;br&gt;
and it's so popular for a very good reason. It's great!&lt;/p&gt;

&lt;p&gt;It's such a fantastic piece of software that it would take me a separate article to describe its awesomeness&lt;br&gt;
in its entirety, and just how many convenient features it has. Since we're focused on self-healing,&lt;br&gt;
I'll discuss the basics below, but I strongly encourage you to read up on it more in-depth&lt;br&gt;
and check all its amazing features.&lt;/p&gt;

&lt;p&gt;Installing pm2 is just as easy as installing the packages we discussed above.&lt;br&gt;
Simply type the following line in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; pm2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running your app isn't rocket science either. Just type the command below, where &lt;code&gt;index.js&lt;/code&gt; is your main server file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 start index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time, you might notice something different though.&lt;br&gt;
Seemingly, nothing has happened, but if you go on to visit the endpoint to your app,&lt;br&gt;
you'll notice that it's up and running.&lt;/p&gt;

&lt;p&gt;Remember when we discussed running the process in the background?&lt;br&gt;
That is exactly what is happening. pm2 started your server as a background process and it is now managing it for you.&lt;/p&gt;

&lt;p&gt;As an added convenience, you can also use the &lt;code&gt;--watch&lt;/code&gt; flag to make sure pm2 watches your files for changes&lt;br&gt;
and reloads your app to make sure it is always up to date.&lt;/p&gt;

&lt;p&gt;To do so, you can use the exact command above, but with the flag appended to the end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 start index.js &lt;span class="nt"&gt;--watch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, pm2 is watching our files and restarts the process anytime the files change or the process crashes.&lt;br&gt;
Perfect! This is exactly what we're after.&lt;/p&gt;

&lt;p&gt;It is doing a great job managing our server behind the scenes, but the lack of visibility is anxiety-inducing.&lt;br&gt;
What if you want to see your server logs?&lt;/p&gt;

&lt;p&gt;pm2 has you covered. Their CLI is really powerful! I'll list some commands below to get you started.&lt;/p&gt;

&lt;p&gt;List your applications with the command below.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command                 &lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pm2 list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lists your applications. You'll see a numeric &lt;code&gt;id&lt;/code&gt; associated with the applications managed by pm2. You can use that id in the commands you'd like to execute.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pm2 logs &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Checks the logs of your application.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pm2 stop &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stops your process. (Just because the process is stopped, it doesn't mean it stopped existing. If you want to completely remove the process, you'll have to use delete)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pm2 delete &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deletes the process. (You don't need to stop and delete separately, you can just go straight for delete, which will stop and delete the process for you)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;pm2 is insanely configurable and is able to perform Load Balancing and Hot Reload for you.&lt;br&gt;
You can read up on all the bells and whistles in &lt;a href="https://pm2.keymetrics.io/docs/usage/quick-start/"&gt;their docs&lt;/a&gt;, but our pm2 journey comes to a halt here.&lt;/p&gt;

&lt;p&gt;Disappointing, I know. But why? I hear you asking.&lt;/p&gt;

&lt;p&gt;Remember how convenient it was to install pm2?&lt;br&gt;
We installed it using the Node.js package manager. Wink... Pistol finger. Wink-wink.&lt;/p&gt;

&lt;p&gt;Wait. Are we using Node.js to monitor Node.js?&lt;/p&gt;

&lt;p&gt;That sounds a bit like trusting your child to babysit itself. Is that a good idea?&lt;br&gt;
There is no objective answer to that question, but it sure sounds like there&lt;br&gt;
should be some other alternatives to be explored.&lt;/p&gt;

&lt;p&gt;So, what next? Well, let's explore.&lt;/p&gt;
&lt;h2&gt;
  
  
  Systemd
&lt;/h2&gt;

&lt;p&gt;If you're planning to run on a good old Linux VM, I think it might be worth mentioning &lt;code&gt;systemd&lt;/code&gt;&lt;br&gt;
before jumping onto the deep end of containers and orchestrators.&lt;/p&gt;

&lt;p&gt;Otherwise, if you plan to run on a managed application environment&lt;br&gt;
(e.g. Azure AppService, AWS Lambda, GCP App Engine, Heroku, etc.),&lt;br&gt;
this will not be relevant to your use case, but it might not hurt knowing about it.&lt;/p&gt;

&lt;p&gt;So assuming that it's just you, your app, and a Linux VM, let's see what &lt;code&gt;systemd&lt;/code&gt; can do for you.&lt;/p&gt;

&lt;p&gt;Systemd can start, stop, and restart processes for you, which is exactly what we need.&lt;br&gt;
If your VM restarts, systemd makes sure that your app starts up again.&lt;/p&gt;

&lt;p&gt;But first, let's make sure you have access to systemd on your VM.&lt;/p&gt;

&lt;p&gt;Below is a list of Linux systems that make use of systemd:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu Xenial (or newer)&lt;/li&gt;
&lt;li&gt;CentOS 7 / RHEL 7&lt;/li&gt;
&lt;li&gt;Debian Jessie (or newer)&lt;/li&gt;
&lt;li&gt;Fedora 15 (or newer)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's be realistic, you're probably not using a Linux system from before the great flood,&lt;br&gt;
so you'll probably have systemd access.&lt;/p&gt;

&lt;p&gt;The second thing that you need is a user with &lt;code&gt;sudo&lt;/code&gt; privileges.&lt;br&gt;
I'm going to be referring to this user simply as &lt;code&gt;user&lt;/code&gt; but you should substitute it with your own.&lt;/p&gt;

&lt;p&gt;Since our user is called &lt;code&gt;user&lt;/code&gt; and, for this example, I'm using Ubuntu,&lt;br&gt;
I'll be referring to your home directory as &lt;code&gt;/home/user/&lt;/code&gt; and I'll go with the assumption that&lt;br&gt;
your &lt;code&gt;index.js&lt;/code&gt; file is located in your home directory.&lt;/p&gt;
&lt;h3&gt;
  
  
  The systemd Service File
&lt;/h3&gt;

&lt;p&gt;The systemd file is a useful little file that we can create in the system area that holds the&lt;br&gt;
configuration to our service. It is really simple and straightforward, so let's try to set one up.&lt;/p&gt;

&lt;p&gt;The systemd files are all located under the directory listed below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/lib/systemd/system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a new file there with the editor of your choice and populate it with some content.&lt;br&gt;
Don't forget to use &lt;code&gt;sudo&lt;/code&gt; as a prefix to your command! Everything here is owned by the root user.&lt;/p&gt;

&lt;p&gt;Okay, let's start by going into the system directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /lib/systemd/system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a file for your service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano myapp.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, let's populate it with some content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# /lib/systemd/system/myapp.service

[Unit]
Description=My awesome server
Documentation=https://awesomeserver.com
After=network.target

[Service]
Environment=NODE_PORT=3000
Environment=NODE_ENV=production
Type=simple
User=user
ExecStart=/usr/bin/node /home/user/index.js
Restart=on-failure

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you glance through the configuration, it's pretty straightforward and self-explanatory, for the most part.&lt;/p&gt;

&lt;p&gt;The two settings you might need some hints on are &lt;code&gt;After&lt;/code&gt; and &lt;code&gt;Type&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;After=network.target&lt;/code&gt; means that it should wait for the networking part of the server to be up and running&lt;br&gt;
because we need the port. The simple type just means don't do anything crazy, just start and run.&lt;/p&gt;
&lt;h3&gt;
  
  
  Running Your App with systemctl
&lt;/h3&gt;

&lt;p&gt;Now that our file has been created, let's tell &lt;code&gt;systemd&lt;/code&gt; to pick up the changes from the newly created file.&lt;br&gt;
You'll have to do this each time you make a change to the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is as simple as that. Now that it knows about our service,&lt;br&gt;
we should be able to use the &lt;code&gt;systemctl&lt;/code&gt; command to start and stop it.&lt;br&gt;
We will be referring to it by the service file name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you'd like to stop it, you can substitute the &lt;code&gt;start&lt;/code&gt; command with &lt;code&gt;stop&lt;/code&gt;.&lt;br&gt;
If you'd like to restart it, type &lt;code&gt;restart&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;Now, on to the part we care most about.&lt;br&gt;
If you'd like your application to start up automatically when the VM boots, you should execute the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want that behavior to stop, just substitute &lt;code&gt;enable&lt;/code&gt; with &lt;code&gt;disable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is as simple as that!&lt;/p&gt;

&lt;p&gt;So, now we have another system managing our process that is not Node.js itself.&lt;br&gt;
This is great! You can proudly give yourself a high five, or maybe an awkward elbow bump&lt;br&gt;
depending on the pandemic regulations while reading this article.&lt;/p&gt;

&lt;p&gt;Our journey does not stop here though. There's still quite a lot of ground left uncovered,&lt;br&gt;
so let's slowly start diving into the world of containers and orchestration.&lt;/p&gt;
&lt;h2&gt;
  
  
  What are Containers?
&lt;/h2&gt;

&lt;p&gt;To be able to move forward, you need to understand what Containers are and how they work.&lt;/p&gt;

&lt;p&gt;There are a lot of container runtime environments out there such as Mesos, CoreOS, LXC, and OpenVz,&lt;br&gt;
but the one name that is truly synonymous with containers is &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt;.&lt;br&gt;
It makes up more than 80% of the containers used and when people mention&lt;br&gt;
containers, it's safe to think they are talking about Docker.&lt;/p&gt;

&lt;p&gt;So, what do these containers do anyway?&lt;/p&gt;

&lt;p&gt;Well, containers contain. They have a very simple and descriptive name in that sense.&lt;/p&gt;

&lt;p&gt;Now the question remains, what do they &lt;em&gt;contain&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Containers contain your application and all of its dependencies.&lt;br&gt;
Nothing more and nothing less. It is just your app and everything that your app needs to run.&lt;/p&gt;

&lt;p&gt;Think about what your Node.js server needs to execute:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js (duh')&lt;/li&gt;
&lt;li&gt;Your index.js file&lt;/li&gt;
&lt;li&gt;Probably your npm packages (dependencies)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, if we were creating a container, we would want to make sure these things are present and contained.&lt;/p&gt;

&lt;p&gt;If we would have such a container ready, then it could be spun up via the container engine (e.g. Docker).&lt;/p&gt;
&lt;h3&gt;
  
  
  Containers vs VMs, and Italian Cuisine
&lt;/h3&gt;

&lt;p&gt;Even if you haven't worked much with Virtual Machines,&lt;br&gt;
I think you have a general idea about how they work.&lt;br&gt;
You've probably seen your friend running a Windows machine with Linux installed on it,&lt;br&gt;
or a macOS with an additional Windows installation, etc.&lt;/p&gt;

&lt;p&gt;So the idea there is that you have your Physical Machine and an Operating System on top,&lt;br&gt;
which then contains your app and its dependencies.&lt;/p&gt;

&lt;p&gt;Let's imagine we're making pizza.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Machine is the Table&lt;/li&gt;
&lt;li&gt;The OS is the Pizza Dough&lt;/li&gt;
&lt;li&gt;And, your app together with its dependencies are the ingredients on top&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let's say you'd like to eat 5 types of pizza, what should you do?&lt;/p&gt;

&lt;p&gt;The answer is to make 5 different pizzas on the same table. That's the VM's answer.&lt;/p&gt;

&lt;p&gt;But here comes Docker and it says: &lt;em&gt;"Hey, that's a lot of waste! You're not going to eat 5 pizzas,&lt;br&gt;
and making the dough is hard work. What about using the same dough?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You might be thinking, hey that's not a bad idea actually — but I don't want&lt;br&gt;
my friend's disgusting pineapple flavor (sorry, not sorry) spilling over&lt;br&gt;
into my yummy 4 cheese. The ingredients are conflicting!&lt;/p&gt;

&lt;p&gt;And here's where Docker's genius comes in:&lt;br&gt;
&lt;em&gt;"Don't worry! We'll contain them. Your 4 cheese part won't even know about the pineapple part."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So Docker's magic is that it's able to use the same underlying Physical Machine&lt;br&gt;
and Operating System to run well-contained applications of many&lt;br&gt;
different "flavors" without them ever conflicting with each other.&lt;br&gt;
And to keep exotic fruit off your pizza.&lt;/p&gt;

&lt;p&gt;Alright, let's move on to creating our first Docker Container.&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating a Docker Container
&lt;/h3&gt;

&lt;p&gt;Creating a Docker container is really easy, but you'll need to have Docker installed on your machine.&lt;/p&gt;

&lt;p&gt;You'll be able to install Docker regardless of your Operating System.&lt;br&gt;
It has support for Linux, Mac, and Windows, but I would strongly advise sticking to Linux for production.&lt;/p&gt;

&lt;p&gt;Once you have Docker installed, it is time to create the container!&lt;/p&gt;

&lt;p&gt;Docker looks for a specific file called &lt;code&gt;Dockerfile&lt;/code&gt; and it will use it to create&lt;br&gt;
a recipe for your container that we call a Docker Image.&lt;br&gt;
So before we create a container, we'll have to create that file.&lt;/p&gt;

&lt;p&gt;Let's create this file in the same directory we have our &lt;code&gt;index.js&lt;/code&gt; file and &lt;code&gt;package.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Dockerfile&lt;/span&gt;

&lt;span class="c"&gt;# Base image (we need Node)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:12&lt;/span&gt;

&lt;span class="c"&gt;# Work directory&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/myapp&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./package*.json ./&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Copy app source code&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./ ./&lt;/span&gt;

&lt;span class="c"&gt;# Set environment variables you need (if you need any)&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_ENV='production'&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PORT=3000&lt;/span&gt;

&lt;span class="c"&gt;# Expose the port 3000 on the container so we can access it&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="c"&gt;# Specify your start command, divided by commas&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; [ "node", "index.js" ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is smart to use a &lt;code&gt;.dockerignore&lt;/code&gt; file in the same directory to ignore files&lt;br&gt;
and directories you might not want to copy. You can think of it as working the same as &lt;code&gt;.gitignore&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .dockerignore

node_modules
npm-debug.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that you have everything set up, it's time to build the Docker Image!&lt;/p&gt;

&lt;p&gt;You can think of an image as a recipe for your container.&lt;br&gt;
Or, if you're old enough, you might remember having disks for software installers.&lt;br&gt;
It wasn't the actual software running on it, but it contained the packaged software data.&lt;/p&gt;

&lt;p&gt;You can use the command below to create the image. You can use the &lt;code&gt;-t&lt;/code&gt; flag to name your image and&lt;br&gt;
find it easier later. Also, make sure you opened up the terminal to the directory where your &lt;code&gt;Dockerfile&lt;/code&gt; is located.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; myapp &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if you list your images, you'll be able to see your image on the list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker image &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have your image ready, you're just one command away from having your container up and running.&lt;/p&gt;

&lt;p&gt;Let's execute the command below to spin it up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll be able to see your server starting up with the container and read your logs in the process.&lt;br&gt;
If you'd like to spin it up in the background, use the &lt;code&gt;-d&lt;/code&gt; flag before your image name.&lt;/p&gt;

&lt;p&gt;Also, if you're running the container in the background, you can print a list of containers using the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far so good! I think you should have a pretty good idea about how containers work at this point,&lt;br&gt;
so instead of diving into the details, let's move ahead to a topic very closely tied to recovery: Orchestration!&lt;/p&gt;
&lt;h2&gt;
  
  
  Orchestration
&lt;/h2&gt;

&lt;p&gt;If you don't have an operations background, chances are you're thinking about containers&lt;br&gt;
as some magical sophisticated components. And you would be right in thinking that.&lt;br&gt;
They are magical and complex. But it doesn't help to have that model in our minds, so it's time to change that.&lt;/p&gt;

&lt;p&gt;It's best to think about them as the simplest components of our infrastructure, sort of like Lego blocks.&lt;/p&gt;

&lt;p&gt;Ideally, you don't even want to be managing these Lego blocks individually&lt;br&gt;
because it's just too fiddly. You'd want another entity that handles them for you,&lt;br&gt;
sort of like the process manager that we discussed earlier.&lt;/p&gt;

&lt;p&gt;This is where &lt;em&gt;Orchestrators&lt;/em&gt; come into play.&lt;/p&gt;

&lt;p&gt;Orchestrators help you manage and schedule your containers and they allow you&lt;br&gt;
to do this across multiple container hosts (VMs) distributed across multiple locations.&lt;/p&gt;

&lt;p&gt;The orchestrator feature that interests us the most in this context is &lt;em&gt;Replication&lt;/em&gt;!&lt;/p&gt;
&lt;h3&gt;
  
  
  Replication and High Availability
&lt;/h3&gt;

&lt;p&gt;Restarting our server when it crashes is great, but what happens&lt;br&gt;
during the time our server is restarting? Should our users be waiting for the service&lt;br&gt;
to get back up? How do they know it will be back anyway?&lt;/p&gt;

&lt;p&gt;Our goal is to make our service &lt;em&gt;Highly Available&lt;/em&gt;, meaning that our&lt;br&gt;
users are able to use our app even if it crashes.&lt;/p&gt;

&lt;p&gt;But how can it be used if it's down?&lt;/p&gt;

&lt;p&gt;Simple. Make copies of your server and run them simultaneously!&lt;/p&gt;

&lt;p&gt;This would be a headache to set up from scratch, but luckily, we have everything&lt;br&gt;
that we need to enable this mechanism.&lt;br&gt;
Once your app is containerized, you can run as many copies of it as you'd like.&lt;/p&gt;

&lt;p&gt;These copies are called &lt;em&gt;Replicas&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So let's look into how we would set up something like this using a container orchestration engine.&lt;br&gt;
There are quite a few out there, but the easiest one to get started with is&lt;br&gt;
Docker's orchestration engine, Docker Swarm.&lt;/p&gt;
&lt;h3&gt;
  
  
  Replication in Swarm
&lt;/h3&gt;

&lt;p&gt;If you have Docker installed on your machine, you're just one command away from using Docker Swarm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker swarm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command enables Docker Swarm for you and it allows you to form a distributed cluster&lt;br&gt;
by connecting other VMs to the Swarm. For this example, we can just use a single machine.&lt;/p&gt;

&lt;p&gt;So, with Docker Swarm enabled, we now have access to the components called &lt;code&gt;services&lt;/code&gt;.&lt;br&gt;
They are the bread and butter of a microservice style architecture,&lt;br&gt;
and they make it easy for us to create replicas.&lt;/p&gt;

&lt;p&gt;Let's create a service! Remember the image name we used when we built our Docker image?&lt;br&gt;
It's the same image we're going to use here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker service create &lt;span class="nt"&gt;--name&lt;/span&gt; myawesomeservice &lt;span class="nt"&gt;--replicas&lt;/span&gt; 3 myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command above will create a service named &lt;code&gt;myawesomeservice&lt;/code&gt; and it will use the image&lt;br&gt;
named &lt;code&gt;myapp&lt;/code&gt; to create 3 identical containers.&lt;/p&gt;

&lt;p&gt;You'll be able to list your services with the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker service &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that there's a service with the name you specified.&lt;/p&gt;

&lt;p&gt;To be able to see the containers that have been created, you can use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that our server is running replicated, the service will make sure to always&lt;br&gt;
restart the container if it crashes, and it can offer access to the healthy containers throughout the process.&lt;/p&gt;

&lt;p&gt;If you'd like to adjust the number of replicas of a service, you can use the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker service scale &amp;lt;name_of_service&amp;gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;number_of_replicas&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker service scale &lt;span class="nv"&gt;myapp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're able to run as many replicas as you'd like, just as simple as that.&lt;/p&gt;

&lt;p&gt;Isn't that awesome? Let's look at one last example and see how we would approach replication in Kubernetes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Replication in Kubernetes
&lt;/h3&gt;

&lt;p&gt;It's hard to skip &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; in a discussion about orchestration.&lt;br&gt;
It's the gold standard when it comes to orchestration, and rightfully so.&lt;/p&gt;

&lt;p&gt;I think Kubernetes has a much steeper learning curve than Swarm, so if you're just getting&lt;br&gt;
started with containers I'd suggest picking up Swarm first. That said, it doesn't hurt to have&lt;br&gt;
a general understanding of how this would work in the world of K8S.&lt;/p&gt;

&lt;p&gt;If you don't feel like &lt;a href="https://kubernetes.io/docs/tasks/tools/install-minikube/"&gt;installing minikube&lt;/a&gt;&lt;br&gt;
or you don't want to fiddle with cloud providers,&lt;br&gt;
there's an easy option to dabble in Kubernetes for a bit, by using the&lt;br&gt;
&lt;a href="https://labs.play-with-k8s.com/"&gt;Play with Kubernetes&lt;/a&gt; online tool.&lt;br&gt;
It gives you a 4-hour session which should be more than enough for small experiments.&lt;/p&gt;

&lt;p&gt;To be able to follow this exercise, please make sure that you created&lt;br&gt;
a &lt;a href="http://dockerhub.com/"&gt;DockerHub&lt;/a&gt; account, and pushed up the docker image to your repo!&lt;/p&gt;

&lt;p&gt;We're going to create two components by creating two &lt;code&gt;.yml&lt;/code&gt; configuration files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A Cluster IP Service&lt;/strong&gt; — this is going to open up a port for us to communicate with our app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Deployment&lt;/strong&gt; — which is sort of like a service in Docker Swarm, with a bit more bells and whistles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's first start with the ClusterIP. Create a &lt;code&gt;cluster-ip.yml&lt;/code&gt; file and paste the following content into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# cluster-ip.yml&lt;/span&gt;

&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-ip-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterIP&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;server&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a Deployment as well. Within a &lt;code&gt;deployment.yml&lt;/code&gt; file, you can paste the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# deployment.yml&lt;/span&gt;

&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;server-deployment&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;server&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;server&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;server&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;your_docker_user/your_image&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll need to make sure that you substituted the &lt;code&gt;your_docker_user/your_image&lt;/code&gt; with your&lt;br&gt;
actual user and image name and you have that image hosted on your Docker repo.&lt;/p&gt;

&lt;p&gt;Now that we have these two files ready, all we need to do to spin this up is to execute&lt;br&gt;
the command below. Make sure you're executing it in the directory that contains the files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now check if your server is up and running by listing the &lt;em&gt;deployments&lt;/em&gt; and &lt;em&gt;services&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything worked out according to plan,&lt;br&gt;
you should be able to copy-paste the &lt;code&gt;IP&lt;/code&gt; and &lt;code&gt;Port&lt;/code&gt; from your &lt;code&gt;cluster-ip-service&lt;/code&gt; into your&lt;br&gt;
browser's address bar to access your application.&lt;/p&gt;

&lt;p&gt;To see the replicas that have been created, you can use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pods listed should correspond to the number of replicas you specified in your &lt;code&gt;deployment.yml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;To clean up all the components, you can simply execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And just like that, we learned about Replication within Kubernetes as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So, we have an application that recovers and is highly available. Is that all there is to it?&lt;/p&gt;

&lt;p&gt;Not at all. In fact, now that your app doesn't "go down", how do you know what issues it might be having?&lt;/p&gt;

&lt;p&gt;By looking at the logs? Be honest. If your app is up every time you check the endpoint,&lt;br&gt;
you'll probably check the logs about two times per year.&lt;br&gt;
There's more interesting stuff to look at on social media.&lt;/p&gt;

&lt;p&gt;So, to make sure your app is improving, you'll have to start thinking about monitoring,&lt;br&gt;
error handling, and error propagation. You'll have to make sure that you're aware of issues&lt;br&gt;
as they arise, and you're able to fix them even if they don't keep your server down.&lt;/p&gt;

&lt;p&gt;That's a topic for another time though, I hope you enjoyed this article&lt;br&gt;
and it was able to shed some light on some of the approaches you could use&lt;br&gt;
to enable recovery for your Node.js application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S. If you liked this post, &lt;a href="https://blog.appsignal.com/javascript-sorcery"&gt;subscribe to our new JavaScript Sorcery list&lt;/a&gt; for a monthly deep dive into more magical JavaScript tips and tricks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S. If you'd love an all-in-one APM for Node.js or you're already familiar with AppSignal, go and &lt;a href="https://www.appsignal.com/nodejs"&gt;check out AppSignal for Node.js&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>security</category>
      <category>devops</category>
    </item>
    <item>
      <title>Node.js Resiliency Concepts: The Circuit Breaker</title>
      <dc:creator>Andrei Gaspar</dc:creator>
      <pubDate>Wed, 29 Jul 2020 13:53:14 +0000</pubDate>
      <link>https://dev.to/appsignal/node-js-resiliency-concepts-the-circuit-breaker-1k51</link>
      <guid>https://dev.to/appsignal/node-js-resiliency-concepts-the-circuit-breaker-1k51</guid>
      <description>&lt;p&gt;In 2009 Node.js opened up a door for front-end developers to dip their toes into the world of servers &lt;br&gt;
without having to leave the comfort of their language.&lt;/p&gt;

&lt;p&gt;It's almost effortless to get started with Node. &lt;br&gt;
You can basically copy-paste an entire HTTP server into existence and then install an ODM and you've got your CRUD app ready to roll!&lt;/p&gt;

&lt;p&gt;However, if we've learned anything from the amazing Spider-Man, &lt;br&gt;
it's that with great power, comes great responsibility.&lt;/p&gt;

&lt;p&gt;So, in this article, we're going to discuss how you can wield your Node-given powers responsibly, &lt;br&gt;
and design servers that don't just work, but are also &lt;em&gt;resilient&lt;/em&gt; and &lt;em&gt;adaptive to failures&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👋 AppSignal now supports Node.js as well. In the coming weeks, we’ll be adding a whole array of integrations i.e. support more things out-of-the-box. We already have support for Next.js, PostgreSQL, and Express. &lt;a href="https://www.appsignal.com/nodejs"&gt;Learn more about AppSignal for Node.js&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Resiliency and Chill
&lt;/h2&gt;

&lt;p&gt;One of the biggest names in the industry when it comes to server resiliency design is Netflix. &lt;br&gt;
They are &lt;em&gt;extremely&lt;/em&gt; dedicated to designing robust systems that will serve us all seasons &lt;br&gt;
of Grey's Anatomy any minute of the day!&lt;/p&gt;

&lt;p&gt;But what is this &lt;em&gt;"resiliency"&lt;/em&gt; anyway?&lt;/p&gt;

&lt;p&gt;Well, resiliency is just a fancy word for the ability of your system to recover from failures &lt;br&gt;
and continue operating.&lt;/p&gt;

&lt;p&gt;If the power goes out and it continues to work, your system is &lt;em&gt;resilient&lt;/em&gt;. &lt;br&gt;
If there is an equipment failure and the system keeps on going, it is even more resilient. &lt;br&gt;
If you hit it with a baseball bat and the system is still up... you get the idea.&lt;/p&gt;

&lt;p&gt;However, in our case, we're more interested in providing &lt;strong&gt;API resiliency&lt;/strong&gt;. &lt;br&gt;
So, let's see how we would identify a resilient API. &lt;br&gt;
What are some of the core principles of a resilient API?&lt;/p&gt;

&lt;p&gt;Well, let's learn from the pros. Let's see what Netflix has to say about it.&lt;/p&gt;

&lt;p&gt;Netflix defines the principles of resiliency as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A failure in a service dependency should not break the user experience.&lt;/li&gt;
&lt;li&gt;The API should automatically take corrective action when one of its service dependencies fails.&lt;/li&gt;
&lt;li&gt;The API should be able to show us what's happening right now, 
in addition to what was happening 15-30 minutes ago, yesterday, last week, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are also responsible for fault tolerance libraries and sophisticated tools &lt;br&gt;
for dealing with latency and fault tolerance in distributed systems.&lt;/p&gt;

&lt;p&gt;To deal with the problem of fault tolerance, most of these solutions use &lt;br&gt;
a popular software design pattern called &lt;strong&gt;circuit-breaker&lt;/strong&gt;, &lt;br&gt;
which is the exact pattern that we're going to be discussing in detail in the upcoming sections.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Circuit Breaker Pattern
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Circuit Breaker&lt;/strong&gt; in software design is named after it's equivalent in electrical engineering, &lt;br&gt;
where it serves as a switch designed to stop the flow of the current in an electric circuit. &lt;br&gt;
It is used as a safety measure to protect the circuit from overload or short circuit.&lt;/p&gt;

&lt;p&gt;Circuit breakers come in all shapes and sizes, there are some that reset automatically, &lt;br&gt;
some that need to be reset manually, but they all essentially do the same thing — open the circuit &lt;br&gt;
if there's trouble.&lt;/p&gt;

&lt;p&gt;The Circuit Breaker was popularized by Miachel Nygard with his book &lt;a href="https://www.amazon.com/Release-Production-Ready-Software-Pragmatic-Programmers/dp/0978739213"&gt;Release It!&lt;/a&gt;, &lt;br&gt;
where he describes this pattern along with other useful information about architecting &lt;br&gt;
resilient and performant software.&lt;/p&gt;

&lt;p&gt;So if the electrical circuit breaker manages the flow of current, what does it's software equivalent do?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The circuit breaker manages the flow of requests to an upstream resource.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's think of the upstream resource as a remote server for the time being, &lt;br&gt;
but it is certainly not limited to being that. Circuit breakers can also be used &lt;br&gt;
locally to protect one part of your system from failure from another part.&lt;/p&gt;

&lt;p&gt;The circuit breaker monitors for failures, and when the failures reach a certain threshold, &lt;br&gt;
it &lt;em&gt;trips&lt;/em&gt; and none of the successive calls will be forwarded to the upstream resource.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Would We Bother Using a Circuit Breaker?
&lt;/h2&gt;

&lt;p&gt;With the rising popularity of microservices, it is common for apps to make remote calls &lt;br&gt;
to other apps running on different processes across a network. &lt;br&gt;
It is often the case that the system is spread out across multiple machines as well.&lt;/p&gt;

&lt;p&gt;Some of these services act as dependencies for others, &lt;br&gt;
and it is not unusual to have multiple dependencies upstream.&lt;/p&gt;

&lt;p&gt;Even if we forget about microservices altogether, &lt;br&gt;
think about how common it is for applications to make remote calls. &lt;br&gt;
It is almost unavoidable that it will have integrations and will rely on upstream resources.&lt;/p&gt;

&lt;p&gt;Another popular case is an API gateway, where a service's primary purpose is to proxy requests upstream. &lt;br&gt;
In this case, the health of the application is very closely tied to the health of the upstream resource.&lt;/p&gt;

&lt;p&gt;So, we have all these cases where requests are being passed upstream, but &lt;strong&gt;why use a circuit breaker&lt;/strong&gt;? &lt;br&gt;
And why don't we just let the request fail at its own pace?&lt;/p&gt;
&lt;h3&gt;
  
  
  Preserve Resources
&lt;/h3&gt;

&lt;p&gt;Wasteful calls pile up on the upstream resource which might be already struggling &lt;br&gt;
with serving previous requests, further escalating the problem.&lt;/p&gt;

&lt;p&gt;Wasteful calls can also be a big problem for the &lt;strong&gt;service making those calls&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Resources such as threads might be consumed while waiting for the upstream resource to respond, &lt;br&gt;
which can lead to resource exhaustion.&lt;/p&gt;

&lt;p&gt;This can in turn lead to the service being unable to handle other requests.&lt;/p&gt;

&lt;p&gt;So, wasteful calls can bring down services, &lt;br&gt;
and the failure can cascade to other services throughout the application.&lt;/p&gt;
&lt;h3&gt;
  
  
  Fail Fast
&lt;/h3&gt;

&lt;p&gt;Imagine you're throwing a party on a Saturday evening. &lt;br&gt;
You're making preparations, sending invitations to all your friends.&lt;/p&gt;

&lt;p&gt;Would you prefer them to respond instantly, or would you prefer them to respond the day after the party?&lt;/p&gt;

&lt;p&gt;I know, I'd go with option one.&lt;/p&gt;

&lt;p&gt;We want responses fast so that we can adapt to them even if it means not getting what we asked for.&lt;/p&gt;

&lt;p&gt;This concept in systems design is called &lt;em&gt;failing fast&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Fail Proactively
&lt;/h3&gt;

&lt;p&gt;When upstream resources give us lemons, we make lemonade.&lt;/p&gt;

&lt;p&gt;You might not be able to prevent upstream failures, but you can always manage them proactively, &lt;br&gt;
and make the most out of what you got.&lt;/p&gt;

&lt;p&gt;Here are some common solutions to improve the failure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fallbacks&lt;/strong&gt; - in certain cases, you might be able to fall back to another service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defaults&lt;/strong&gt; - in certain cases, the integrity of the data is not crucially important, 
and defaults serve a good enough purpose until the upstream resource recovers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache&lt;/strong&gt; - you can serve cached requests until the upstream resource recovers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Avoid Polluting the Logs
&lt;/h3&gt;

&lt;p&gt;Your monitoring solution is one of the most important components of your system. &lt;br&gt;
Without it, you're completely blind to what happens inside the dark realm of containers and Linux servers.&lt;/p&gt;

&lt;p&gt;Metrics and logs are your eyes and ears. &lt;br&gt;
And the better the quality of logs, the better you're able to understand what happens with your system.&lt;/p&gt;

&lt;p&gt;If requests keep failing and you don't have a system in place that handles the situation gracefully, &lt;br&gt;
it will end up pumping ungodly amounts of pollution into your logs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Circuit Breaker States
&lt;/h2&gt;

&lt;p&gt;The circuit breaker has 3 main states which give us a clue about the &lt;br&gt;
health of the upstream resource or endpoint that we're targeting.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Closed&lt;/strong&gt; - the closed state means that the circuit is closed and everything is running smoothly. 
Just like in the case of an electrical circuit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open&lt;/strong&gt; - this state means that there is currently no connection upstream. 
In the case of an electrical circuit, if it is open, electricity cannot make its way through it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Half Open&lt;/strong&gt; - the half open state means it has experienced difficulties reaching the upstream resource, 
but it's now testing the waters with new requests to see if it can stabilize. 
If it does, it goes to the closed state, if requests fail, it opens the circuit again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even though these are the conventional names of circuit breaker states, &lt;br&gt;
I prefer not to use them because I find them deceptive and can be misleading for developers.&lt;/p&gt;

&lt;p&gt;When people see &lt;em&gt;Open&lt;/em&gt; they're intuitively associating it with OK, &lt;br&gt;
and &lt;em&gt;Closed&lt;/em&gt; sounds a lot like something went wrong.&lt;/p&gt;

&lt;p&gt;What I prefer to use instead are colors e.g. Red, Yellow, Green or &lt;br&gt;
descriptive names like Failing, Stabilizing, OK.&lt;/p&gt;

&lt;p&gt;So, for this demonstration, we're going to use colors to describe states, &lt;br&gt;
but remember, this is just personal preference!&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating Your Own Circuit Breaker
&lt;/h2&gt;

&lt;p&gt;There are plenty of libraries out there that we could use to implement our circuit breaker, &lt;br&gt;
but that would beat the purpose of the article since our goal is to understand how &lt;br&gt;
the circuit breaker pattern is implemented.&lt;/p&gt;

&lt;p&gt;So let's reinvent the wheel to learn how the wheel works.&lt;/p&gt;

&lt;p&gt;What we are going to code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The simplest &lt;a href="https://expressjs.com/"&gt;Express.js&lt;/a&gt; server to act as our upstream resource 
and simulate succeeding and failing requests.&lt;/li&gt;
&lt;li&gt;A configurable Circuit Breaker class that uses the &lt;a href="https://github.com/axios/axios"&gt;Axios&lt;/a&gt; library 
to make requests, and has basic logging capability.&lt;/li&gt;
&lt;li&gt;A few lines of code where we make use of our Circuit Breaker.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are going to use &lt;a href="https://www.typescriptlang.org/"&gt;TypeScript&lt;/a&gt; to implement these features.&lt;/p&gt;

&lt;p&gt;So, let's dive in!&lt;/p&gt;

&lt;p&gt;The first thing we want to do is to navigate to an empty directory of our choice, &lt;br&gt;
which will be our work directory, and execute the &lt;code&gt;npm init&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we have the &lt;code&gt;package.json&lt;/code&gt; file, it's time to install our main dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; express axios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we're using TypeScript, we'll also need some dev dependencies, so let's install those as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; typescript @types/express @types/axios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we're going to need a &lt;code&gt;tsconfig.json&lt;/code&gt; file to hold our TypeScript configuration. &lt;br&gt;
You can use the one below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es6"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commonjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sourceMap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"node_modules"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now our work directory should contain a &lt;code&gt;node_modules&lt;/code&gt; directory &lt;br&gt;
and three files: &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;package-lock.json&lt;/code&gt;, and &lt;code&gt;tsconfig.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is time to copy-paste a basic Express server into existence.&lt;/p&gt;

&lt;p&gt;Create a file called &lt;code&gt;index.ts&lt;/code&gt; and paste the following lines of code into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Success!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;`Listening at http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code snippet summons a simple express server that will be listening to &lt;code&gt;GET&lt;/code&gt; requests on &lt;br&gt;
localhost:3000, and randomly failing with &lt;code&gt;status 400&lt;/code&gt; or responding with &lt;code&gt;status 200&lt;/code&gt;. &lt;br&gt;
We'll be able to use this endpoint to test our Circuit Breaker.&lt;/p&gt;

&lt;p&gt;Before we go further with the implementation, let's add a couple of convenience scripts to &lt;br&gt;
our &lt;code&gt;package.json&lt;/code&gt; file so that we can build and start the server using npm commands.&lt;/p&gt;

&lt;p&gt;In the scripts section of your package.json, copy and paste the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
  "scripts": {
    "build": "tsc",
    "start-server": "npm run build &amp;amp;&amp;amp; node build/index.js"
  },
 ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will allow you to start your server with a simple &lt;code&gt;npm&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run start-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the command is executed, the server should print "Listening at.. localhost:3000" to the console.&lt;/p&gt;

&lt;p&gt;So far so good! Let's move on to the meat of the article, which is the Circuit Breaker itself!&lt;/p&gt;

&lt;p&gt;Let's create a &lt;code&gt;circuit-breaker&lt;/code&gt; directory, which will contain all the assets related to the Circuit Breaker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;circuit-breaker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's navigate into this directory and start thinking about the components &lt;br&gt;
that we'll need to make the circuit breaker a reality.&lt;/p&gt;

&lt;p&gt;First, we talked about states, so let's create a file called &lt;code&gt;BreakerStates.ts&lt;/code&gt; to define our states.&lt;/p&gt;

&lt;p&gt;We're going to use an enum and color codes for the states, to make it a bit more developer-friendly.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;BreakerStates.ts&lt;/code&gt; file let's declare an enum like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// circuit-breaker/BreakerStates.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;GREEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GREEN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;RED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;YELLOW&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YELLOW&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now that we have the states, what else do we need?&lt;/p&gt;

&lt;p&gt;We'll need some configuration options for our Circuit Breaker &lt;br&gt;
that will answer the following questions for us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many failures do we allow before moving to &lt;code&gt;RED&lt;/code&gt; state? Let's call this our &lt;code&gt;failureThreshold&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How many successes do we need before moving to &lt;code&gt;GREEN&lt;/code&gt; state? Let's call this our &lt;code&gt;successThreshold&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Once we are in &lt;code&gt;RED&lt;/code&gt; state, how much time should we wait before we allow a request to pass through? 
We'll call this our &lt;code&gt;timeout&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, immediately, we can see that we'll need a public class named &lt;code&gt;BreakerOptions&lt;/code&gt; &lt;br&gt;
that can hold these properties. We could also opt for an interface trick here, but let's stick &lt;br&gt;
to the conventional class-based approach.&lt;/p&gt;

&lt;p&gt;Let's create a file called &lt;code&gt;BreakerOptions.ts&lt;/code&gt; and define our public class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// circuit-breaker/BreakerOptions.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;BreakerOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;failureThreshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;successThreshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;){}}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we have the States and Options defined, we can start planning the CircuitBreaker &lt;br&gt;
class implementation. Since the circuit breaker will be making requests, &lt;br&gt;
and we're using Axios as our HTTP library, we'll have Axios as our dependency for this class.&lt;/p&gt;

&lt;p&gt;Let's think about the properties that we'll have in the class.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;request&lt;/strong&gt; - the request property will contain details about the request that we are going to attempt. 
Since we integrated with Axios, it would be smart to have this as the Axios request configuration. 
We can use the &lt;code&gt;AxiosRequestConfig&lt;/code&gt; type for that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;state&lt;/strong&gt; - this property can hold our circuit breaker state. 
We have a &lt;code&gt;BreakerState&lt;/code&gt; type created for this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;failureCount&lt;/strong&gt; - we will need something to count the number of failures with, 
let's use this property for that purpose.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;successCount&lt;/strong&gt; - same as failureCount, but for tracking successes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;nextAttempt&lt;/strong&gt; - we will need a property to store a timestamp for the next time 
when we try a request when we're in the &lt;code&gt;RED&lt;/code&gt; state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's not forget about the &lt;code&gt;BreakerOptions&lt;/code&gt; we defined! &lt;br&gt;
We'll need to store those inside the class as well. &lt;br&gt;
It would also be smart to make them optional and have default values defined for them within the class.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;failureThreshold&lt;/strong&gt; - lets us know when to switch to &lt;code&gt;RED&lt;/code&gt; state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;successThreshold&lt;/strong&gt; - lets us know when to switch to &lt;code&gt;GREEN&lt;/code&gt; state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;timeout&lt;/strong&gt; - lets us know how much to wait before the next attempt (in milliseconds).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a handful of properties to be defined. &lt;br&gt;
So let's set all this up before we move to the logic implementation.&lt;/p&gt;

&lt;p&gt;Let's create a file called &lt;code&gt;CircuitBreaker.ts&lt;/code&gt; where we'll define our CircuitBreaker class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// circuit-breaker/CircuitBreaker.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BreakerOptions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./BreakerOptions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./BreakerStates&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AxiosRequestConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;CircuitBreaker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AxiosRequestConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;failureCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;successCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;nextAttempt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Options&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;failureThreshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;successThreshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AxiosRequestConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;BreakerOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GREEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureCount&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successCount&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextAttempt&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureThreshold&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureThreshold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successThreshold&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successThreshold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Define defaults&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureThreshold&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successThreshold&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it's time to think about the methods that we'll need. &lt;br&gt;
Let's plan them out and then we can start implementing them one by one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;log&lt;/strong&gt; - we'll need a method to log the current state of the Circuit Breaker. 
We'll be able to use this same method to integrate with our monitoring system as well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;exec&lt;/strong&gt; - the execute method will be a public API through which we'll be able to trigger 
the request attempt. We'll need to make this into an asynchronous function because 
we'll be waiting for a server response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;success&lt;/strong&gt; - this method will handle the successful executions and return the upstream response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;failure&lt;/strong&gt; - this method will handle the failed attempts and return the upstream response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So let's start at the beginning and define our log method as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// circuit-breaker/CircuitBreaker.ts&lt;/span&gt;

   &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;Successes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;Failures&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;State&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All it's responsible for is taking the result and displaying it in a nice tabular format, &lt;br&gt;
including other details about the current state of our Circuit Breaker.&lt;/p&gt;

&lt;p&gt;Let's move on to the success method and define some logic. Here's what it should do for us.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Return the successful response.&lt;/li&gt;
&lt;li&gt;Reset the failure count.&lt;/li&gt;
&lt;li&gt;Log the status so that we're aware of what happened.&lt;/li&gt;
&lt;li&gt;If in &lt;code&gt;YELLOW&lt;/code&gt; state, increment the success count — and if the success count is larger than 
the threshold defined, reset and move to &lt;code&gt;GREEN&lt;/code&gt; state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sounds easy enough, let's write the code!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// circuit-breaker/CircuitBreaker.ts&lt;/span&gt;

    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;YELLOW&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successCount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successThreshold&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GREEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, we have success down — we'll do the same for failure. Here's the gist of it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Return the response.&lt;/li&gt;
&lt;li&gt;Increment the failure count.&lt;/li&gt;
&lt;li&gt;Log the status so that we're aware of the failure.&lt;/li&gt;
&lt;li&gt;If the failure count exceeds the threshold, move to &lt;code&gt;RED&lt;/code&gt; state, 
and define when our next attempt should take place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// circuit-breaker/CircuitBreaker.ts&lt;/span&gt;

    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureCount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureThreshold&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextAttempt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, the most important method to define, the exec method! &lt;br&gt;
This stands at the core of our mechanism. Let's see what it should do for us.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most importantly, if the state is &lt;code&gt;RED&lt;/code&gt; and the next attempt is scheduled sometime in the future, 
throw an Error and abort. We do not allow the request to go upstream.&lt;/li&gt;
&lt;li&gt;If the state is &lt;code&gt;RED&lt;/code&gt; but the timeout period expired, 
we want to switch state to YELLOW and allow the request to pass.&lt;/li&gt;
&lt;li&gt;If the state is NOT &lt;code&gt;RED&lt;/code&gt; we try to make the request, 
and based on whether the request succeeded or failed, we call the appropriate handler method.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple enough, right? Let's see how the implementation looks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// circuit-breaker/CircuitBreaker.ts&lt;/span&gt;

    &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RED&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextAttempt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;YELLOW&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Circuit suspended. You shall not pass.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, now that we have our &lt;code&gt;CircuitBreaker&lt;/code&gt; class all set up, &lt;br&gt;
it's time to see how we can use it to perform requests.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Before anything else though, here's the complete implementation of the class, &lt;br&gt;
you can review it to see if it matches yours!&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// circuit-breaker/CircuitBreaker.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BreakerOptions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./BreakerOptions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./BreakerStates&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AxiosRequestConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;



&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;CircuitBreaker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AxiosRequestConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;failureCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;successCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;nextAttempt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Options&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;failureThreshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;successThreshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;



    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AxiosRequestConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;BreakerOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GREEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureCount&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successCount&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextAttempt&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureThreshold&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureThreshold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successThreshold&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successThreshold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Define defaults&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureThreshold&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successThreshold&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;



    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;Successes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;Failures&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;State&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;



    &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RED&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextAttempt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;YELLOW&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Circuit suspended. You shall not pass.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;



    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;YELLOW&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successCount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successThreshold&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GREEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;



    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureCount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failureThreshold&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BreakerState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextAttempt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking good? Great!&lt;/p&gt;

&lt;p&gt;Alongside our &lt;code&gt;index.ts&lt;/code&gt; file, we can create a &lt;code&gt;test.ts&lt;/code&gt; file as well, that will contain a &lt;br&gt;
couple of lines of code for testing our masterpiece.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// test.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CircuitBreaker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./circuit-breaker/CircuitBreaker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;



&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;circuitBreaker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;span class="nx"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;circuitBreaker&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we imported the CircuitBreaker, &lt;br&gt;
created an instance of it and started calling the &lt;code&gt;exec()&lt;/code&gt; method at an interval of 1 second.&lt;/p&gt;

&lt;p&gt;Let's add one more script to our &lt;code&gt;package.json&lt;/code&gt; file to be able to run this test conveniently.&lt;/p&gt;

&lt;p&gt;The scripts section should look like this, updated with the &lt;code&gt;test-breaker&lt;/code&gt; script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
  "scripts": {
    "build": "tsc",
    "start-server": "npm run build &amp;amp;&amp;amp; node build/index.js",
    "test-breaker": "npm run build &amp;amp;&amp;amp; node build/test.js"
  },
  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's make sure the server is running!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run start-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in a separate terminal window, let's run the circuit breaker test as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run test-breaker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once executed, here's an example of the log stream that you should be seeing in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Success!
┌───────────┬───────────────┐
│  (index)  │    Values     │
├───────────┼───────────────┤
│  Result   │   'Failure'   │
│ Timestamp │ 1592222319902 │
│ Successes │       0       │
│ Failures  │       1       │
│   State   │    'GREEN'    │
└───────────┴───────────────┘
Request failed with status code 400
┌───────────┬───────────────┐
│  (index)  │    Values     │
├───────────┼───────────────┤
│  Result   │   'Failure'   │
│ Timestamp │ 1592222320906 │
│ Successes │       0       │
│ Failures  │       2       │
│   State   │    'GREEN'    │
└───────────┴───────────────┘
..............
┌───────────┬───────────────┐
│  (index)  │    Values     │
├───────────┼───────────────┤
│  Result   │   'Failure'   │
│ Timestamp │ 1592222321904 │
│ Successes │       0       │
│ Failures  │       3       │
│   State   │     'RED'     │
└───────────┴───────────────┘
...............
┌───────────┬───────────────┐
│  (index)  │    Values     │
├───────────┼───────────────┤
│  Result   │   'Failure'   │
│ Timestamp │ 1592222331941 │
│ Successes │       2       │
│ Failures  │       1       │
│   State   │   'YELLOW'    │
└───────────┴───────────────┘
...............
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this point forward, you can have as much fun with it as you like.&lt;/p&gt;

&lt;p&gt;You can start and stop the server while the circuit breaker is running to notice what happens, &lt;br&gt;
and you can also create different breakers with different &lt;code&gt;BreakerOptions&lt;/code&gt; like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// test.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CircuitBreaker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./circuit-breaker/CircuitBreaker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BreakerOptions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./circuit-breaker/BreakerOptions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;



&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;breaker1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BreakerOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;breaker2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BreakerOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="nx"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;breaker1&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;breaker2&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementation Granularity
&lt;/h2&gt;

&lt;p&gt;Once you have it up and running, the design choices are in your hands. &lt;br&gt;
You can choose to make a circuit breaker responsible for an entire upstream service or just target individual endpoints depending on your needs.&lt;/p&gt;

&lt;p&gt;Feel free to use different HTTP integrations, experiment with extending the &lt;br&gt;
breaker options and define multiple endpoints in your server to test with.&lt;/p&gt;

&lt;p&gt;Here are additional feature ideas to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an API for the breaker so that it can be reset or tripped by the operations staff.&lt;/li&gt;
&lt;li&gt;Implement an event system around the Circuit Breaker so you can subscribe 
different parts of your application to it.&lt;/li&gt;
&lt;li&gt;Integrate the breaker with your favorite monitoring solution.&lt;/li&gt;
&lt;li&gt;Implement a Queue to automatically retry failed requests. 
(Warning: don't use this for requests downstream waiting for a response.)&lt;/li&gt;
&lt;li&gt;Implement Caching to serve failed requests from the cache.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Parting Words
&lt;/h2&gt;

&lt;p&gt;This sums up our overview of the Circuit Breaker pattern! &lt;br&gt;
I hope this article helped you grasp a few resiliency principles &lt;br&gt;
and it sparked your imagination to try extending this boilerplate with some creative solutions.&lt;/p&gt;

&lt;p&gt;We reinvented the wheel to understand how it works, &lt;br&gt;
but custom solutions are not always the best choice. &lt;br&gt;
You have to analyze complexity and keep maintenance overhead in sight.&lt;/p&gt;

&lt;p&gt;Once you're comfortable with the basics, I would suggest you check out a few npm packages &lt;br&gt;
which are designed specifically for this purpose. &lt;br&gt;
There are a couple of candidates out there like opossum, hystrixJS, and brakes.&lt;/p&gt;

&lt;p&gt;It all depends on your requirements and I trust you to make the right decisions &lt;br&gt;
in your journey to improve system resiliency!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S. If you liked this post, &lt;a href="https://blog.appsignal.com/javascript-sorcery"&gt;subscribe to our new JavaScript Sorcery list&lt;/a&gt; for a monthly deep dive into more magical JavaScript tips and tricks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S. If you'd love an all-in-one APM for Node or you're already familiar with AppSignal, go and &lt;a href="https://www.appsignal.com/nodejs"&gt;check out AppSignal for Node.js&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Daydreaming about APIs and imagining web services — our guest author Andrei is a solutions architect by day and the co-founder of &lt;a href="//boardme.io"&gt;Boardme&lt;/a&gt; by night. When he's not typing frantically in a terminal, he's exploring nature, pretends to draw, and supplies bystanders with unsolicited gym advice.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Emojis as Website URLs 🤔</title>
      <dc:creator>Andrei Gaspar</dc:creator>
      <pubDate>Fri, 18 Oct 2019 10:04:15 +0000</pubDate>
      <link>https://dev.to/gasparandr/emojis-as-website-urls-1cae</link>
      <guid>https://dev.to/gasparandr/emojis-as-website-urls-1cae</guid>
      <description>&lt;p&gt;So here's a completely useless, yet mildly interesting idea I was fiddling with not that long ago — &lt;em&gt;can you use emojis as URLs in a website?&lt;/em&gt; Maybe the more important question would be: &lt;em&gt;should you?&lt;/em&gt; However, since I care more about the technical implications, I'm going to let someone else figure out the answer to that.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, is there a solution?
&lt;/h2&gt;

&lt;p&gt;Long story short, yes. I figured out a pretty straight forward solution for handing this, and it involves encoding emojis into URIs, and mapping them to routes on the server.&lt;/p&gt;

&lt;p&gt;Why encode them? — you might ask&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/AiEzloQTXzAeid9xQR/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/AiEzloQTXzAeid9xQR/giphy.gif" alt="why"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The answer is simple: because that's what the browser does when it executes the HTTP Request. So if you're using an emoji in your website URL, the browser encodes it into a URI and that's the route your server is called on.&lt;/p&gt;

&lt;p&gt;Here's how you encode an emoji&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;encodeURI('😊') // Result is "%F0%9F%98%8A"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Armed with this knowledge and with a burning desire for mischief, I started putting together a solution that offers emoji support for the basic routes of a website (think contact, pricing, terms, privacy, etc.)&lt;/p&gt;

&lt;p&gt;This is how &lt;strong&gt;&lt;code&gt;emoji-express 🚂&lt;/code&gt;&lt;/strong&gt; was born 🎉🎉🎉&lt;/p&gt;

&lt;p&gt;Emoji express is an open source &lt;a href="https://www.npmjs.com/package/emoji-express"&gt;npm package&lt;/a&gt;, designed to be working with the popular express framework for NodeJS, so I though the name was fitting. &lt;/p&gt;

&lt;p&gt;Initially it could do two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add emoji support to a website with 2 lines of code&lt;/li&gt;
&lt;li&gt;Let the user specify a custom string of emojis, that will redirect to a specific route in their website&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some examples would be:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/contact&lt;/code&gt; route&lt;/p&gt;

&lt;p&gt;&lt;a href="https://boardme.app/%F0%9F%93%AE"&gt;https://boardme.app/📮&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/pricing&lt;/code&gt; route&lt;/p&gt;

&lt;p&gt;&lt;a href="https://boardme.app/%F0%9F%92%B3"&gt;https://boardme.app/💳&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I received a request on twitter for a really interesting problem &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/2Y7lZAxlutI5MuVEzb/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/2Y7lZAxlutI5MuVEzb/giphy.gif" alt="intriguing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Translating emojis from URLs automatically
&lt;/h2&gt;

&lt;p&gt;To be able to solve this, you'd have to have the name of every single valid emoji, and all those names would have to be formatted to be URI compliant.&lt;/p&gt;

&lt;p&gt;So for example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://example.com/%F0%9F%A6%87%F0%9F%9A%B6%E2%80%8D%E2%99%82%EF%B8%8F"&gt;https://example.com/🦇🚶‍♂️&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;would be translated to: &lt;a href="https://example.com/batman-walking"&gt;https://example.com/batman-walking&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://example.com/%F0%9F%94%A5-in-the-%F0%9F%95%B3%EF%B8%8F"&gt;https://example.com/🔥-in-the-🕳️&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;would be translated to: &lt;a href="https://example.com/fire-in-the-hole"&gt;https://example.com/fire-in-the-hole&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It seemed like a straight forward enough problem if I can get my hands on the data; so I started looking for emoji datasets online, and sure enough I found the complete emojipedia dataset, that contained the emojis and their names.&lt;/p&gt;

&lt;p&gt;A couple nodejs scripts later, I had an array of all the emojis, with their names normalized, and their associated URIs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
...
{
        "emoji": "🐢",
        "name": "turtle",
        "URI": "%F0%9F%90%A2"
    },
    {
        "emoji": "🦎",
        "name": "lizard",
        "URI": "%F0%9F%A6%8E"
    },
    {
        "emoji": "🐍",
        "name": "snake",
        "URI": "%F0%9F%90%8D"
    },
...
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;One last problem to solve - emoji modifiers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I thought - OK problem solved, I'll just need to run a find-and-replace on the route, basically finding the URI and replacing it with the emoji name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o7TKOo9pQ3YUIjF2U/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o7TKOo9pQ3YUIjF2U/giphy.gif" alt="easy win"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NOPE.&lt;/p&gt;

&lt;p&gt;Turns out, there are URIs that share the same base, but they are decorated with emoji modifiers to express the type of the emoji. (e.g. male/female, color, size etc.)&lt;/p&gt;

&lt;p&gt;So, how do we make sure we are replacing the right URI? The answer is simple yet again: &lt;strong&gt;a decorated URI should be technically longer in size than a non-decorated URI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We are going to sort the emojis based on the length of their URI, before initiating the find-and-replace 💡&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const emojisSorted = emojis.sort( (a, b) =&amp;gt; ( a.URI.length &amp;lt; b.URI.length ) ? 1 : -1 );
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That is all it took! &lt;a href="https://www.npmjs.com/package/emoji-express"&gt;emoji-express&lt;/a&gt; now has automatic emoji translate support for routes 🎉&lt;/p&gt;

&lt;p&gt;Granted, there isn't much use for it, but it was a fun pet project to pick up. Feel free to take it for a ride!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>emoji</category>
      <category>node</category>
      <category>url</category>
    </item>
    <item>
      <title>Terraform with DigitalOcean on Windows</title>
      <dc:creator>Andrei Gaspar</dc:creator>
      <pubDate>Fri, 18 Oct 2019 09:06:18 +0000</pubDate>
      <link>https://dev.to/gasparandr/terraform-with-digitalocean-on-windows-j12</link>
      <guid>https://dev.to/gasparandr/terraform-with-digitalocean-on-windows-j12</guid>
      <description>&lt;p&gt;Terraform is a great tool for automating infrastructure management. You can think of it as infrastructure as code. Well, more like infrastructure as configuration — but you get the idea — you have some configs that spin up servers for you, and configure them the way you want.&lt;/p&gt;

&lt;p&gt;Terraform works with a long list of service providers (e.g. AWS, Azure, GCP etc.) and it can be tailored to work with your in-house solutions as well. In this article we're going to go through a simple example of spinning up a droplet on DigitalOcean.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you don't have a DigitalOcean account yet, sign up using &lt;a href="https://m.do.co/c/bf4c82930341"&gt;this link&lt;/a&gt; — you'll get $50 in credits, I'll get $25; fair deal.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Alright, that's enough of an introduction. Let's get started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/X8ynfaP1ZwTvTbxH1b/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/X8ynfaP1ZwTvTbxH1b/giphy.gif" alt="Get started"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DigitalOcean API token and SSH key
&lt;/h2&gt;

&lt;p&gt;We'll need to generate a token and set up an SSH key before we get started using Terraform, so let's get that out of the way.&lt;/p&gt;

&lt;p&gt;Once we're done here, we will have 4 important things that we'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API token&lt;/li&gt;
&lt;li&gt;Path to the private key we generated on your system&lt;/li&gt;
&lt;li&gt;Path to the public key we generated on your system&lt;/li&gt;
&lt;li&gt;SSH fingerprint of your key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Log in to DigitalOcean to follow these steps.&lt;/p&gt;

&lt;p&gt;Go to the &lt;code&gt;API&lt;/code&gt; menu item, and click &lt;code&gt;Generate New Token&lt;/code&gt;. Once this screen appears give it a name and press the &lt;code&gt;Generate Token&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3RBRWN3V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.andreigaspar.com/content/images/2019/10/image-14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3RBRWN3V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.andreigaspar.com/content/images/2019/10/image-14.png" alt="Get started"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once your token has been generated, copy it and &lt;strong&gt;stash it in a safe place&lt;/strong&gt;. Your token should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;72a134d5f2203f5dd58252998bf4823813541b8ac48be03b93e866a2e02072ea

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;del&gt;We got the first important thing&lt;/del&gt; ✔️&lt;/p&gt;

&lt;p&gt;On to the SSH key.&lt;/p&gt;

&lt;p&gt;Create an SSH key &lt;strong&gt;without a passphrase&lt;/strong&gt; by typing this command in your terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -t ecdsa
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Give it a name when prompted, and specify the directory where you'd like it to be generated.&lt;/p&gt;

&lt;p&gt;When it prompts for passphrase hit &lt;code&gt;ENTER&lt;/code&gt; twice (no passphrase provided).&lt;/p&gt;

&lt;p&gt;You should see something like this in the terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generating public/private ecdsa key pair.
Enter file in which to save the key (C:\some\path\on\your_system): KEY_NAME
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in KEY_NAME.
Your public key has been saved in KEY_NAME.pub.
The key fingerprint is:
SHA256:sIo7STxwxv2ltjAZ1hCVbUyE3G5sKWs3LA9lTZo3Nb9 andrei@DESKTOP-D8GRA4B
The key's randomart image is:
+---[ECDSA 256]---+
|   . BB+         |
|    o.= . o      |
|   . +.O . o     |
|  . = #o= . .    |
|   = X.=S+   .   |
|    O.B +   E    |
|   o.B = .       |
|    o.. .        |
|    oo           |
+----[SHA256]-----+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Save the paths for your private and public key to a text file, we're going to need them.&lt;/p&gt;

&lt;p&gt;&lt;del&gt;We got the second and third important things.&lt;/del&gt; ✔️&lt;/p&gt;

&lt;p&gt;Great, now that we have our SSH keys, copy the content of the public key  (yourkey.pub) you just generated, and head straight back to DigitalOcean.&lt;/p&gt;

&lt;p&gt;Find the &lt;code&gt;Security&lt;/code&gt; menu item to set up your SSH key, press &lt;code&gt;Add SSH Key&lt;/code&gt;, paste the content of your public key in the input and give it a name.&lt;/p&gt;

&lt;p&gt;Once you added the SSH key, it should appear under the list of SSH keys in a table showing it's name and it's fingerprint. We need that fingerprint, copy it and stash it somewhere safe.&lt;/p&gt;

&lt;p&gt;It should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;del&gt;The last important thing is stashed. Awesome stuff.&lt;/del&gt;  ✔️&lt;/p&gt;

&lt;p&gt;Now let's set up Terraform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Terraform
&lt;/h2&gt;

&lt;p&gt;Download the package from &lt;a href="https://www.terraform.io/downloads.html"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You'll download a zip file, which you'll unzip, and it should contain a file named &lt;code&gt;terraform.exe&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Copy or move that &lt;code&gt;terraform.exe&lt;/code&gt; file in a place you want to keep it e.g.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\Users\YOUR_USER\TF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now grab the &lt;strong&gt;path of the directory where you moved it&lt;/strong&gt;, and append it to your &lt;code&gt;Path&lt;/code&gt; environment variable — which you can find by simply typing &lt;code&gt;environment&lt;/code&gt; in the windows start search box.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dHGek8uJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.andreigaspar.com/content/images/2019/10/image-15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dHGek8uJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.andreigaspar.com/content/images/2019/10/image-15.png" alt="search box"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on Edit the system environment variables.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hEIPYycG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.andreigaspar.com/content/images/2019/10/image-16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hEIPYycG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.andreigaspar.com/content/images/2019/10/image-16.png" alt="system properties"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Append the directory path to the &lt;code&gt;Path&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;To test if it worked, restart your command prompt and type this command (it should return the version of Terraform).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform -v
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Awesome. Terraform should be locked and loaded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0pL7UTBy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media0.giphy.com/media/3o7buflZ5B9MTxcU7u/giphy.gif%3Fcid%3D790b76112c79d61a8a5f557853707bd6504a37346a79be35%26rid%3Dgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0pL7UTBy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media0.giphy.com/media/3o7buflZ5B9MTxcU7u/giphy.gif%3Fcid%3D790b76112c79d61a8a5f557853707bd6504a37346a79be35%26rid%3Dgiphy.gif" alt="Lock and load"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Terraform Project
&lt;/h2&gt;

&lt;p&gt;Now that we got these things out of the way, we can move on to working with Terraform. Let's  start by making a project directory somewhere, and adding two files into it. We'll name one &lt;code&gt;variables.tf&lt;/code&gt; and the other one &lt;code&gt;droplet.tf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;variables.tf&lt;/code&gt; file is where all those values that we stashed are going to come into play. You can paste the code below into it, and substitute the placeholders assigned to the &lt;code&gt;default&lt;/code&gt; keys with your values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable "token" {
    type = "string"
    description = "DigitalOcean API Token"
    default = "YOUR_TOKEN_HERE"
}
variable "public_key" {
    type = "string"
    description = "The Path to Your Public Key"
    default = "PATH_TO_TOUR_PUBLIC_KEY_HERE"
}
variable "private_key" {
    type = "string"
    description = "The Path to Your Private Key"
    default = "PATH_TO_YOUR_PRIVATE_KEY_HERE"
}
variable "ssh_fingerprint" {
    type = "string"
    description = "SSH Key fingerprint"
    default = "YOUR_SSH_FINGERPRINT_HERE"
}

provider "digitalocean" {
    token = "${ var.token }"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see we set up DigitalOcean as the provider. You can check the related documentation using &lt;a href="https://www.terraform.io/docs/providers/do/index.html"&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;droplet.tf&lt;/code&gt; file you can paste the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "digitalocean_droplet" "tfdroplet" {
    image = "ubuntu-18-04-x64"
    name = "tfdroplet"
    region = "lon1"
    size = "512mb"
    private_networking = true

    ssh_keys = [
        "${var.ssh_fingerprint}"
    ]

    connection {
        user = "root"
        type = "ssh"
        private_key = "${file(var.private_key)}"
        timeout = "2m"
        host = "${self.ipv4_address}"
    }

    provisioner "remote-exec" {
        inline = [
            "export PATH=$PATH:/usr/bin",
            "sudo apt-get update",
            "sudo apt-get -y install nginx"
        ]
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With the code above we're creating a small DigitalOcean droplet, and configuring it. It is going to run the Ubuntu 18.04 version, it's located in London, and it has a size of 512mb.&lt;/p&gt;

&lt;p&gt;After the droplet is created, we're also running an update command and install &lt;strong&gt;Nginx&lt;/strong&gt; to it, to demonstrate how you would go about doing something like this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launch 🚀
&lt;/h2&gt;

&lt;p&gt;Alright let's spin up this bad boy. This will be no more than 3 commands.&lt;br&gt;
To install the dependencies needed, let's launch a terminal in your project directory and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(you can think of this like an npm install, if you're familiar with node)&lt;/p&gt;

&lt;p&gt;After terraform has been initialized, we can now run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform plan
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This command is going to make an execution plan for you to preview, you should see something like this in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

digitalocean_droplet.tfdroplet: Refreshing state... 

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:
...
...
...
Plan: 1 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Lastly, we can run the apply command to create our droplet and configure it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform apply
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This might take a few seconds to complete, but after the installation finishes you'll be able to see your new droplet listed on your DigitalOcean account.&lt;/p&gt;

&lt;p&gt;If you want to SSH into it from Putty or your terminal, don't forget to use your private key that we created.&lt;/p&gt;

&lt;p&gt;That's about it. I hope you enjoyed this brief look into Terraform and you'll be excited to learn more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/kaBU6pgv0OsPHz2yxy/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/kaBU6pgv0OsPHz2yxy/giphy.gif" alt="Bye"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>digitalocean</category>
      <category>windows</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
