<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Muhib's Blog]]></title><description><![CDATA[I'm a Software Engineer interested in web and cross-platform technologies. I enjoy learning new concepts and technologies. This is my blog where I share my learning with others.]]></description><link>https://blog.muhib.me</link><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 19:32:14 GMT</lastBuildDate><atom:link href="https://blog.muhib.me/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The essence of writing clean code: Part I]]></title><description><![CDATA[Writing code is a form of art 🎨 Following the basic principles of clean code can help achieve the level of artistry. If you write code for a living 👩‍💻, then sooner or later clean code will matter a lot to you. The concepts shown here are the gist...]]></description><link>https://blog.muhib.me/the-essence-of-writing-clean-code-part-i</link><guid isPermaLink="true">https://blog.muhib.me/the-essence-of-writing-clean-code-part-i</guid><category><![CDATA[clean code]]></category><category><![CDATA[best practices]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[software development]]></category><category><![CDATA[coding]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Sat, 14 Oct 2023 19:55:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697312916242/db761cd2-d7d6-4818-8e99-5617a2947ac3.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Writing code is a form of art 🎨 Following the basic principles of clean code can help achieve the level of artistry. If you write code for a living 👩‍💻, then sooner or later clean code will matter a lot to you. The concepts shown here are the gist of the book <a target="_blank" href="https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">Clean Code: A Handbook of Agile Software Craftsmanship</a> 📖 by Robert C. Martin</p>
<p>Engineers spend <strong>80%</strong> of their time reading code, and the rest <strong>20%</strong> of their time actually writing 🤯. In a work environment, it's important that your colleagues can understand (and maintain) your code easily.</p>
<h1 id="heading-principles-of-writing-clean-code">Principles of writing clean code</h1>
<h2 id="heading-1-naming">1. Naming 🪧</h2>
<p>The most simple requirement, yet the most difficult to achieve 🫠 If naming isn't done properly, the rest of the clean code principles don't matter much. So this section will be a bit longer compared to others. While naming your variables, functions, classes and such keep in mind that the names should be:</p>
<ul>
<li><p>Descriptive but to the point</p>
</li>
<li><p>Implies what kind of data being stored</p>
</li>
</ul>
<h3 id="heading-variables-and-properties">Variables and Properties</h3>
<p>Now, look into the following Python code</p>
<pre><code class="lang-python"><span class="hljs-comment"># BAD</span>
ca = db.Column(db.DateTime, required=<span class="hljs-literal">False</span>);

<span class="hljs-comment"># GOOD </span>
created_at = db.Column(db.DateTime, required=<span class="hljs-literal">False</span>);
<span class="hljs-comment"># ---------</span>

<span class="hljs-comment"># Suppose, we're creating a user with admin level permission</span>
user = createAdminUser(...) <span class="hljs-comment"># BAD, not enough context</span>
userWithAdminPermission = createAdminUser(...) <span class="hljs-comment"># OKAY, long variable names are less preferred</span>
admin_user = createAdminUser(...) <span class="hljs-comment"># GOOD</span>
super_user = createAdminUser(...) <span class="hljs-comment"># GOOD</span>
</code></pre>
<p>Very simple yet strong example. Abbreviating variables or shortening them only creates confusion. <em>Remember, when you're writing the code, only you have the full context. Nevertheless, you should write code in such a way that people without context still understand the code easily 🤝</em></p>
<p>Now let's look at another example</p>
<pre><code class="lang-python"><span class="hljs-comment"># Example 1</span>
<span class="hljs-comment"># Storing raw user data as Python dictionary</span>
user_data = {
    <span class="hljs-string">'name'</span>: <span class="hljs-string">'Muhib'</span>,
    <span class="hljs-string">'age'</span>: <span class="hljs-number">27</span>,
    <span class="hljs-string">'email'</span>: <span class="hljs-string">'test@email.com'</span>
}

<span class="hljs-comment"># Example 2</span>
<span class="hljs-comment"># Creating a SQLAlchmey (ORM) User DB object</span>
user_data = new User(name, age, email); <span class="hljs-comment"># BAD (Arguable)</span>
user = new User(name, age, email) <span class="hljs-comment"># GOOD</span>
db_user = new User(name, age, email) <span class="hljs-comment"># GOOD</span>
</code></pre>
<p>Here, <code>user_data</code> can mean anything, it can refer to a Python dictionary or a Database (db) object. Our goal is to be more <strong>specific 🎯</strong>. According to SQLAlchemy convention, a simple variable named <code>user</code> should refer to a database object. To make it even more specific, we can name it <code>db_user</code>.</p>
<p>Although variables and properties are usually <strong>nouns</strong>, sometimes we should include <strong>adjectives</strong> as well to further clarify the context 😇. This is mostly true for boolean values:</p>
<pre><code class="lang-python"><span class="hljs-comment"># -- BAD --</span>
<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserDetails</span>:</span>
    name: str
    login: bool
    premiumSubscription: bool

<span class="hljs-comment"># -- GOOD --</span>
<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserDetails</span>:</span>
    name: str
    isLoggedIn: bool
    hasPremiumSubscription: bool
</code></pre>
<p>In this code, we're storing the login state of the user and if the user is subscribed to a premium package.</p>
<h3 id="heading-functions-and-methods">Functions and Methods</h3>
<p>The same principles apply to functions and methods, except you should incorporate <strong>verbs</strong> as well. For example, <code>login()</code>, <code>createUser()</code> , <code>database.insert()</code> are some good names.</p>
<p>Don't use names like <code>user()</code>, <code>email()</code> as they sound like properties ❌. Prefer <code>getUser()</code>, <code>getEmail()</code> instead✅. Remember to be more specific. If you're creating a user, use <code>createUser(</code> instead of <code>create()</code> .</p>
<p>Avoid using generic names. <code>processTransaction()</code> or <code>processUserRecord()</code> ✅ is far better than <code>processData()</code> ❌</p>
<p>Make sure that you're consistent with naming patterns. If you use <code>fetchUser</code> in your code, stick with the <code>fetch*</code> prefix throughout the code. Don't mix <code>fetchUser</code> and <code>getProducts</code> as they can create confusion. Use <code>fetchUser</code> and <code>fetchProducts</code> to be consistent.</p>
<h3 id="heading-classes">Classes</h3>
<p>Class names, by convention, should always be <strong>nouns</strong>. If one of your classes handle creating new user, then <code>UserFactory</code> (noun) is better than <code>CreateUser</code> (verb).</p>
<pre><code class="lang-python"><span class="hljs-comment"># User creation class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CreateUser</span>:</span> <span class="hljs-comment"># BAD</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BuildUser</span>:</span> <span class="hljs-comment"># BAD</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserFactory</span>:</span> <span class="hljs-comment"># GOOD</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span>:</span> <span class="hljs-comment"># OKAY, not bad, not good (arguable)</span>

<span class="hljs-comment"># Process website transactions</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Transaction</span>:</span> <span class="hljs-comment"># BAD, we're not creating transaction, we're processing it</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HandleTransaction</span>:</span> <span class="hljs-comment"># BAD, verb</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProcessTransaction</span>:</span> <span class="hljs-comment"># BAD, verb</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TransactionHandler</span>:</span> <span class="hljs-comment"># GOOD</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TransactionProcessor</span>:</span> <span class="hljs-comment"># GOOD</span>
</code></pre>
<h3 id="heading-casing"><strong>Casing</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Name</td><td>Example</td><td>Used in</td></tr>
</thead>
<tbody>
<tr>
<td>Camel Case</td><td>fetchProduct, getUser</td><td>JavaScript</td></tr>
<tr>
<td>Snake Case</td><td>fetch_product, get_user</td><td>Python</td></tr>
<tr>
<td>Pascal Case</td><td>FetchProduct, GetUser</td><td>C#</td></tr>
</tbody>
</table>
</div><p>These are the most common casing conventions. We should respect the cases while writing code for community acceptance. Consult the community guidelines for the language you use.</p>
<p>If you have been attentive for the past few minutes, you might have noticed that I violated this rule ⛔ somewhere above the code examples. Find it out! 🔎</p>
<p>Enough of naming, let's move forward to the next one</p>
<h2 id="heading-2-code-formatting">2. Code Formatting 💻</h2>
<p>A beginner's mistake 🧑‍🦱. They know about formatting practices but are not willing enough to follow them. There's nothing fancy here, so I am linking a good article which explains formatting: <a target="_blank" href="https://hackmd.io/@jenc/H1bgodhlo">Clean Code - Formatting</a>. If someone is interested, have a look!</p>
<h2 id="heading-3-writing-better-functions">3. Writing better functions 🔨</h2>
<h3 id="heading-keep-it-short">Keep it short</h3>
<p>Functions should be relatively short. I'm going to keep this simple, so not giving any specific line count. But, functions should be easy to read and easy to understand. Consider the following example in Python, which handles uploading images to a file server.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">upload_image</span>(<span class="hljs-params">image_data</span>):</span>
    image_fields = image_data.subdict([<span class="hljs-string">'title'</span>, <span class="hljs-string">'owner_id'</span>])
    image = Image(image_fields)
    db.session.add(image)
    db.session.commit()

    version_fields = image_data.subdict([<span class="hljs-string">'title'</span>, <span class="hljs-string">'mime_type'</span>, <span class="hljs-string">'blob'</span>])
    image_version = ImageVersion(version_fields)
    db.session.add(image_version)
    db.session.commit()

    tags = generate_tags(image_version)
    image_version.update_tags(tags)

    webhook_url = <span class="hljs-string">"https://example.com/webhook"</span>
    payload = {
        <span class="hljs-string">"asset_id"</span>: image.id,
        <span class="hljs-string">"version_id"</span>: image_version.id,
        <span class="hljs-string">"tags"</span>: tags
    }
    response = requests.post(webhook_url, json=payload)

    <span class="hljs-keyword">if</span> response.status_code != <span class="hljs-number">200</span>:
        <span class="hljs-keyword">raise</span> WebhookError(<span class="hljs-string">'Notify failed'</span>)
</code></pre>
<p>If you look into it for a good amount of time 😖, the code is not difficult to understand at all. But our goal is to reduce the thinking time and avoid unnecessary loads on our brains 🧠. So, here's what we're gonna do, we're going to refactor the above code 💡:</p>
<pre><code class="lang-python"><span class="hljs-comment"># After refactor</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">upload_image</span>(<span class="hljs-params">image_data</span>):</span>
    image = create_asset(image_data, Image)
    image_version = create_version(image_data)

    <span class="hljs-keyword">try</span>:
        notify_webhook(image, image_version)
    <span class="hljs-keyword">except</span> WebhookError:
        logger.warn(<span class="hljs-string">'Failed to notify'</span>)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_asset</span>(<span class="hljs-params">asset_fields, model</span>):</span>
    fields = asset_fields.subdict([<span class="hljs-string">'title'</span>, <span class="hljs-string">'owner_id'</span>])
    asset = model(fields)
    db.session.add(asset)
    db.session.commit()
    <span class="hljs-keyword">return</span> asset

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_version</span>(<span class="hljs-params">version_data</span>):</span>
    fields = version_data.subdict([<span class="hljs-string">'title'</span>, <span class="hljs-string">'mime_type'</span>, <span class="hljs-string">'blob'</span>])
    version = Version(fields)
    db.session.add(version)
    db.session.commit()

    tags = generate_tags(version)
    version.update_tags(tags)

    <span class="hljs-keyword">return</span> version

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">generate_tags</span>():</span>
    <span class="hljs-keyword">pass</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">notify_webhook</span>(<span class="hljs-params">asset, version</span>):</span>
    webhook_url = <span class="hljs-string">"https://example.com/webhook"</span>
    payload = {
        <span class="hljs-string">"asset_id"</span>: asset.id,
        <span class="hljs-string">"version_id"</span>: version.id,
        <span class="hljs-string">"tags"</span>: version.tags
    }
    response = requests.post(webhook_url, json=payload)

    <span class="hljs-keyword">if</span> response.status_code != <span class="hljs-number">200</span>:
        <span class="hljs-keyword">raise</span> WebhookError(<span class="hljs-string">'Notify failed'</span>)
</code></pre>
<p>We basically <strong>extracted</strong> the concepts into different functions and tried to make them generic. After refactoring, just look into the <code>upload_image</code> method. It's so concise and easy to understand 🥳. Yes, the line of code might have increased a bit. But now, not only the code is <strong>easy to understand</strong>, but many functions are <strong>reusable</strong> as well 🐼. If we add a new method <code>upload_video</code>, we should be able to reuse and keep the flow simple. Furthermore, another engineer can look into the code and choose to delve deeper only if required, previously it was not possible, he had to read the full code to get the gist. There are more complex forms of refactoring, but those are out of scope for this article.</p>
<h3 id="heading-make-it-read-like-an-instruction-manual">Make it read like an instruction manual</h3>
<p>There's another characteristic of the refactored code. Considering <code>upload_image</code> as the entry point, the code reads like a <strong>step-by-step instruction manual</strong>. That's how the functions are ordered one after another. We can use the <code>TO &lt;describe&gt;</code> pattern to read the code and evaluate ourselves.</p>
<blockquote>
<p>TO <code>upload_image</code>, we need to call <code>create_asset</code> , <code>create_version</code> and <code>notify_webhook</code> (sequentially)</p>
<p>TO <code>create_version</code>, we need to call <code>generate_tags</code></p>
<p>DONE</p>
</blockquote>
<p>If you look into the function ordering, you can see the functions come one after another: <code>upload_image -&gt; create_asset -&gt; create_version -&gt; generate_tags -&gt; notify_webhook</code> Think of it as <strong>depth-first-search</strong> but for reading functions 📥</p>
<p>But the big question is</p>
<p><strong><mark>When should you extract a group of code to a separate function?</mark></strong></p>
<p>In the last example, we just extracted different concepts to different functions. So it was simple. But in many cases, it might get more complicated 🚩. The next article in this series will discuss this in detail. That's all for today! Get your feet wet and start practising clean coding today 🫡 Thank you! 🙏</p>
]]></content:encoded></item><item><title><![CDATA[Why you should not use JWT for authentication]]></title><description><![CDATA[JWT (JSON Web Token) is a well-known and simple method of authenticating a user. Almost all tutorials you did on the backend, specially API building tutorials probably told you to use JWT. I also thought once that JWT is the modern and better authent...]]></description><link>https://blog.muhib.me/why-you-should-not-use-jwt-for-authentication</link><guid isPermaLink="true">https://blog.muhib.me/why-you-should-not-use-jwt-for-authentication</guid><category><![CDATA[JWT]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[backend]]></category><category><![CDATA[authentication]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Tue, 14 Feb 2023 18:54:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676467234038/63cc0351-cea7-42e3-9fb5-84060bb15285.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>JWT (JSON Web Token) is a well-known and simple method of authenticating a user. Almost all tutorials you did on the backend, specially API building tutorials probably told you to use JWT. I also thought once that JWT is the modern and better authentication method. Of course, it was a lack of my knowledge. This article tries to shed some light on this and show you some other alternatives of JWT, which can be better suited depending on your needs</p>
<h2 id="heading-what-is-jwt">What is JWT?</h2>
<p>JWT (JSON Web Token) is a <strong>stateless</strong> token containing user information, <strong>signed</strong> using public-private cryptography. As such, an intruder cannot modify the token information, because that would also change the signature.</p>
<p>A JWT token looks like this</p>
<pre><code class="lang-plaintext">eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
</code></pre>
<p>This example is taken from <a target="_blank" href="https://jwt.io/">jwt.io</a>. You will find the decoded version if you visit the page. It contains <code>sub</code> (user identification), <code>name</code> and <code>iat</code> (issuing time). Instead of <code>iat</code>, <code>exp</code> (expiry time) is also used.</p>
<p>This <a target="_blank" href="https://stytch.com/blog/jwts-vs-sessions-which-is-right-for-you/">image</a> can help you understand the breakdown</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676318723458/c2f1fbcc-a907-4bd3-aa37-271d59486aa0.jpeg" alt class="image--center mx-auto" /></p>
<h3 id="heading-advantages-of-jwt">Advantages of JWT</h3>
<p><strong>Stateless:</strong> It is stateless. So no data needs to be persisted to authenticate any user</p>
<p><strong>Self-contained data:</strong> You don't need any other source of truth to verify your user. Claims allow you to add extra data params, like if the user is <code>admin</code>.</p>
<h3 id="heading-disadvantages-of-jwt">Disadvantages of JWT</h3>
<p><strong>Client-controlled logout</strong></p>
<p>With JWT, the biggest problem is there are no reliable ways to log out users. The logout is fully controlled by the client, the server side can do nothing about it. It can just expect the client will forget about the token, that's it. This is dangerous from a security perspective.</p>
<p>You can, of course, use short-lived tokens and use <a target="_blank" href="https://www.geeksforgeeks.org/jwt-authentication-with-refresh-tokens/">refresh tokens</a> to fetch new JWT tokens. Let's say, your token expiration time is 2 mins. Now, you have to handle the complexity of using refresh tokens and generating new tokens every 2 minutes. This will be a big overhead in your front end. It will also cost your servers if your application grows large. Above all, you still don't have full control if you want to unauthenticate a user.</p>
<p><strong>Blacklisting user sessions</strong></p>
<p>Maybe some logins got marked as <em>unauthorized</em> by the user, maybe the login was suspicious, or the device is lost or not used anymore. In that case, you would want to blacklist that token. To do this, you would actually have to store those blacklisted tokens in a persistent database and check through them each time a user needs authorized access. This can be an overhead. Besides, storing blacklisted tokens is equivalent to <strong>maintaining state</strong> on the server, which somewhat defeats the purpose of JWT.</p>
<p><strong>Manually adding it to requests</strong></p>
<p>You have to add the JWT in each of your request headers manually or have some config in place to do that for you.</p>
<p><strong>Storage security</strong></p>
<p>Many devs use <code>localStorage</code> to store session tokens, which can be easily exploited through JavaScript XSS (Cross-site scripting) attacks. You can, however, store the token in secure cookies. But that would solve only one problem</p>
<p>So, what is the solution?</p>
<h2 id="heading-the-solution-good-old-session-cookies">The solution: Good old session cookies</h2>
<p>Session cookies are underrated. They are old but gold.</p>
<p>This is how it works: when a user logs in with the correct credentials, the server creates a random bearer token representing the session and sends the session back as a cookie.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>user_id</td><td>session_token</td><td>expiry</td></tr>
</thead>
<tbody>
<tr>
<td>2</td><td>47a0479900504cb3ab4a1f626d174d2d</td><td>1516239022</td></tr>
<tr>
<td>2</td><td>0050479900504cb3ab4a1f626d171f62</td><td>1516239822</td></tr>
<tr>
<td>5</td><td>0504cb39900504cb3ab4a1f626d171f6</td><td>1556239822</td></tr>
</tbody>
</table>
</div><p>The user id <code>2</code> is logged in with two different devices, thus two sessions. The <code>session_token</code>, which is random and unpredictable, will be sent as cookies.</p>
<p>Does managing it seem complex? Not really. Popular web frameworks have some abstraction in place to handle cookie-based sessions. In this article, we will see how we can use Flask to handle session cookies.</p>
<h3 id="heading-advantages-of-session-cookies">Advantages of session cookies</h3>
<p><strong>Server-controlled logout</strong></p>
<p>Whenever a user needs to log out, the server can just delete the session entry, and that's it. The user gets logged out immediately, totally controlled by the server. This is a more reliable solution compared to JWT.</p>
<p><strong>Blacklisting</strong></p>
<p>This is also easy. Why keep a list of blacklisted sessions when you can just delete them? If a user marks his device as lost, you can delete all the sessions of that user, forcing him to log in again with his credentials.</p>
<p><strong>Auto-attachment</strong></p>
<p>With how cookies work in general, you don't have to add the cookie with each of the request headers. Once the web browser receives a cookie, it will send the cookie automatically with each of the subsequent requests. These cookies are secure and cannot be accessed or modified using JavaScript.</p>
<h3 id="heading-disadvantages-of-session-cookies">Disadvantages of session cookies</h3>
<p><strong>Increased database read/write</strong></p>
<p>Sessions are persisted in DB. This might result in a slightly increased load on scaling. But in real-world systems, Redis is used to store user sessions, which solves this issue.</p>
<p><strong>CSRF Attack</strong></p>
<p>If not taken preventive measures, session cookies are vulnerable to Cross-site request forgery. To solve this issue in a dynamic website, <a target="_blank" href="https://stackoverflow.com/questions/5207160/what-is-a-csrf-token-what-is-its-importance-and-how-does-it-work/33829607#33829607">CSRF tokens</a> can be used. As for REST APIs, <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">CORS</a> (Cross-origin resource sharing) can be configured properly to prevent unwanted requests.</p>
<h3 id="heading-implementing-a-rest-like-api-with-flask-and-session-cookies">Implementing a REST-like API with Flask and session cookies</h3>
<p>I will demonstrate a simple example with Flask to use session cookies. We will use <a target="_blank" href="https://flask-login.readthedocs.io/">Flask-Login</a>, which will manage the session cookies for us.</p>
<p>First, we will create a User model and some mock database methods</p>
<pre><code class="lang-python"><span class="hljs-comment"># user.py</span>

<span class="hljs-keyword">from</span> flask_login <span class="hljs-keyword">import</span> UserMixin

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span>(<span class="hljs-params">UserMixin</span>):</span>
  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, id: int, name: str, email: str, password: str</span>):</span>
    self.id = id
    self.name = name
    self.email = email
    self.password = password <span class="hljs-comment"># in a real application, password would be hashed</span>

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_id</span>(<span class="hljs-params">self</span>):</span>
    <span class="hljs-comment"># required by flask_login</span>
    <span class="hljs-keyword">return</span> str(self.id)


<span class="hljs-comment"># Mock DB</span>
u1 = User(<span class="hljs-number">1</span>, <span class="hljs-string">'TestUser'</span>, <span class="hljs-string">'test@email.com'</span>, <span class="hljs-string">'weakpassword'</span>)
u2 = User(<span class="hljs-number">2</span>, <span class="hljs-string">'SecondUser'</span>, <span class="hljs-string">'rest@email.com'</span>, <span class="hljs-string">'pass2'</span>)
users = [u1, u2]

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_user</span>(<span class="hljs-params">id</span>):</span>
  <span class="hljs-keyword">for</span> user <span class="hljs-keyword">in</span> users:
    <span class="hljs-keyword">if</span> user.id == id:
      <span class="hljs-keyword">return</span> user
  <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>
</code></pre>
<p>The <a target="_blank" href="https://flask-login.readthedocs.io/en/latest/_modules/flask_login/mixins/#UserMixin">UserMixin</a> model implements some methods that are required by Flask-Login. This <code>get_user</code> will act as a fake database method.</p>
<p>Next, we need to instantiate <code>LoginManager()</code> . We will use a separate file for this:</p>
<pre><code class="lang-python"><span class="hljs-comment"># login_manager.py</span>

<span class="hljs-keyword">from</span> flask_login <span class="hljs-keyword">import</span> LoginManager
<span class="hljs-keyword">from</span> user <span class="hljs-keyword">import</span> get_user

login_manager = LoginManager()


<span class="hljs-meta">@login_manager.user_loader</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">load_user</span>(<span class="hljs-params">user_id</span>):</span>
  <span class="hljs-comment"># in a real application, you would fetch the user from DB</span>
  _id = int(user_id)
  <span class="hljs-keyword">return</span> get_user(_id)


<span class="hljs-meta">@login_manager.unauthorized_handler</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">unauthorized</span>():</span>
  <span class="hljs-keyword">return</span> {<span class="hljs-string">'message'</span>: <span class="hljs-string">'Unauthorized'</span>}, <span class="hljs-number">401</span>
</code></pre>
<p>The <code>load_user</code> method will be used by Flask-Login to reload a user. How the user is returned is totally up to you. In our case, we will be returning the user from our mock DB. In a real application, you would fetch the user using your ORM (SQLAlchemy, in most cases).</p>
<p>Finally, the <code>main.py</code> file will be used to include the routes and start the server.</p>
<pre><code class="lang-python"><span class="hljs-comment"># main.py</span>

<span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask, request
<span class="hljs-keyword">from</span> flask_login <span class="hljs-keyword">import</span> login_user, logout_user, login_required, current_user
<span class="hljs-keyword">from</span> user <span class="hljs-keyword">import</span> get_user
<span class="hljs-keyword">from</span> login_manager <span class="hljs-keyword">import</span> login_manager

app = Flask(__name__)
app.config[<span class="hljs-string">'SECRET_KEY'</span>] = <span class="hljs-string">'some-nice-secret-key'</span>

login_manager.init_app(app)


<span class="hljs-meta">@app.route('/heartbeat', methods=['GET'])</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">heartbeat</span>():</span>
  <span class="hljs-keyword">return</span> {<span class="hljs-string">'status'</span>: <span class="hljs-string">'OK'</span>}


<span class="hljs-meta">@app.route('/login', methods=['POST'])</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">login</span>():</span>
  data = request.get_json()
  user = get_user(data[<span class="hljs-string">'user_id'</span>])

  <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> user:
    <span class="hljs-keyword">return</span> {<span class="hljs-string">'message'</span>: <span class="hljs-string">'User not found'</span>}, <span class="hljs-number">400</span>

  <span class="hljs-keyword">if</span> user.email == data[<span class="hljs-string">'email'</span>] <span class="hljs-keyword">and</span> user.password == data[<span class="hljs-string">'password'</span>]:
    login_user(user)
  <span class="hljs-keyword">else</span>:
    <span class="hljs-keyword">return</span> {<span class="hljs-string">'message'</span>: <span class="hljs-string">'Invalid credentials'</span>}, <span class="hljs-number">400</span>

  <span class="hljs-keyword">return</span> {<span class="hljs-string">'message'</span>: <span class="hljs-string">'User logged in'</span>}


<span class="hljs-meta">@app.route('/logout', methods=['POST'])</span>
<span class="hljs-meta">@login_required</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logout</span>():</span>
  logout_user()
  <span class="hljs-keyword">return</span> {<span class="hljs-string">'message'</span>: <span class="hljs-string">'Logged out'</span>}


<span class="hljs-meta">@app.route('/profile/&lt;user_id&gt;', methods=['GET'])</span>
<span class="hljs-meta">@login_required</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">profile</span>(<span class="hljs-params">user_id</span>):</span>
  user = get_user(int(user_id))

  <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> user <span class="hljs-keyword">or</span> current_user.id != user.id:
    <span class="hljs-keyword">return</span> login_manager.unauthorized()

  <span class="hljs-keyword">return</span> {<span class="hljs-string">'name'</span>: user.name, <span class="hljs-string">'email'</span>: user.email}


app.run(host=<span class="hljs-string">'0.0.0.0'</span>, port=<span class="hljs-number">81</span>)
</code></pre>
<p>The <code>login</code> and <code>logout</code> methods are self-explanatory. Notice that the <code>logout</code> method doesn't take any kind of user-identifying param. Just calling <code>logout_user</code> will automatically fetch the session cookie attached to the request, and log the user out.</p>
<p>To access certain profile data, you have to be logged in as that user.</p>
<p>That's it! The full code can be accessed and run from <a target="_blank" href="https://replit.com/@ahmedsadman/session-login?v=1">this Repl</a> (Click <strong>Show Files</strong> to see the code).</p>
<h2 id="heading-where-to-use-jwt">Where to use JWT?</h2>
<p>Don't get me wrong, JWT is a solid solution, but it works best in certain scenarios, not all. In a gateway backend (backend directly communicating with web client), JWT complicates things. Besides server implementation, you have to maintain a whole lot of logic in the front end. On the other hand, cookies make everything simpler.</p>
<p>Although JWT might not always be the solution for your web API authentications, it definitely has some use of its own. It's a great way to gain temporary access to protected 3rd party resources. Or in another terms, JWT is best suited when communicating API to API.</p>
<p>Suppose, you use Spotify. Now, for the sake of this example, let's say a song is stored in AWS S3 and the access URL looks like this</p>
<pre><code class="lang-plaintext">https://s3.spotify.com/music/example-music.mp3?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
</code></pre>
<p>Notice the <code>token</code> param with the query. The token param has a JWT, which verifies that you're an authenticated user of Spotify and can access the music file for the next X minutes. Usually, file access is not directly related to your Web API in this case, so, a stateless token can be super useful to give privileged access to files.</p>
<p>The following diagram can help you understand this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676398705912/c4c86457-83b8-4c71-81d8-daaa8ccc1a42.png" alt class="image--center mx-auto" /></p>
<p>In the above example, Gateway API uses session cookies, and the related services are under a private network. But, S3 Access is separate from your business logic and thus it shouldn't know anything about your application. As such, a JWT token is the best approach to give controlled access to your S3 files (like the music files in Spotify in our example).</p>
<p>Thanks for reading this far. I hope this article clarified the concepts. If you liked it, please share it with your network. If you have any feedback or questions, drop them in the comments. Thanks again!</p>
]]></content:encoded></item><item><title><![CDATA[Docker: A conceptual overview]]></title><description><![CDATA[In modern DevOps, Docker is considered the most popular set of services for application containerization. In this article, we will NOT be covering a Docker tutorial, because a lot of good tutorials are already available on the internet. Instead, we w...]]></description><link>https://blog.muhib.me/docker-a-conceptual-overview</link><guid isPermaLink="true">https://blog.muhib.me/docker-a-conceptual-overview</guid><category><![CDATA[Docker]]></category><category><![CDATA[virtualization]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[hypervisor]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Sat, 03 Sep 2022 09:46:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1662198152164/SUf9AA5hP.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In modern DevOps, Docker is considered the most popular set of services for application containerization. In this article, we will NOT be covering a Docker tutorial, because a lot of good tutorials are already available on the internet. Instead, we will dive into the theory of how Docker works behind the scenes.</p>
<p>"Docker" is not a single tool, but rather a set of tools/components:</p>
<ol>
<li>Docker Client (user CLI to talk with other Docker components)</li>
<li>Docker Engine (the core engine with all the magic behind virtualization)</li>
<li>Docker Compose (run multiple containers)</li>
<li>Volumes (persistent disk space)</li>
<li>Docker Hub (place to store built images) etc.</li>
</ol>
<h2 id="heading-what-is-an-image">What is an Image?</h2>
<p>A single file with all the program dependencies and configuration included, which can be used to create containers that can be run anywhere. The <em>image</em> works as the <strong>blueprint</strong> to create <em>containers</em>.</p>
<h2 id="heading-what-is-a-container">What is a Container?</h2>
<p>An instance of an image which runs a program. This container can be run in any computer system without any extra hassle</p>
<p>Docker is used to create images and also run containers derived from those images. Images can be stored in <strong>Container Registries</strong> such as <strong>Docker Hub</strong>. You can think of Docker Hub as GitHub, but for Docker Images. Please note, you can also create your private container registries and keep your image there.</p>
<h1 id="heading-how-docker-work-behind-the-scenes">How Docker work behind the scenes?</h1>
<p>Before jumping into how Docker works, we need to understand how a process communicates with the hardware</p>
<p>Processes cannot talk to the hardware directly. They have to communicate with the <strong>Kernel</strong>, which works as the bridge between hardware and software</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662142241161/oLgWNuYdG.png" alt="pic1.drawio.png" /></p>
<p>The process uses a <strong>system call</strong> to talk with the Kernel. The <em>system call</em> is the API that can be used by external programs to communicate with the Kernel.</p>
<p>Now, let's say you have two processes, <em>Spotify</em> and <em>VSCode</em>. For the sake of this example, let's assume Spotify requires <em>Node v12</em>, while VSCode requires <em>Node v16</em>. Let's also assume that we cannot install multiple Node versions on the same machine. So in such a scenario, one of the applications will work and the other won't. This is where Docker comes into play. Look at the below image (if the image is not clear, please right-click on the image and open the image in a new tab)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662143024547/N8gBlojEv.png" alt="pic2.drawio (1).png" /></p>
<p>Here, Docker creates isolated segments in your Hard Disk and can redirect to the proper disk segment as required by different processes. In this way, Docker helps avoid dependency and configuration issues that could've been otherwise conflicting. In this sense, we say that a containerized application can work on other computers too without any issue.</p>
<p>But the burning question is, how does Docker achieve this isolation?</p>
<h1 id="heading-namespace-and-control-groups">Namespace and Control Groups</h1>
<p>To achieve this, Docker uses some low-level kernel features, those are <em>Namespace</em> and <em>Control Groups (cgroups)</em></p>
<p><strong>Namespacing</strong>: Isolating resources per process or a group of processes. For example, isolating the separate versions of Node.js in the hard disk from our above example.</p>
<p><strong> Control Groups</strong>: Limiting the number of resources used per process. This can be used to dictate how much resource (processing power, memory etc) a containerized process can use</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662144045671/s8m5VT02l.png" alt="pic3.drawio.png" /></p>
<p>The Docker Engine or more specifically Docker Daemon (a process named <code>dockerd</code>) is in charge of managing all these things.</p>
<p>But....<br />There's a catch...</p>
<p><em>Namespace</em> and <em>Control Groups</em> are <strong>ONLY supported by Linux kernel</strong>.  </p>
<p>Then, you might ask,  </p>
<p><strong>How Docker runs in Windows/macOS?</strong><br />In these cases, <em>Docker Desktop</em> creates a Linux virtual machine in your said operating system and runs Docker on top of that.</p>
<p>Please note, that the said features in the Linux kernel are not new and have existed for quite a long time. In fact, the concept of containerization is not new either.</p>
<p>Now, from our previous diagram, let's mark out the containers:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662145480449/I8tCwlu2n.png" alt="pic4.drawio.png" /></p>
<p>In the above image, there are two containers, both marked in <em>orange outline</em>. Shows only the hard disk as the resource.</p>
<p>And here is a zoomed view of a single container with each resource shown:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662145965792/SzNSDZ2fk.png" alt="pic5.drawio.png" /></p>
<p><em>One extremely important point to note, the kernel here is <strong>independent</strong> and expands beyond the container boundary. A single kernel is responsible for controlling multiple containers. We will get back to this later.</em></p>
<h1 id="heading-from-images-to-containers">From images to containers</h1>
<p>Let's discuss in-depth on images, and how images are actually used behind the scenes to create containers.</p>
<p>Images keep a <em>copy</em> (or in more formal terms <strong>snapshot</strong>) of the file system that is required by a specific program, along with configuration and startup command.</p>
<p>When you try to build a container, the following happens:</p>
<ol>
<li>Look for the container image in your local system</li>
<li>If it's not found locally, reach out to Docker Hub to download the image</li>
<li>Create a placeholder container</li>
<li>Replace the placeholder container hard disk portion with the file system snapshot of the image</li>
<li>Run the startup command (and other necessary configs, if any) found in the image and start the container</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662147344366/BJmVvgIr-.png" alt="pic6.drawio (1).png" /></p>
<h1 id="heading-hypervisor-vs-docker">Hypervisor vs Docker</h1>
<p>Remember, a few blocks back I said that the kernel is independent and a single kernel is responsible to handle all container communications with the hard disk? Well, that single independent kernel is the host kernel. So if you're running Linux operating system, the main Linux kernel itself will handle all the containers.</p>
<p>On the other hand, a Hypervisor is an old virtualization technology (sometimes dependent on hardware support), where a whole copy of the operating system is made to run a single application. Unlike Docker, this introduces a lot of overhead, including increased boot-time. You might have used <em>VMWare</em> or <em>VirtualBox</em> with your operating system, those use Hypervisors to achieve virtualization.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662147913685/7_QH-Z5dM.png" alt="pic7.drawio.png" /></p>
<p>In the case of Docker, the host kernel manages everything so a complete copy of the OS is not needed. As you can already guess, the winner is Docker here. Nobody uses Hypervisor anymore unless there are specific reasons.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Docker is a very powerful tool that has revolutionized how we deploy applications on the web. As a Software Engineer/Developer, it is an absolute must that you have the basic working knowledge of Docker. I hope you have enjoyed this article, if you have any questions, please use the comment section. Also, don't forget to follow and subscribe to my blog. Have a great day!</p>
]]></content:encoded></item><item><title><![CDATA[Introduction to Microservices architecture with Tinder]]></title><description><![CDATA[Howdy folks? It's been a long time since I wrote an article. Today, I'm restarting with this which will aid beginners to learn what Microservice architecture is, how it works and its pros and cons. After that,  we will design a mock Tinder applicatio...]]></description><link>https://blog.muhib.me/introduction-to-microservices</link><guid isPermaLink="true">https://blog.muhib.me/introduction-to-microservices</guid><category><![CDATA[Microservices]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[software architecture]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Fri, 07 Jan 2022 12:47:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1641551760736/pj19gZOBT.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Howdy folks? It's been a long time since I wrote an article. Today, I'm restarting with this which will aid beginners to learn what Microservice architecture is, how it works and its pros and cons. After that,  we will design a mock Tinder application using microservices.</p>
<p>Microservices is an architectural design pattern that is followed by many tech giants to create highly scalable and reliable systems. Netflix is the first company that popularized the use of microservices architecture. Before learning about Microservices, we need to understand what was there before Microservice came in.</p>
<h1 id="heading-big-old-monoliths">Big Old Monoliths</h1>
<p>To create a basic web application, we need <em>a) server</em> and <em>b) database</em> . These pieces together make a single <em>service</em>. If your application grows in size and gains popularity, it will be not so basic after a few months. Soon you will be going through thousands (if not millions) of lines of code and countless files and folders all working together to provide the functionality to the customers. It might be hosted in version control like Github and all of your teammates will be working on that single repository. This is a monolith architecture. All kinds of functionality for your application like user auth, user profile and core functionalities reside in a single place.</p>
<h2 id="heading-pros">Pros</h2>
<ol>
<li>Easy to detect issues throughout the system</li>
<li>Infrastructure maintenance is relatively simple and less expensive</li>
<li>Easy to onboard new team members as the codebase is in a single place</li>
<li>Doesn't require a sophisticated engineering team to handle the system</li>
</ol>
<h2 id="heading-cons">Cons</h2>
<ol>
<li>Difficult to scale properly as each and every functionality is tightly coupled</li>
<li>Adding new features and code maintenance can get overwhelming very easily</li>
<li>No fault isolation. If one part of your application goes down, the whole application goes down.</li>
<li>Difficult to distribute development across teams</li>
<li>Usually limited to a single type of tech stack. So if you're working with the MERN stack, you will have to deliver the whole functionality in that single stack.</li>
<li>Build and deploy process can be very slow.</li>
</ol>
<h1 id="heading-lets-split-them-up-onto-microservices">Let's split them up, onto Microservices</h1>
<p>When we want to adopt Microservices, we need to do separation of concerns. Instead of creating a giant single service (monoliths), we separate them based on their functionality and create small services (microservices). There are some certain criterias like data duplication, scope, independence etc while doing this which will make it an actual microservice, but we can skip those part for this article. All of those services might have their own databases and own servers. For example, if you're creating a social media application like Facebook, then it might have the following services:</p>
<ol>
<li>Authentication Service: Responsible for user authentication and authorization</li>
<li>File storage service: Responsible for serving and storing media files</li>
<li>Friends service: Store friend relations</li>
<li>Feed Service: Generate your personal feeds based on relevancy</li>
</ol>
<p>...and many more. Please note, if you used a monolith architecture, all of these services would be treated as a single one.</p>
<h2 id="heading-pros">Pros</h2>
<ol>
<li>Each unit is decoupled so upgrading and maintaining a single part is much easier.</li>
<li>Scaling is more flexible and easier. Each microservice can be scaled independently. You can quickly point out which service is load-intensive and scale just that.</li>
<li>Improved fault isolation. So if your 'file storage' service goes down your 'authentication' and 'friends' service would still work. This is possible because each service has its own set of machines (servers, databases etc).</li>
<li>Easy to distribute development to different teams. One team can be responsible for one microservice</li>
<li>You can use different tech stacks for different microservices. So the service where machine-learning is involved, you can use Python. For the service which is IO heavy, you can use something like Node.js and so on. You get the idea.</li>
<li>It can help to board new members easily assuming one team looks after a single service.</li>
<li>Build and deploy will be extremely quick as you're working on a small service.</li>
</ol>
<h2 id="heading-cons">Cons</h2>
<ol>
<li>The system architecture or infrastructure gets extremely complex</li>
<li>Needs a very capable and much bigger engineering team</li>
<li>Expensive</li>
<li>Detecting issues or debugging gets relatively difficult as different services are communicating over the network. More tools are needed for logging and monitoring</li>
<li>Inability to properly draw boundaries among different microservices would cause more trouble than solving them.</li>
</ol>
<blockquote>
<p>WARNING: The concepts here are very simplified for new learners, so this article should not be treated as a full-fledged guide to microservices. In reality, separating concerns is not as easy as it seems. They are called 'micro' for a reason (not 'mini'). Don't confuse 'microservices' with 'service-oriented architecture'. Yes, they are different!</p>
</blockquote>
<p><strong>Monoliths or Microservices, which one is better?</strong><br />Depends. Unless you're working on an application that is complex in nature and you need to scale to millions of active users, you can safely avoid microservices. Even then, a monolith might be a better option depending on your team and capability. Also, it is not possible to get a full practical hands-on experience on Microservices unless you're working in a professional setting.</p>
<h1 id="heading-designing-tinder-using-microservice-architecture">Designing Tinder using Microservice architecture</h1>
<p>Now comes the fun part, we will design a mock version of the popular dating application Tinder. Please note, this is not an actual design of Tinder and is for educational purposes only.</p>
<p>Before jumping to the microservice-based architecture, let's see how it would look if it's built using the monolith architecture:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641543670594/SYxTy8FkW.png" alt="tinder-monolith.png" /></p>
<p>Let's jump into the microservices design part. For Tinder, I've decided to create the following microservices:</p>
<ol>
<li><p>Gateway service: This is the service where the users will connect from the public internet. It would be responsible to process some initial data and directing the request to the relevant services as required. Typically, every kind of microservice-based application should have a gateway service like this.</p>
</li>
<li><p>Auth Service: Used to authenticate/authorize user requests</p>
</li>
<li><p>Storage Service: Will be used to storing and serve all kinds of media files from the user, such as images, videos etc</p>
</li>
<li><p>Messaging Service: A socket-based messaging server that will be used for one-on-one chatting/messaging purposes among the matched users</p>
</li>
<li><p>Profile Service: Here we will be storing users and their matchings related information</p>
</li>
</ol>
<p>This is enough for our learning. In reality, considering that Tinder uses microservices, it is definitely not only 5 services. It might be 50 or 100 or 150, we may never know. Just as an example, Netflix uses 300+ microservices to keep the platform running smoothly.</p>
<p>Using this architecture, let's see how this boils down into a simple diagram</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641545701296/CbD0YtLnA.png" alt="tinder-microservice-1.png" /></p>
<p>Each circle represents a running container, usually, it's a docker container. A container might run on the same or a different machine. Some containers together form a cluster. The cluster decides how to balance the loads and communicate among different containers. Things like this are handled with a container orchestration tool, such as Kubernetes.</p>
<p>Let's talk about scaling a little bit. Let's say, after some logging and monitoring the engineers at Tinder see that the most demanding service is the messaging service (obviously!), so they can just scale the messaging service like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641549534678/PSf29aXQT.png" alt="tinder-microservice-scaled.png" /></p>
<p>We just horizontally scaled the messaging containers. Please note, some earlier portions of the image is cut off to fit smaller screens. The rest of the architecture is the same as the previous images.</p>
<h2 id="heading-handling-the-communication-chaos">Handling the communication chaos</h2>
<p>Now, it is very likely that when some event occurs, multiple services have to know about it. <em>User registration</em> is such a scenario. When the user registration happens, we need to do the following:</p>
<ol>
<li>Store the user-related information in the Auth service and send processed data in Profile and Messaging service</li>
<li>Store and process the user media (like profile pictures, gallery images) in the Storage service</li>
<li>Store the user details process data in the Profile service</li>
<li>Store and process session related information in the messaging service.</li>
</ol>
<p>We can make the communication direct among different services. But, this is not the perfect solution. It will easily get tangled and complex as the communication is happening in many places. The left side of the figure below depicts this situation. Imagine what would happen when you have to communicate across 100 services. Also, from an engineering perspective, we're tightly coupling the services as soon as we put inter-communication logic inside them. The goal should be the exact opposite, which is <em>decoupling</em>. By decoupling, we can ensure maximum scalability.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641550426918/dQjRpj6UI.png" alt="com-chaos.png" /></p>
<p>To solve this issue, microservices use a common bus channel for communication, this is a simple message queue where there are publishers (or producers) and subscribers (or consumers). Any service can subscribe and listen to a message queue. One service can be both consumer and producer at the same time. The right side of the figure depicts this.</p>
<p>This is much more simple. No service is directly communicating with each other. There is a common channel where everyone is publishing the events with necessary data. As a result, one service doesn't have to know about another service, which ensures decoupling. Those services subscribed will be informed of all the data in the channel. </p>
<h2 id="heading-technologies-used-for-microservices">Technologies used for microservices</h2>
<p>For deployment, we would need a combination of Docker, Kubernetes, Helm, Ansible, Jenkins and a few other tools. If you go to the microservice route, you obviously need a very capable DevOps team.</p>
<p>For inter-service communication, as I already described earlier - RabbitMQ, Amazon SQS, Kinesis etc are used.</p>
<p>Logging is an important part. To implement proper logging and monitoring we need a combination of Elasticsearch, Logstash, Kibana, Newrelic, Sentry etc.</p>
<p>That's all I know. There are definitely more tools that I'm simply not aware of.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As a beginner step, this article should be enough. If you want to explore more in-depth knowledge on microservices, you can watch this amazing  <a target="_blank" href="https://www.youtube.com/watch?v=CZ3wIuvmHeM">guide on Microservices from the one and only Netflix.</a>. That's all for today. Please leave your feedback or questions in the comments below. Have a good day.</p>
]]></content:encoded></item><item><title><![CDATA[Introducing ScreenView: The missing social platform for movie/tv show lovers]]></title><description><![CDATA[Do you love to watch movies? Do you love to watch tv and web series? Then, ScreenView is for you. When the Auth0 hackathon was announced, I along with my friend decided to build a platform for what we love most which led to ScreenView. Before getting...]]></description><link>https://blog.muhib.me/introducing-screenview-social-platform</link><guid isPermaLink="true">https://blog.muhib.me/introducing-screenview-social-platform</guid><category><![CDATA[Auth0]]></category><category><![CDATA[Auth0Hackathon]]></category><category><![CDATA[projects]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Fri, 27 Aug 2021 14:54:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630075296566/xHPInFO6J.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Do you love to watch movies? Do you love to watch tv and web series? Then, ScreenView is for you. When the Auth0 hackathon was announced, I along with my friend decided to build a platform for what we love most which led to ScreenView. Before getting started with ScreenView, let's talk about Auth0 first.</p>
<h2 id="what-is-auth0">What is Auth0?</h2>
<p><a target="_blank" href="https://auth0.com">Auth0</a> is an authentication-as-a-service platform. It makes user authentication extremely simple. You don't have to worry about security or managing user/roles because Auth0 can handle all that for you. This project uses Auth0 as the authentication service provider.</p>
<h2 id="what-is-screenview">What is ScreenView?</h2>
<p>ScreenView is a social platform for movie/tv series lovers where the users can share their activities and stay updated with their friends. In short, we can say it's like Facebook/Twitter but targeted for movie/tv series lovers.</p>
<h2 id="the-problem">The problem</h2>
<p>Traditional social platforms like Facebook/Twitter are not enough to share your media activities. Yes, you can share what you're watching with your friends, but those posts will get lost under a pile of other generalized posts. Features like movie reviews, recommendations and discovery are not available on such platforms although these are essential. It's tough to find people with similar watching interests because those platforms aren't simply built for a specific audience.</p>
<h2 id="the-solution">The solution</h2>
<p>ScreenView. It lets all your dream come true. Everything you need for such a social platform is already there. This is built by movie lovers, for movie lovers. You can do the following:</p>
<ul>
<li>Discover upcoming, new and trending movies to watch</li>
<li>Follow people with similar interests</li>
<li>Stay up to date with what your friends are watching</li>
<li>Share your opinion in the comments</li>
<li>Create and keep track of your own Watchlist</li>
<li>Share your Watchlist with your friends</li>
<li>Write and share movie reviews with your friends</li>
<li>And a lot more interesting features planned for the future</li>
</ul>
<h2 id="the-building-blocks-of-screenview">The building blocks of ScreenView</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Type</td><td>Name</td></tr>
</thead>
<tbody>
<tr>
<td>Language</td><td>Javascript/Node.js</td></tr>
<tr>
<td>Framework (Backend API)</td><td>Express</td></tr>
<tr>
<td>Framework (Frontend)</td><td>React</td></tr>
<tr>
<td>Database</td><td>MongoDB</td></tr>
<tr>
<td>ODM</td><td>Mongoose</td></tr>
<tr>
<td>CSS Framework</td><td>Tailwind CSS</td></tr>
<tr>
<td>Auth Provider</td><td>Auth0</td></tr>
<tr>
<td>Movie API Provider</td><td>TMDB</td></tr>
</tbody>
</table>
</div><h3 id="challenges-we-faced">Challenges we faced</h3>
<p>This project was definitely technically challenging. There were many challenges that we faced. The most noteworthy one was <strong>determining the business logic to show user feeds</strong>. I had to find a way to effectively fetch and show user feeds in record time. After much hard work, I completed the job with success and full satisfaction. For those who are interested, you can look into the MongoDB query in the code repo (given at the end of the article).</p>
<h2 id="quick-sneak-peak">Quick sneak-peak</h2>
<p>There are many features but to keep the article short I'm going to show you the main ones quickly.</p>
<p>In the below GIF, you can see the user posting a review of a movie. Remember, you can also post watch status, where you share what you're watching with your friends.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1629991414350/hPnVzsZgC.gif" alt="sv-review-post.gif" /></p>
<p>In the next GIF, you see typical user activities like browsing through feeds, commenting, looking into the movie discovery section and user connections
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1629991823763/pUxl1qbaF.gif" alt="sv-feed-connection.gif" /></p>
<p>And in the final GIF, you'll see how easy it is to add items to your watchlist from anywhere. Interested in a movie that your friend is watching, just add it to the Watchlist right from the feed. Or interested in a new movie you discovered, just add it.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1629992251352/4dRkckXk6.gif" alt="sv-watchlist.gif" /></p>
<h2 id="try-it-out">Try it out!</h2>
<p>We're live: https://screenview.netlify.app</p>
<p>Code repository: https://github.com/ahmedsadman/screenview</p>
<p>Please note, what you see in your feed depends on the people you follow. This is a new site so it might take some time to gain traction. Until then, you can invite your friends to this site to grow your feed.</p>
<p>Hope you liked this work. Please don't forget to share it with your friends and family who loves screen entertainment. Thank you!</p>
]]></content:encoded></item><item><title><![CDATA[How to build a strong profile for the tech job (engineering) market]]></title><description><![CDATA[Graduated students often wonder what is stopping them from being called in an interview. Let's say you're a very good programmer. But the recruiters don't know that. To prove your skills and your worth, you have to get called for the interview first....]]></description><link>https://blog.muhib.me/how-to-build-a-strong-profile-for-the-tech-job</link><guid isPermaLink="true">https://blog.muhib.me/how-to-build-a-strong-profile-for-the-tech-job</guid><category><![CDATA[jobs]]></category><category><![CDATA[job search]]></category><category><![CDATA[recruitment]]></category><category><![CDATA[Learning Journey]]></category><category><![CDATA[Career]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Fri, 30 Jul 2021 13:18:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1627587805644/oi5gUoQIB.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Graduated students often wonder what is stopping them from being called in an interview. Let's say you're a very good programmer. But the recruiters don't know that. To prove your skills and your worth, you have to get called for the interview first. This is where a strong profile comes into play. By profile, I mean your LinkedIn, GitHub and your overall brand as a programmer. In this article, we will discuss different tips on how to improve your profile, these are the same ways I followed myself.</p>
<p>The process can be divided into mainly two categories - building your brand and networking.</p>
<h1 id="heading-building-your-brand">Building your brand</h1>
<h2 id="heading-a-strong-github-profile-will-speak-for-itself">A strong GitHub profile will speak for itself</h2>
<h3 id="heading-do-projects">Do projects</h3>
<p>Try to build some unique projects, it doesn't have to be for academic purposes only. In fact, doing projects on your own is the best approach to learn and grow. All those projects should be recorded in GitHub, using proper commits and workflow. What I mean is, don't do the whole project at once and publish it under a single commit. Your commits should reflect the development path.</p>
<p>Avoid hotel management or library management type of stuff. Those are very common, easy to implement and complete code is available on the internet. It is tough to build unique projects, in that case, do some common projects but make it more challenging. Want to make a to-do app? Fine. Instead of making a simple to-do app, make it collaborative. With just a simple collaboration feature you just introduced a challenging aspect of your project. You should try to incorporate challenging stuff in your projects so that recruiters know that you can create innovative solutions. The projects should have a visual component that anyone can use. For example, think of the recruiter as your customer. He should be able to use your project and benefit from it without knowing the technical details. So, if you're making a web application, keep a live version running online for demo purposes.</p>
<h4 id="heading-try-to-avoid-frontend-only-projects">Try to avoid frontend-only projects</h4>
<p>If you work in full-stack, your job field will broaden drastically. And when trying to land your first job, you should be more open about roles. So, try to incorporate the backend. If you think of yourself as a mobile application developer, you could try to create the same API on your own that you initially did with Firebase.</p>
<h3 id="heading-preach-your-projects">Preach your projects</h3>
<p>Don't just do projects and relax. Spread it. Use Facebook, LinkedIn and Reddit. Try to gather <strong>Stars</strong> for your GitHub projects. Some Reddit pages where you can showcase your projects are <a target="_blank" href="https://www.reddit.com/r/webdev/">r/webdev</a> , <a target="_blank" href="https://www.reddit.com/r/Python/">r/python</a> and <a target="_blank" href="https://www.reddit.com/r/programming/">r/programming</a>. <strong>In your post, explain what the project does, what kind of problem it solves and most importantly, what kind of challenges you faced and how did you solve it.</strong> It's even better if you can attach a demo video of your project.</p>
<h3 id="heading-get-involved-in-open-source-contributions-optional">Get involved in open-source contributions (optional)</h3>
<p>This will drastically boost your profile. You can read this comprehensive guide on <a target="_blank" href="https://opensource.guide/how-to-contribute/">how to start contributing to open-source projects</a>. With such contributions, you will learn how to understand a large codebase and work in a team-like environment. Of course, noteworthy contributions should be mentioned in your resume.</p>
<p>Please note, getting started with open-source contributions is difficult. If you don't like it, then don't stress over it.</p>
<h3 id="heading-build-the-homepage">Build the homepage</h3>
<p>GitHub now offers an amazing way to introduce yourself. You just have to create a repository with your GitHub username, like <a target="_blank" href="https://github.com/ahmedsadman/ahmedsadman">this</a>. This is the best place to showcase your work. You can find some inspirations in <a target="_blank" href="https://github.com/abhisheknaiidu/awesome-github-profile-readme">Awesome GitHub Profile Pages</a> repo. Add your intro here. Pour your full creativity into this.</p>
<p>Most importantly, don't forget to <strong>pin</strong> your top projects on the GitHub front page.</p>
<h2 id="heading-share-your-knowledge-with-the-world">Share your knowledge with the world</h2>
<p>If you don't have a tech blog, start one. Write about the stuff you learn day to day. Blogging will help you reinforce your learning. You can write articles for beginners like you, or advanced articles if you feel confident enough. <strong>When other people see your blog, they will understand how you think and how you solve problems</strong>. But be careful not to publish wrong information. To start your blog, you can use <a target="_blank" href="https://hashnode.com">Hashnode</a> or <a target="_blank" href="https://medium.com">Medium</a> whichever you prefer.</p>
<p>Alternatively, you can start your own YouTube channel if you feel like it. Even better, you can do both. I know about one of my co-workers who got called by Amazon just because she had an awesome YouTube channel teaching computer science.</p>
<p>Whatever you do, preach it. Use the platforms described earlier. People should know about your blog.</p>
<h2 id="heading-internships-and-part-time-jobs">Internships and part-time jobs</h2>
<p>As soon as you can, get involved with internships and part-time jobs during your academic life. This will boost your profile without any doubt. The best way to get into internships or part-time jobs is via networking. Keep a good connection with your university seniors and related online groups and platforms.</p>
<h2 id="heading-a-simple-and-minimalistic-resume">A simple and minimalistic resume</h2>
<p>Create a simple resume, don't add any icons or fancy designs. To create a resume, I would recommend either <a target="_blank" href="https://novoresume.com/">Novoresume</a> or a Latex-based resume. You can find Latex resume templates in <a target="_blank" href="https://www.overleaf.com/latex/templates/tagged/cv">Overleaf</a>. <strong>The resume should be a single page, either double column (equal weight) or a single column.</strong> Your photo is not necessary. Your resume should contain the following sections in order (assuming you're a fresh candidate in the job market)</p>
<ol>
<li><p>A small introduction about yourself, as concise as possible. Describe what kind of role you're interested in and how you can add value to a company</p>
</li>
<li><p>Education</p>
</li>
<li><p>Skills (Technical, specifying soft skills is not important)</p>
</li>
<li><p>Experience (include any part-time, full-time, remote or freelance jobs experience). Nobody cares if you were the president of your university's Computer Society or Debating Society. These are not experiences)</p>
</li>
<li><p>Projects (A small description of each project along with what tools/tech stack were used to make that project). Also, add the GitHub link to your project. Don't add the demo link here. Your GitHub's readme page should contain the demo link</p>
</li>
<li><p>Achievements (Any contests or hackathons you participated in and made an impact)</p>
</li>
</ol>
<p>Also, at the top of your resume, don't forget to give your LinkedIn and GitHub profile links. Be careful of your grammar and spelling.</p>
<p>When writing about your experience, follow the <strong>action-outcome rule</strong>. So instead of writing this:</p>
<blockquote>
<p>Implemented feature X in the application</p>
</blockquote>
<p>Write this:</p>
<blockquote>
<p>Implemented feature X in the application which helped the company retain 2X more customers</p>
</blockquote>
<h1 id="heading-grow-your-network">Grow your network</h1>
<h2 id="heading-participate-in-hackathons">Participate in hackathons</h2>
<p>Whenever you get an opportunity to get into a hackathon, do it. Regardless of whether you're prepared for it or not. Use it as an opportunity to connect with other developers and important tech people. This will help you grow your network and your recognition.</p>
<p>Hackathons will also teach you how to work in teams and come up with innovative solutions within a strict time constraint. It will test your patience and discipline. You can select some of your friends with whom you will consistently participate in these hackathons. Don't forget to mention any noteworthy events in the <em>Achievement</em> section of your resume</p>
<h2 id="heading-linkedin-says-it-all">LinkedIn says it all</h2>
<p>Your recruiter will first look into LinkedIn. Keep your information updated. At a minimum, your profile should contain a photo, a cover photo, a small introduction, experience, honors and awards and languages.</p>
<p>For each company experience, try to describe what you did using the action-outcome rule described earlier. I see many people make the mistake of putting social and club activities in their LinkedIn experience section. That is a mistake and it puts a question mark in your professionalism. LinkedIn has a separate section called 'Volunteering Experience' where you can put those things. Remember, it's okay for a fresh graduate to not have any solid experience.</p>
<p>As you know, you can set a title with your LinkedIn profile. Instead of writing <code>Software Engineer</code>, you should write <code>Aspiring Software Engineer</code>. Similarly, use <code>Aspiring Data Scientist</code> instead of <code>Data Scientist</code>. In this way, when you sit for the interview the interviewers will go easy on you because you didn't actually claim to be an engineer who has zero experience. It further clarifies that you're not boasting or over-confident.</p>
<h3 id="heading-build-valuable-connections">Build valuable connections</h3>
<p>Please don't treat LinkedIn as Facebook. It is not the place to add your Facebook friends (although you can and that's totally fine). You should focus on building connections with people who have the same job interest and who are already working in those job sectors that interest you. Don't miss the chance to connect with HRs and recruiters of bigger companies.</p>
<p>If you have some target companies (which you should) that you would like to work for, get connected with the people who work there.</p>
<h3 id="heading-dont-hesitate-to-reach-out-to-strangers">Don't hesitate to reach out to strangers</h3>
<p>The primary goal of LinkedIn is to connect you with other professionals, so don't hesitate to initiate first conversations.</p>
<p>In fact, when you are going into the job market. Do the following:</p>
<ul>
<li><p>Connect with the people from the target companies</p>
</li>
<li><p>Endorse them for a few skills</p>
</li>
<li><p>Ask them in the message for referrals by introducing who you're and showcasing your skills.</p>
</li>
</ul>
<p>At first, it might seem a bit lame to endorse people you don't know. But you have to understand how endorsements work. That person is already working in a good company and other people have already endorsed him for his skills. You can select the option "Heard from other people about his skills" when endorsing.</p>
<p>You will see that more than 50% of people will either reject or ignore your referral request. But that shouldn't stop you from continuing.</p>
<p>You can follow this message format to connect with people by leaving a note:</p>
<blockquote>
<p>Hello, I am X. I am really impressed with your profile. I'm interested in a similar job sector/your company so I would like to connect with you.</p>
</blockquote>
<p>You can follow this message format to ask for a referral:</p>
<blockquote>
<p>Hello, I am X. I have been following your company for a long time and I'm also impressed with your profile. I see there are some job openings right now. Here is my GitHub profile (put your GitHub) and here are some of my noteworthy projects I would like you to check out (put some of your project demo links along with GitHub code). I would be very grateful if you can refer me for the X job position. Thanks in advance. Looking forward to hearing from you.</p>
</blockquote>
<h3 id="heading-ask-for-recommendations">Ask for recommendations</h3>
<p>LinkedIn has a section for recommendations. Having some recommendations will attract more recruiters to your LinkedIn profile. Try to get recommendations from industry professionals. These people can be your manager during your time of internship/part-time, CEO/CTO or even coworkers. If possible, try to get recommendations from a high-ranking professional. It's better to have only one recommendation from a highly qualified professional rather than five normal recommendations. You should target to have at least three recommendations in total. Although not much important, you should also ask people for skill endorsements.</p>
<h3 id="heading-coursera-certifications">Coursera Certifications</h3>
<p>This is a debatable topic. Although gathering Coursera certifications have become a trend, it can add little to no value to landing a job. So, I would suggest enriching your skillset and doing projects, because that's what will help you in the long run. After that, if you get enough time, feel free to get certifications and show off in your profile.</p>
<hr />
<p>The above-discussed things are general guidelines and it doesn't mean you have to follow all of them. For example, you can do fine without starting your own blog. The same goes for open-source contributions. Everybody doesn't have to follow the same path to become successful. Some people might get a job just via networking. Some might need to do both networking and branding. <strong>It varies from person to person where luck is an important factor</strong>. But ideally, you should try to tackle as much as possible.</p>
<h1 id="heading-preparing-for-interviews">Preparing for interviews</h1>
<p>Now that you know how to make your profile attractive, time to prepare for interviews. Different companies have different interview procedures:</p>
<ol>
<li><p>Some companies will assess only your data structure and algorithms knowledge</p>
</li>
<li><p>Some companies will assess your technical competency, critical thinking and teamwork capabilities through long discussions about your projects and past experiences. Also giving you tough projects under an extremely strict time constraint.</p>
</li>
<li><p>Some companies will do a combination of 1 and 2</p>
</li>
</ol>
<p>If you know about your target company's interview procedure, you can prepare accordingly. But it's always a good idea to prepare for a global scenario. You already did project works. Be prepared to answer questions about the projects you put in your resume.</p>
<p>Now it's time to sharpen your basic computer science knowledge.</p>
<p>To sharpen your knowledge on data structure and algorithms, allot 6-8 months before attempting the first interview of your life. You will do only DSA (data structures and algorithm) problems in this timeline. You should use <a target="_blank" href="https://leetcode.com/">Leetcode</a> for interview preparation. Try to do around 100 easy and 100 medium questions. Then continue solving more of your choice. Although how many questions and what type of question you want to solve is purely subjective. Don't stress over it if you're not good at it. Most companies will ask easy questions, even some companies will ignore it altogether. With the preparation of 6-8 months, you can also attempt FAANG company interviews. <strong>There's a myth in South Asian countries that you have to be a competitive programmer to get into FAANG companies, which is not true. Getting into a FAANG company from a foreign third-world country is always tough, because in that case, the company's expectation bar is very high, no matter what you do.</strong> For example, if you're applying to Google from Bangladesh, their expectation bar will be very high just to get called for an interview. On the other hand, if you're a US citizen, the expectation bar will be standard and you will get called fairly easily. Maybe you're worthy of FAANG company, but to prove that you have to get called into the interview first. Here, a strong profile comes into play again, how you got the strong profile (either competitive programming or projects/open-source contributions or job experience) doesn't matter.</p>
<p>That's it for today folks. Don't forget to leave your feedback and questions in the comments below. If you want more articles like this, subscribe to/follow my blog. Thank you. Have a nice day!</p>
]]></content:encoded></item><item><title><![CDATA[Understanding password hashing and salting for enhanced security]]></title><description><![CDATA[Passwords are the first and most important layer of security of any application. As a developer, it's your responsibility to ensure the highest possible security to your users. In this article, we will discuss password hashing which ensures the best ...]]></description><link>https://blog.muhib.me/understanding-password-hashing-and-salting-for-enhanced-security-1</link><guid isPermaLink="true">https://blog.muhib.me/understanding-password-hashing-and-salting-for-enhanced-security-1</guid><category><![CDATA[Databases]]></category><category><![CDATA[Cryptography]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Security]]></category><category><![CDATA[Hashing]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Fri, 23 Jul 2021 14:11:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1627049405226/kanFCOWv0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Passwords are the first and most important layer of security of any application. As a developer, it's your responsibility to ensure the highest possible security to your users. In this article, we will discuss password hashing which ensures the best possible security against a data breach</p>
<h2 id="what-is-password-hashing">What is password hashing?</h2>
<p>Saving passwords as plain text is the worst. If an attacker compromises your database, he can see all the passwords of your users. This actually goes against privacy laws. Firstly, as the developer, you should never know the user's password. Secondly, a user might use common passwords across different accounts and such data leaks might be devastating for an individual. So, how do you protect passwords?</p>
<p>You use password hashing. Hashing is a cryptographic way to secure users passwords. In this way, no one can find out the actual password even if he directly looks into the database. Even the application owners or developers wouldn't be able to tell the user's password.</p>
<p>In this procedure, the password is passed into a specific hash function, which then outputs a jumbled string. Let's say, my  password is <code>helloworld</code>, then:</p>
<pre><code><span class="hljs-comment">// SHA256</span>
hash(<span class="hljs-string">'helloworld'</span>) = <span class="hljs-string">'936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af'</span>
</code></pre><p>Here, the algorithm used for hashing is called <code>SHA256</code>. Given the same string, it is guaranteed that a hash function will always generate the same output. But hashing is a one-way algorithm. It means once a string is hashed, you can never get back to the original string using the hashed output.</p>
<blockquote>
<p><strong>What is the difference between encryption and hashing?</strong></p>
<p>Encryption requires a secret key to encrypt with. Whoever has the secret key, can encrypt or decrypt as required. So, if you encrypt a string and you know the key, you can get back to the original version using that key. But hashing is one way. Meaning, there is no way to go back to the original string.</p>
</blockquote>
<p>Whenever a new user registers with a service, his password is hashed and stored in their database. The database user table might look like this:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>id</td><td>name</td><td>password</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td>alice</td><td>ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222</td></tr>
<tr>
<td>2</td><td>bob</td><td>3caf14423f92dbac6f80589aa72f7be572d7b87562f9fd32ed0c4427b680b598</td></tr>
<tr>
<td>3</td><td>john</td><td>cc6db669c9856670ab5faf03a76b4885d146e62a1fd18ab7693a525368e7d654</td></tr>
</tbody>
</table>
</div><p><strong>Now that you have stored the hashed password, how do you compare the passwords during authentication?</strong></p>
<p>As I said earlier, hashing is a one-way algorithm. So, there is no way to get back to the original password. The authentication is done as below:</p>
<ul>
<li>User provides his plain password during login</li>
<li>The plain password is hashed and the new hash is compared with the existing hash in the database</li>
<li>If the hash matches, the user is authenticated</li>
</ul>
<h2 id="security-considerations-for-password-hashing">Security considerations for password hashing</h2>
<p>Unfortunately, such simple hashing is not enough. An attacker might use brute force attacks using a rainbow table or hash table. These two tables are different but for simplicity, we're not going to discuss the difference. A rainbow table or hash table is basically an original password - hashed password mapping using the most common password phrases. Hash tables are huge containing millions (if not billions) of common passwords and can size up to 100GB. Rainbow tables take less space but lookup is slow. For the rest of the article, we will use the terms interchangeably. A hash table might look like this:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>input</td><td>hash</td></tr>
</thead>
<tbody>
<tr>
<td>hello</td><td>2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824</td></tr>
<tr>
<td>unlockme</td><td>06f088e12170d07e80fced4405bb4d7c3ec0153d1e3c136be0f58502ef97b364</td></tr>
<tr>
<td>password1234</td><td>a28d722529366b0e1ff5d75c7ce5676b1a574a982d6b0a2b32050c565139dc8b</td></tr>
</tbody>
</table>
</div><p>We know, for a given string and the same hashing algorithm, it will always produce the same output. The hashing algorithms used for passwords are built to be <strong>slow</strong> for the attacker's inconvenience. But in a rainbow table, a hash is pre-computed (the attacker prepared the table earlier). The attacker just has to compare the hashes from the database and do a reverse lookup to find the password. Because of modern CPU/GPU power and distributed computing, an attacker can crack your password in record time in this way! That is why it is very important to use a strong password. Regardless, you have to solve this problem because you can't expect every user to use a very strong password.</p>
<blockquote>
<p>When a database is compromised, the attacker immediately dumps the database, which basically means saving a copy in your local disk. The attacks then run on the saved database to find out original passwords.</p>
</blockquote>
<p>Oh, there is another problem. Let's say Bob and Alice use the same password <code>unlockme</code>. In that case, the hash would be the same for both user's passwords. The attacker will instantly know that the two people are using the same password, which can help the attacker to find patterns in the hashing and further accelerate the attack. For example, attackers will easily figure out there is no salting (described below) or your website uses default passwords for new accounts or you're using a weak hashing algorithm. You definitely don't want these to happen.</p>
<p>To overcome these above-mentioned issues, we <em>salt</em> the hashes.</p>
<h3 id="salting-your-hashes">Salting your hashes</h3>
<p>Salting is basically adding random strings to the passwords so that two passwords never match. Salts can be appended or prepended to the original password. For our previous example, Alice and Bob had the same password <code>unlockme</code>. If we salt this it would look something like this:</p>
<p>Alice's password (salted with append): unlockme<strong>ea22$sas</strong></p>
<p>Bob's password (salted with append): unlockme<strong>3xx#$/a5</strong></p>
<p>The character set in bold is the salt. In a real-world scenario, salt is generated using a <strong>cryptographically secure</strong> algorithm. The said term refers to such systems which are resistant to  <a target="_blank" href="https://en.wikipedia.org/wiki/Cryptanalysis"><strong>cryptanalysis</strong></a>. </p>
<blockquote>
<p>Proving a system to be cryptographically secure requires a huge amount of time, research, extensive testing and community engagement. Thus, it is always recommended to use a proven and standard cryptographic system. Don't try to roll out your own.</p>
</blockquote>
<p>Such algorithms guarantee that salt will be unique and unpredictable. Now, although the password is the same, Bob and Alice's password would have different hash</p>
<pre><code><span class="hljs-attribute">hash</span>('unlockmeea<span class="hljs-number">22</span>$sas') = '<span class="hljs-number">1471</span>dc<span class="hljs-number">5</span>d<span class="hljs-number">222</span>f<span class="hljs-number">43483</span>aee<span class="hljs-number">85051691</span>f<span class="hljs-number">45</span>c<span class="hljs-number">7</span>bf<span class="hljs-number">135</span>e<span class="hljs-number">55</span>d<span class="hljs-number">0</span>b<span class="hljs-number">53184</span>ffaf<span class="hljs-number">4</span>cc<span class="hljs-number">4</span>d<span class="hljs-number">30905</span>f'

<span class="hljs-attribute">hash</span>('unlockme<span class="hljs-number">3</span>xx#$/a<span class="hljs-number">5</span>') = '<span class="hljs-number">5983</span>db<span class="hljs-number">3704436</span>d<span class="hljs-number">24</span>a<span class="hljs-number">6</span>acccb<span class="hljs-number">87405</span>cb<span class="hljs-number">002</span>dfd<span class="hljs-number">2</span>f<span class="hljs-number">04</span>b<span class="hljs-number">22</span>b<span class="hljs-number">451247</span>d<span class="hljs-number">541</span>b<span class="hljs-number">1</span>dbca<span class="hljs-number">295</span>a'
</code></pre><p>The salt should be unique for each and every password. The application/backend has to know which salt was used to hash a specific password. Otherwise, the application will never be able to produce the same output. This is why the salt has to be stored along with the hashed password. Let's see how the user table would look with salting in place. For this example, the salt is stored with the password using dot notation:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>id</td><td>name</td><td>password</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td>alice</td><td><strong>fE07$/</strong>.ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222</td></tr>
<tr>
<td>2</td><td>bob</td><td><strong>Xfk7aa</strong>.3caf14423f92dbac6f80589aa72f7be572d7b87562f9fd32ed0c4427b680b598</td></tr>
<tr>
<td>3</td><td>john</td><td><strong>Q//$cc</strong>.cc6db669c9856670ab5faf03a76b4885d146e62a1fd18ab7693a525368e7d654</td></tr>
</tbody>
</table>
</div><p>When Alice wants to log in with her correct password <code>unlockme</code> (suppose), she will provide her password in the login form. The server will find Alice in the user table and see that the salt is <code>fE07$/</code>. So the salted string will be <code>unlockmefE07$/</code>. This string will be hashed and then matched with the existing database hash <code>ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222</code>. If they both match, Alice is authenticated. If it doesn't, it means Alice gave the wrong password.</p>
<p>At this point, there is no way for the attacker to identify duplicate passwords.</p>
<p><strong>But how does salting prevent rainbow table/hash table attacks?</strong></p>
<p>As we saw earlier, hashing didn't prevent the attacker from cracking common/weak passwords. But salting solves the problem for us. Unlike traditional hashing algorithms like SHA256 or MD5, password hashing algorithms (like <code>bcrypt</code> or <code>blowfish</code>) are built to be <strong>very slow</strong>. There is a very specific reason for it.</p>
<p>Previously, the attacker pre-computed the hash. The initial computation took a lot of time, but after the table was prepared the attacker could use it indefinitely.</p>
<p>But when salting is introduced, each and every hash is unique. Because every salt is unique and unpredictable. Now, the attacker can't use any pre-computed hash table. For each password, the attacker has to create a rainbow table using that password's salt. This is a very tedious and time-consuming process.</p>
<p>In short, when the passwords were unsalted, the attacker:</p>
<ul>
<li>Pre-computed a hash table containing the most common password phrases. </li>
<li>Whenever he compromised a database with unsalted hashes, he just had to compare the hashes with the hash table and do a reverse lookup.</li>
</ul>
<p>Now, with the salting in place:</p>
<ul>
<li>Attacker compromises a database and sees the passwords are hashed and salted</li>
<li>If the attacker wants to crack Alice's password, he has to use the salt <code>fE07$/</code> and create a rainbow table with the common password phrases.</li>
<li>For all the other users, the attacker has to create a new rainbow table with their salt and hope that the password is cracked. Do remember that rainbow tables can contain billions of common phrases and creating them is extremely expensive both from in time and space perspective.</li>
</ul>
<p>There's more to it. We said several times, hashing is <strong>slow</strong> for the attacker's inconvenience. Let's see exactly how slow it is.</p>
<p>One of the most widely used library for password hashing is <code>bcrypt</code>. Here is an example of password hashing using <code>bcrypt</code> with Node.js:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// app.js</span>
<span class="hljs-keyword">const</span> bcrypt = <span class="hljs-built_in">require</span>(<span class="hljs-string">"bcrypt"</span>);
<span class="hljs-keyword">const</span> saltRounds = <span class="hljs-number">15</span>;
<span class="hljs-keyword">const</span> plainTextPassword1 = <span class="hljs-string">"veryweakpassword"</span>;
bcrypt
  .genSalt(saltRounds)
  .then(<span class="hljs-function"><span class="hljs-params">salt</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Salt: <span class="hljs-subst">${salt}</span>`</span>);
    <span class="hljs-keyword">return</span> bcrypt.hash(plainTextPassword1, salt);
  })
  .then(<span class="hljs-function"><span class="hljs-params">hash</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hash: <span class="hljs-subst">${hash}</span>`</span>);
    <span class="hljs-comment">// Store hash in your password DB.</span>
  })
  .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> <span class="hljs-built_in">console</span>.error(err.message));
</code></pre>
<p>Here, the variable <code>saltRounds</code> is important. It is the cost or work factor for the salting algorithm. The higher the cost, the more iterations will be done to generate the salt, thus significantly slowing down the hashing process. Actually, the time required for salting grows <strong>exponentially</strong> with the cost.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627023246851/p5T4i24JE.gif" alt="graph.gif" /></p>
<p>In a <em>Core i7, 16 GB RAM</em> system salting with 15 rounds requires around <strong>20 seconds</strong> to complete, whereas 20 rounds require <strong>66 seconds</strong> to complete. In general applications, the cost/round is reduced to not cause any significant delay when registering new users. Even a 4-5 seconds delay is more than enough. Just imagine the attacker has to wait 5 seconds to generate each hash, where there are billions of phrases and salting is in place to force the attacker to generate a new rainbow table for each password.</p>
<h3 id="handling-data-breach">Handling data breach</h3>
<p>If your database is breached, you should immediately reset all user's passwords and inform them via email. Occasionally, a company can choose to inform their users to change passwords rather than resetting them from their side. </p>
<p>With enough computation power, the attacker might be able to reveal few weak passwords although salting and hashing slowed them down drastically. In such breaches, it is not possible to know exactly which passwords were compromised. Thus, we should consider all passwords as compromised and inform the users accordingly.</p>
<h2 id="protecting-yourself-from-a-data-breach">Protecting yourself from a data breach</h2>
<ul>
<li>You're at risk only if you're using a weak password, a password that is found in the common password list. So, always use a strong password. </li>
<li>Use a password manager like <a target="_blank" href="https://bitwarden.com/">BitWarden</a> . </li>
<li>When registering for new websites, generate a long (around 20-25 characters) password using BitWarden. With a strong password, the chance of password compromise is zero. <code>k8FQxVP&amp;t28jB&amp;!J!iCi</code> is an example of strong password which I generated using BitWarden while writing this article.</li>
<li>Don't use the same password on multiple websites</li>
<li>Change the password of important or transactional websites every 1-2 months.</li>
<li>Additionally, use  <a target="_blank" href="https://haveibeenpwned.com">HaveIBeenPwned</a> to find out if your passwords were ever compromised, if so, change all your existing passwords. </li>
</ul>
<p>Thank you for reading. Don't forget to leave your feedback and questions in the comments below. Also, if you like my articles then please follow/subscribe to the blog.</p>
]]></content:encoded></item><item><title><![CDATA[Synchronous vs asynchronous programming and their use cases]]></title><description><![CDATA[Synchronous and asynchronous are two different types of programming implementations that confuse a lot of new developers. This knowledge is very essential to create performant and scalable systems.
In short, a synchronous program blocks further opera...]]></description><link>https://blog.muhib.me/synchronous-vs-asynchronous-programming</link><guid isPermaLink="true">https://blog.muhib.me/synchronous-vs-asynchronous-programming</guid><category><![CDATA[operating system]]></category><category><![CDATA[asynchronous]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Fri, 09 Jul 2021 08:45:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1625820793424/eRcZLlao7l.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Synchronous and asynchronous are two different types of programming implementations that confuse a lot of new developers. This knowledge is very essential to create performant and scalable systems.</p>
<p>In short, a synchronous program blocks further operation till the current task execution has been completed. On the other hand, an asynchronous program allows to start multiple tasks at once, then progress and finish in <em>overlapping</em> time. Here the term <em>overlapping</em> is important. In the rest of this article, we will try to understand these concepts in detail and how they can be used to create efficient programs. To make you understand the differences between synchronous (parallel) and asynchronous (concurrent) programming, I will use a real-world restaurant example.</p>
<h2 id="concurrent-and-parallel-restaurant-orders">Concurrent and parallel restaurant orders</h2>
<h3 id="concurrentasynchronous-restaurants">Concurrent/Asynchronous restaurants</h3>
<p>Suppose, on a nice weekend you go to hang out with your friends in a restaurant. You see there's only one counter. You go to the counter and place your order.</p>
<p>The cashier forwards your order to the kitchen and gives you a token. When your order is prepared, the token number will be shown on the large display. So you get back to the table. While you're waiting for your order, you're having a good gossip with your friends. Because that's what people generally do, right?</p>
<p>When you're called to take your order, you pause your conversation, go to the counter to get the food and then get back and start eating. The conversation still goes on. At some point, you guys are done and leave the restaurant.</p>
<p><strong>Now, think of yourself as a computer program</strong></p>
<p>So, you're waiting in line to place the order. But the wait is not noticeable as the line is moving very fast. The reason is the cashier is only taking the orders, but not instantly preparing the items. <strong>(Wait for a program/functions/job to get placed in the system)</strong></p>
<p>When it's finally your turn, you process the menu in your head, place your order and pay. <strong>(Program gives parameters and execution logic to the system)</strong></p>
<p>Now you have to wait. But even when you're waiting, you've switched your attention to your gossiping. So, you're not totally idle and still doing something productive while waiting. <strong>(Don't wait for the current task to complete and pick something else to work on)</strong></p>
<p>At one point, your order is prepared. You go to the counter, get your food, return to your table and start enjoying the meal. <strong>(When the initial job's processing is complete, pick up where the program left off with that task and continue).</strong></p>
<p>So, we can say the story has three tasks. We assume that all the tasks are asynchronous:</p>
<ol>
<li>Get the food</li>
<li>Gossiping with friends</li>
<li>Eating the food</li>
</ol>
<p>When you placed the order on the counter, you started task 1. When it was being processed, you were focusing on task 2. So the task status is:</p>
<pre><code><span class="hljs-attribute">Task</span> <span class="hljs-number">1</span> = In Progress
<span class="hljs-attribute">Task</span> <span class="hljs-number">2</span> = In Progress
<span class="hljs-attribute">Task</span> <span class="hljs-number">3</span> = Waiting for execution (dependent <span class="hljs-literal">on</span> task <span class="hljs-number">1</span>)
</code></pre><p>When your order is complete, you go to the counter to fetch the items. Then you return to your table and enjoy the meal. Task 1 is complete and task 3 starts</p>
<pre><code><span class="hljs-attribute">Task</span> <span class="hljs-number">1</span> = Complete
<span class="hljs-attribute">Task</span> <span class="hljs-number">2</span> = In Progress (<span class="hljs-number">50</span>% complete)
<span class="hljs-attribute">Task</span> <span class="hljs-number">3</span> = In Progress
</code></pre><p>Please note, task 2 is halfway complete as you started doing it much earlier. You're eating your food and also talking with your friends. Doing two tasks at once? So what? Remember, all the tasks are asynchronous. Besides, tasks 2 and 3 are not dependent on each other. Task 2 and 3 is progressing in <strong>overlapping</strong> time. For better understanding, think of it this way:</p>
<ul>
<li>When you're eating, you're not talking. But your friends are talking so the conversation is still going on. </li>
<li>When you're not eating, you're talking.</li>
</ul>
<p>You can think of your talking as a separate async process. After some talk, you're waiting for feedback from your friends. At that waiting moment, you're eating your food. This goes on till both task 2 and 3 is complete.</p>
<p>That's it! That's how asynchronous programming works. Of course, we will jump into technical details in the later portions of this article.</p>
<p>For now, just note that all the above things happened in a <strong>single-core processor</strong> with a <strong>single-threaded program</strong>. We will get more into this later.</p>
<h3 id="parallelsynchronous-restaurants">Parallel/Synchronous restaurants</h3>
<p>Now let's imagine the restaurant has 4 counters to take orders. There are long lines in all the 4 queues and they are working parallelly. The catch is, the cook and the cashier is the same person. Meaning, the same person takes the order and prepares the item for you.</p>
<p>You choose the first queue, when your time comes after waiting, you place the order. Now, you have to wait in line. You can't move because someone else might take your position. The cashier/cook comes back with your order after some time. While you're waiting, other people are also waiting just like you to get their turn to place an order and get their food.</p>
<p>In this scenario, you're <strong>synchronized</strong> with the cashier/cook. You have to wait and be there at the exact moment that the cashier/cook finishes your order and gives them to you, or otherwise, someone else might take them. Then your cashier/cook finally comes back with your order, after a long time waiting there in front of the counter.</p>
<p>After getting the food, you get back to the table to eat. As you had to wait in the queue, you didn't get any time to have a good conversation with your friends. You just eat the food and leave the restaurant.</p>
<p><strong>Now, imagine you're the computer program</strong></p>
<p>The restaurant has 4 cashiers, which in the computer world would translate into 4 processor cores. For such, at least 4 threads are needed. You will be able to relate the rest of the story with the computer world easily so I'm not going to break it down further.</p>
<p>For the rest of the article, I would use the word 'synchronous' and 'sync' (short form) interchangeably. The same goes for asynchronous/async.</p>
<h3 id="is-asynchronous-programming-better-than-synchronous-programming">Is asynchronous programming better than synchronous programming?</h3>
<p>You saw from the story, for async programming you needed only 1 processor and a single thread. Whereas, sync programming, required 4 processors with 4 threads. Besides, you didn't get any time to gossip with your friends. It seems that synchronous programming is resource-heavy and also doesn't let you do much work. Hence, the burning question, is synchronous programming bad?</p>
<p><strong>No. This is a common misconception.</strong></p>
<p>The more precise answer is, "it depends". Using asynchronous programming where it should not be used would result in an extremely poor performing application. Let's jump into the technical details and everything will be clear as the blue sky.</p>
<h2 id="synchronous-vs-asynchronous-technical-differences">Synchronous vs Asynchronous: Technical differences</h2>
<p>The most popular asynchronous programming language is <strong>Node.js</strong>. On the other hand, Java, C++, Python all languages are synchronous by default. Newer versions of Python have asynchronous programming support, but it's still at an early stage and not mature at all. Such capability of doing both synchronous and asynchronous programming might make Python way more popular in future than it is now.</p>
<p>Asynchronous program is always single-threaded. The architecture and implementation of an asynchronous system require it to be single-threaded. Maybe we will discuss that in a separate article in future (If you're curious, you can look into JavaScript Event Loop). So, anything you write in Node.js will be single-threaded and will run under a single processor core.</p>
<p>If you don't have a clear idea about threading, you can read my article on  <a target="_blank" href="https://muhib.me/python-gil">Python multithreading and multiprocessing</a>. Although it discusses Python, it explains the concept of threading independently.</p>
<h3 id="async-the-good-side">Async: The good side</h3>
<p>Synchronous programs can be single-threaded or multi-threaded, depending on the developer's specification. A Python program (synchronous) can have a web process having multiple threads. Each thread can handle one web request at once and no more. </p>
<p>But due to the nature of asynchronous programming that we discussed, it can handle hundreds of requests by just using a single thread. For this reason, such programs are very lightweight.</p>
<p>So if it was a Python web application, you would need 100 threads to handle 100 different user requests at once. Creating and dropping threads is resource-intensive. You might be able to handle the same 100 users with a single thread if it's written in Node.js, which is really lightweight from a resource usage perspective.</p>
<h3 id="async-the-bad-side">Async: The bad side</h3>
<p>Wow! So good! Why don't we use async programming everywhere then? Unfortunately, everything good also has a significant bad side.</p>
<p>Async is only the best when you're doing I/O heavy operation (network request, database read etc). But for CPU intensive operations, asynchronous programs will be a nightmare. Because CPU operations are not the same as I/O. <strong>During mathematical operation, the CPU (processor) will be blocked, which in turn will block the only single thread that the program has.</strong> As a result, all the other user requests (assuming it's a web app) will be blocked till the current mathematical calculation is done, resulting in very poor performance. In such cases, you have to use something like Python or Java which is synchronous.</p>
<p>Besides, error handling for asynchronous calls might get tricky. </p>
<h3 id="is-async-faster-than-sync-in-general">Is async faster than sync in general?</h3>
<p>No. Well, technically it might be but that doesn't create any noticeable difference in most cases. The main advantage of asynchronous programming is it is very lightweight from the resource usage perspective. Both memory and processor usage. So with async programming, you can do a lot more with a lot less resources.</p>
<h2 id="use-cases">Use cases</h2>
<h3 id="synchronous-programming">Synchronous programming</h3>
<p>It's best for creating applications that use the CPU a lot. For example, training ML models, doing heavy mathematics etc. That doesn't necessarily mean that it can't be used for I/O operations. In fact, many I/O applications are created using synchronous programming languages like Java, C++ and Python. The only difference is, if you used an asynchronous program in those cases then it would use less resource</p>
<h3 id="asynchronous-programming">Asynchronous programming</h3>
<p>There are many use cases. It ultimately boils down to I/O operation. But I'm still breaking it down for your better understanding</p>
<ul>
<li><p><strong>I/O intensive web applications:</strong> You already know it's best for handling web requests, database requests etc. If your server has 4 processor cores, you can spawn 4 different processes with one thread each, effectively increasing system throughput up to 4x times.</p>
</li>
<li><p><strong>Hybrid web application:</strong> In most cases, you might need both CPU and I/O intensive tasks. In that case, you can use a combination of both by creating separate services. Take Uber as an example. Uber might have a separate <code>RouteCalculator</code> service for calculating the best route. This is CPU intensive task so this can be written in Python. On the other hand, for fetching user data or creating and updating users, Uber might have another <code>UserService</code> which is written in Node.js. The final resulting application is the union of both services where they communicate with each other effectively. The most popular web apps you see is written in this way using microservices (or similar) architectures.</p>
</li>
<li><p><strong>Causing side-effects:</strong> For complex applications, there are a lot of secondary tasks that are not directly related to the end-user. For example, when a user registers on Facebook, it will notify the other services, send and aggregate event logs, generate friend suggestions for the future etc. As these are not directly related to the immediate registration, Facebook can reply with a success response while queuing those tasks asynchronously for later execution.</p>
</li>
<li><p><strong>ML applications:</strong> Machine learning involves mathematical calculations. If your application works with ML, you can issue an asynchronous request to run ML jobs (written in Python maybe) while you finish up other tasks in your main application.</p>
</li>
<li><p><strong>Performance improvements:</strong> Using asynchronous operations might drastically improve application performance, or at least, make it look like a better performer. Separating async and sync operations is a crucial task for best performance. For example, when you move folders in Google Drive, the folders are immediately moved from the UI side, making it seem faster. But the actual folder move operation (backend) is done asynchronously which would take slightly more time.</p>
</li>
</ul>
<p>That's it for today. Feel free to leave any feedback or questions in the comments below.</p>
]]></content:encoded></item><item><title><![CDATA[Introduction to system scalability and reliability]]></title><description><![CDATA[Scalability and reliability are measures of how well your application can be served to end-users. If you have a system that can serve millions of users without noticeable downtime, then we can say the system is highly scalable and reliable.
When you'...]]></description><link>https://blog.muhib.me/introduction-to-system-scalability-and-reliability</link><guid isPermaLink="true">https://blog.muhib.me/introduction-to-system-scalability-and-reliability</guid><category><![CDATA[Cloud]]></category><category><![CDATA[scalability]]></category><category><![CDATA[Devops]]></category><category><![CDATA[System Architecture]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Sat, 19 Jun 2021 15:02:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1624114312297/bWDOFR02e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Scalability and reliability are measures of how well your application can be served to end-users. If you have a system that can serve millions of users without noticeable downtime, then we can say the system is highly scalable and reliable.</p>
<p>When you're working with a product that has a large user base, a lot of things change. Google has to process at least 100K requests per second. Without a robust scalable architecture, it would have been absolutely impossible. Scalability and reliability are probably the major factors for which we need Software Engineers in the first place.</p>
<p>In this article, we will go through a conceptual overview of software scalability and reliability. To understand this article, you have to know the basics of  <a target="_blank" href="https://muhib.me/web-development-career-in-2021">web development</a>  and  <a target="_blank" href="https://muhib.me/cloud-deployment-beginners">cloud</a>. It's an engineer's job to make the product scalable and robust. But please note, these topics are very diverse and large books can be written on these things. How the whole system is laid out is called the <strong>architecture</strong> of the system, which addresses scalability/performance and reliability. Besides regular Software Engineers, companies will have separate Staff Engineers, Software Architects or Site Reliability Engineers who will solve architectural problems from a much higher level. </p>
<p>The topic where scalability and software architecture is discussed is known as <strong>System Design</strong>. It is a very different skill compared to your general problem solving or coding skills. You might think that your job performance will be evaluated depending on how much good code you write and how good a problem solver you are. It's true, but only for the first 2-3 years. For senior roles, you will be judged based on your system architectural skills. Generally, a company expects that you will contribute at an architectural level when you have around 2-3 years of job experience. So, if you really want to climb the success ladder, you have to have a good grasp of such topics.</p>
<p>Here, I will cover very basics of scalability and reliability. For the sake of understanding, we will think of a fictional project and see how it scales depending on the user base.</p>
<p>Let's say you have created a social platform named <em>Circle</em> (we will just assume this name for future references), which is very similar to <em>Facebook</em>. This is a hobby project and you have given it to some of your friends to test it. So, your friends like Circle and they start using it from time to time.</p>
<h2 id="heading-case-1-very-small-user-base">Case 1: Very small user base</h2>
<p>Let's say Circle is doing well among your friends and currently you have the following metrics:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Total Users</td><td>Concurrent Users</td><td>Requests/second</td><td>Latency</td></tr>
</thead>
<tbody>
<tr>
<td>500</td><td>100</td><td>70-80</td><td>1-2 sec</td></tr>
</tbody>
</table>
</div><p>For such a scenario, a 1GB single-core server worth 5$  and a managed database should be enough. How many loads your server can handle cannot be determined with any theories, because there aren't any exact theories or calculations. You have to implement monitoring and logging to know if you need to use more than one server.</p>
<p>But for the sake of this example, let's say your 5$ single server is handling the load pretty good with an acceptable amount of latency. Latency is the time required to complete a request. Whereas concurrent users are the number of users that are active in your website simultaneously at a time instant. You have the following simple architecture.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624010679546/tmurYAPjJ.png" alt="a0 (1).png" /></p>
<p>For future references, let's name this architecture A0.</p>
<h2 id="heading-case-2-small-user-base">Case 2: Small user base</h2>
<p>More popularity, more users. With your current A0 architecture, you have the following metrics</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Total Users</td><td>Concurrent Users</td><td>Requests/second</td><td>Latency</td></tr>
</thead>
<tbody>
<tr>
<td>5000</td><td>2000</td><td>700-800</td><td>5-6 sec</td></tr>
</tbody>
</table>
</div><p>You might have already understood that <strong>latency</strong> is the metric that we're concerned about because that gives a clear idea of how the website is performing. So, things are not going well. The latency is not acceptable. It's a slow website now. A slow website is as good as a dead website. Also, you're seeing that due to excess load your single server is crashing sometimes. You have to improve the latency. If you can reduce server load, latency will improve as a side effect (and vice-versa).</p>
<p>So, you add another server to handle more load. You add a  <a target="_blank" href="https://www.nginx.com/resources/glossary/load-balancing/">load balancer </a> at the front. This will distribute the load equally between the two servers using  <a target="_blank" href="https://avinetworks.com/glossary/round-robin-load-balancing/">round-robin technique</a>. The architecture is as follows.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624011423941/pT4dqKb77.png" alt="a1.png" /></p>
<p>Let's name this architecture A1. After implementing this architecture, you see the latency has been reduced to 2-3 seconds, it seemed acceptable. So, you're good for now.</p>
<h2 id="heading-case-3-moderate-user-base">Case 3: Moderate user base</h2>
<p>Circle is not your hobby project anymore. It has gained huge popularity and there is a sudden spike in your network traffic. You have the following metrics with the A1 architecture </p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Concurrent Users</td><td>Requests/second</td><td>Latency (Actual)</td><td>Latency (Expected)</td></tr>
</thead>
<tbody>
<tr>
<td>20K</td><td>12K</td><td>10sec</td><td>&lt;= 2sec</td></tr>
</tbody>
</table>
</div><p>Before jumping to improvements, please note that I have removed the total user count and will continue to do so from this point onwards. Total user count doesn't affect the scalability in any way. We have to look for the active users who are using the application concurrently because those users are actually putting the load in the servers, not the inactive users.</p>
<p>Let's get back to the metrics. Ten-second latency is beyond acceptable. You set your expectation that the latency should be less than or equal to 2 seconds at this point. What to do to achieve this? Just add more servers</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624011873642/I84cAluLX.png" alt="a2-draft.png" /></p>
<p>After implementing this, you see the latency has improved up to 4 seconds. But this is still below your expectation. Maybe you can do something else rather than adding more servers? Yes, you can. <strong>After some observation, you see that your database is facing a high load all the time.</strong></p>
<p>Previously, we were only concentrating on servers because the server performance was the bottleneck. We just added more servers to overcome the issue. Now, the database load has become a performance bottleneck. If we don't address this database load, adding more servers will be of no use. Now, you may suggest adding more databases, just like we did with servers. But that is not preferable at this point for the given reasons:</p>
<ul>
<li>Databases are very expensive. A very simple managed database having only 30GB storage would cost you around 30-40$/month</li>
<li>Syncing across databases and keeping data consistent across them is a very challenging task from an engineering perspective</li>
</ul>
<p>Besides, databases are designed to handle huge loads and we aren't even close to the saturation point for the given scenario.</p>
<p>So, you monitor your weblogs and see that your application is read-heavy. It's a social platform, so people will actually read much more frequently than posting something in their timeline. This is true in many cases, most of the general applications are read-heavy. </p>
<p>Fortunately, there is an efficient way to reduce database load on reading operations. You just have to introduce a  <a target="_blank" href="https://redislabs.com/solutions/use-cases/caching/">caching layer</a>. </p>
<p><strong>Caching</strong>: What caching basically does is that it stores frequently requested data in the memory (RAM). We know that RAM access is much faster. So if the data is found in caching layer, then there is no need to hit the database. Caching is done in memory, so it's much faster than a traditional database. If the data is not found in the cache, only then the request will be directed to the database. This mechanism will drastically reduce database load and significantly decrease read operation latency. For our social platform, frequently accessed data might be the user feeds, the reactions and comments, friend lists etc which can be easily cached. We can use Redis as the caching database.</p>
<p>On another note, caching is a very difficult thing to implement correctly. If the data changes, the cache needs to be updated. Otherwise, users will be served with old data. Besides, it's difficult to determine which data properties should be cached to achieve better results.</p>
<p>Now with the caching layer, you see that the latency is around 1-2 seconds. The final architecture for this case is given below</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624012543070/oLunvUBaO.png" alt="a2-final.png" /></p>
<p>Let's name this architecture A2.</p>
<h2 id="heading-evaluating-your-service-reliability">Evaluating your service reliability</h2>
<p>One day, your service goes down for hours, your customers are angry and your platform will start losing profit. Your website is not reliable because it is down for hours. In a real-world scenario, just imagine the impact of Google being down for hours or Amazon.</p>
<p>So, how this downtime might occur? Well, the software is unpredictable. There might be downtime due to server maintenance issues, a bug that caused the server to crash etc. In the final architecture A2, can you imagine any possible scenario when the clients might not be able to connect to your platform, at all?</p>
<p>Let's say one of the servers from the server pool goes down due to some crash, there are still many other servers to handle the clients. <strong>The load balancer is intelligent enough to re-route new requests to the working servers</strong>. In the meantime, you can fix the issue with the bad server and once is fixed, it will be back in the working pool again. So, the server downtime issue is already fixed. Can you imagine any other devastating scenario? Is there any fault with the current architecture?</p>
<h3 id="heading-understanding-single-point-of-failure">Understanding "Single Point of Failure"</h3>
<p>Previously, if one server went down, the load balancer would re-route the request to other working servers. The load balancer itself is a server. What happens if the load balancer goes down? If you look into the architecture carefully, load balancer was the single point where all your clients connected. The clients only know the load balancer IP, the server IPs are never exposed to the clients. Such points are called <strong>single point of failures</strong>, as if that point stops working, your whole system is down. In a system architecture, we often have to look out and eliminate such single failure points.</p>
<p>To solve this issue, just like the server, you have to add redundancy in load balancing too</p>
<p><strong>There are multiple load balancers now, how the client would know which load balancer to connect?</strong></p>
<p>Every service has a record in the DNS system. So, let's say if your DNS name is <code>circle.com</code>, then you can assign multiple IP addresses for the same DNS. As you have guessed, the IP addresses will be the load balancer IPs. So, the DNS will be responsible for distributing the requests. Now, you might ask, what would happen if the DNS is down? Practically, if DNS is down, the whole internet is down. DNS is a global thing and I don't know any incidences of the DNS system being down. The architecture is given below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624025835754/eP7qU8un1.png" alt="a2.5.png" /></p>
<p>Here, we have placed <code>M</code> number of load balancers and <code>N</code> number of servers, where <code>M &lt;&lt; N</code>. Let's name it A2.5. This architecture has no single point of failures.</p>
<p><strong>What about database failures?</strong></p>
<p>Currently, we have a traditional database and a caching database in the system. This might also go down. But, we assume that we are using <strong>managed databases</strong>. It means the providers of the database (like AWS, Google Cloud) will manage the database for us. Providers will constantly keep a backup and redundancies as required.</p>
<h2 id="heading-case-4-large-user-base">Case 4: Large user base</h2>
<p>With the previous A2.5 architecture, you can serve a large number of users just by increasing values of <code>M</code> (load balancer count) and <code>N</code> (server count). But at one point, there is a very high chance that you will face a performance bottleneck in the database. It's simple, more users, more data. And even databases can get slow if you try to run queries in, let's say 500M data rows. It might seem like a lot of data, but this is common for very large applications. </p>
<p>Let's go through our current observations, where we assume that the values of <code>M</code> and <code>N</code> is high enough for a large system:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Concurrent Users</td><td>Requests/second</td><td>Latency (Actual)</td><td>Latency (Expected)</td></tr>
</thead>
<tbody>
<tr>
<td>100K</td><td>80K</td><td>6s</td><td>&lt;= 2sec</td></tr>
</tbody>
</table>
</div><p>So, this is the time to introduce some complexity in the data layer by introducing a master-slave architecture.</p>
<blockquote>
<p>In a real-life scenario, you will have a lot more options before making your data layer complex. For example, breaking down services and scaling up separate services as required, each having their own database systems. But for the sake of learning and simplicity, we are considering a mono repo (single-service) with a single database</p>
</blockquote>
<h3 id="heading-master-slave-architecture-for-the-data-layer">Master-slave architecture for the data layer</h3>
<p>In such an architecture, there are multiple nodes of the same type. There is only one <code>master</code> node who are tasked with an important responsibility, whereas the <code>slaves</code> are helping hands for the master.</p>
<p>If we apply this architecture to a database system, you will have multiple databases. Among them, one will be master and the others will be slaves. One common practice is given below:</p>
<ul>
<li>Read operations will be handled by slaves</li>
<li>The master will handle ONLY the write operations</li>
<li>There will be a synchronization service to propagate the write changes from master to slaves</li>
</ul>
<p>Let's see how our final architecture would look like with the master-slave database in place:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624112364558/stQWKHJj3.png" alt="a3.png" /></p>
<p>After implementing this, you see your latency is reduced to 2s. So you're satisfied for now. Please note, this architecture is not perfect for practical use cases. To keep things simple I have removed several redundancies and components. Let's name it A3 for future references.</p>
<h2 id="heading-case-5-huge-user-base">Case 5: Huge user base</h2>
<p>Your users have expanded through different geographical regions. Your new metrics are:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Concurrent Users</td><td>Requests/second</td><td>Latency (Actual)</td><td>Latency (Expected)</td></tr>
</thead>
<tbody>
<tr>
<td>500K</td><td>300K</td><td>5s</td><td>&lt;= 2sec</td></tr>
</tbody>
</table>
</div><p>And you have the following observations:</p>
<ul>
<li>Your servers are situated in Asia (assume). Your USA user base is having high latency because of the extra distance the network packets have to travel</li>
<li>The data storage is so so huge that it seems it is not possible to store all the data in the master database</li>
</ul>
<p>Now, solving this is very complicated and obviously too advanced for a beginner. Besides, there is no "correct" system design. But you have come this far, so I will give you a very high-level idea of how such scaling can be achieved:</p>
<ul>
<li>Each region (Asia/Europe) will have its own independent architecture</li>
<li>There will be a gateway service for each architecture. When different regions need to talk to each other, they will use the gateway. The gateway service will decide what to do.</li>
<li>There will be a huge sized main data centre that will collect all data from different regions and will serve as the single source of truth. It will have its own redundancies.</li>
</ul>
<p>The simplest presentation of the architecture is given below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624113626075/uZH4bNyMu.png" alt="a4.png" /></p>
<p>This is as far as I can go in terms of complexity. This is more than enough for a new learner. I wish I could have said to you that at this point, you know many things about system architecture. But to be honest, I can't say that. System architecture is much more complicated than what is shown here. We just scratched the surface. For example, we considered only client, server and databases. But in a real-world large scale application, there might be hundreds of different components working together. Interesting, isn't it?</p>
<p>I hope you have learnt something valuable and enjoyed reading this article. Please leave your feedback and questions in the comments below. If you like my articles, don't forget to follow and subscribe. Thank you!</p>
]]></content:encoded></item><item><title><![CDATA[Multiprocessing, Multithreading and GIL: Essential concepts for every Python developer]]></title><description><![CDATA[Multithreading and Multiprocessing are ways to utilize 100% of the CPU and create performant applications. If you work with complex web applications, machine learning models or video/image editing tools then you have to tackle multithreading/multipro...]]></description><link>https://blog.muhib.me/python-gil</link><guid isPermaLink="true">https://blog.muhib.me/python-gil</guid><category><![CDATA[Python]]></category><category><![CDATA[multithreading]]></category><category><![CDATA[operating system]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Fri, 04 Jun 2021 13:45:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1621878077736/vqIlNB7Sv.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Multithreading and Multiprocessing are ways to utilize 100% of the CPU and create performant applications. If you work with complex web applications, machine learning models or video/image editing tools then you have to tackle multithreading/multiprocessing sooner or later.</p>
<p>Let's say you create an application for editing photos. When the photo has a very high resolution, you will see a very significant drop in performance. Why? Because image editing is mathematically expensive. It puts pressure on the processor. To improve performance, you have to introduce multiprocessing/multithreading. In that case, if a user's CPU has 4 cores, your application should use all 4 cores if required.</p>
<p>Compared to other languages, multiprocessing and multithreading have some limitations in Python. Lacking the knowledge might result in creating slow and inefficient systems. The main purpose of this article is to understand the difference.</p>
<p>Let's get started by knowing a little bit more about Multithreading and Multiprocessing</p>
<h2 id="multithreading-vs-multiprocessing">Multithreading vs Multiprocessing</h2>
<p>Let's see the basic differences first</p>
<h3 id="multithreading">Multithreading</h3>
<ul>
<li>A <strong>single process</strong>, having multiple <strong>code segments</strong> that can be run <strong>concurrently</strong></li>
<li>Each <strong>code segment</strong> is called a <strong>thread</strong>. A process  having multiple threads is called a multi-threaded process</li>
<li>The process memory is shared among the threads. So thread A can access the variables declared by thread B</li>
<li>Gives the impression of parallel execution, but it's actually concurrency which is not the same as parallelism. Although, threads can run in parallel in a multi-core environment (more on this later)</li>
<li>Threads are easier to create and easier to throw away</li>
</ul>
<h3 id="multiprocessing">Multiprocessing</h3>
<ul>
<li>Multiple processes, working independently of each other. Each process might have one or more threads. But a single thread is the default.</li>
<li>Each process has its own memory space. So process A cannot access the memory of process B</li>
<li>Two different processes can run at two different cores in parallel independent of each other</li>
<li>There is a significant overhead of creating and throwing away processes </li>
</ul>
<p>Now, the terms <strong>concurrency</strong> and <strong>parallelism</strong> are not the same. By concurrent execution it means a task can start, progress and complete in <em>overlapping time</em>. It doesn't necessarily mean that they are running at the same instant. On the other hand, parallel execution means two tasks are literally running at the same instant (in a multi-core environment).</p>
<p>Also, we have to understand the difference between <strong>I/O bound</strong> and <strong>CPU bound</strong> operations.</p>
<p>If an operation depends on I/O (input/output) devices to complete its work, then it's <strong>I/O bound</strong> operation. For example, network requests, reading from a database or hard disk, reading from memory, writing to database - all these are I/O bound.</p>
<p>If an operation depends on the processor to complete its work, then it's a <strong>CPU bound</strong> operation. For example, matrix multiplication, sorting arrays, editing images, video encoding/decoding, training ML models all are CPU bound operations. The common thing here is a mathematical operation. Every example stated here involves heavy mathematical calculation which can be done by the processor only.</p>
<p>In a single-core processor, thread execution might look like below</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1622654761005/9CBBrD2P5.png" alt="core-1.png" /></p>
<p>There are two processes, namely <em>Process 1</em> and <em>Process 2</em>. While Process 1 is executing, Process 2 has to wait. In the case of threads, they can be executed concurrently (not in parallel). So for example, if <em>Thread 1</em> issues a web request, it can take some time for the web request to complete. In that idle time, the CPU will be given to <em>Thread 2</em> and it can do its operation (maybe do another web request). <strong>Please note, thread switching is efficient if it's an I/O bound operation. In the case of CPU bound operation, it doesn't yield better results from the performance perspective.</strong></p>
<p>In a multi-core scenario, thread execution might look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1622657528171/XskMEmhGX.png" alt="multi-core.png" /></p>
<p>In the above figure, there are 2 processes each having 8 threads (16 threads in total). As you can see, threads for Process 1 have expanded to core 2. Threads 1-4 and threads 5-8 (blue boxes, top to bottom) are executed in <em>parallel</em>, because they are running in different cores. The same applies to <em>Process 2</em>. <em>Concurrency</em> among the threads in a single core is still preserved. Thus, the computation power is doubled for a process. This was possible when we used multithreading in a multi-core environment.</p>
<p>Now, when to use multithreading and when to use multiprocessing? It depends. Based on the characteristics described above, a programmer will go with either of them. If communication is important, then threads might be better because memory is shared. There are some more factors involved but to keep things simple, we will not dive into those. But in the case of performance, there is a very subtle difference. Creating more processes would be slower than creating threads because processes have an extra overhead and threads are more lightweight in nature. </p>
<p>In most cases, a C++ or Java programmer will go with multithreading unless there is an absolute need to go with multiprocessing (btw, don't mix up the term multiprocessing and multi-core). But, can we say the same thing for Python? Unfortunately, no. Python is different from C++ or Java.</p>
<h2 id="whats-so-different-in-python">What's so different in Python?</h2>
<p>Previously, we saw that threads of the same process might expand to the second core or more if required. <strong>Unlike C++ or Java, Python's multithreading cannot expand to the second core  <em>by default</em> no matter how many threads you create or how many cores the computer might have</strong>. All the threads will be run in a single core. Why? It's to make the program thread-safe. </p>
<p>We know that memory space is shared between threads. So let's say you have a variable named <code>counter</code> which has a value of <code>3</code>, <code>counter = 3</code>. Now, if thread A is modifying the <code>counter</code> variable, thread B should wait for thread A to complete. If both of them tries to modify the variable at the same time, there will be a  <a target="_blank" href="https://stackoverflow.com/questions/34510/what-is-a-race-condition">race condition</a>  and the final value will be inconsistent. So, there should be some <strong>locking mechanism</strong> which can prevent the race condition.</p>
<p>Java and C++ use some other kind of locking mechanism to prevent the race condition. Python uses GIL.</p>
<h3 id="introducing-global-interpreter-lock-gil">Introducing Global Interpreter Lock (GIL)</h3>
<p>We know that Python is an  <a target="_blank" href="https://www.geeksforgeeks.org/difference-between-compiled-and-interpreted-language">interpreted language</a>  and thus it runs in an interpreter. GlL is a type of  <a target="_blank" href="https://www.geeksforgeeks.org/mutex-vs-semaphore/">mutex lock</a> that locks the interpreter itself.</p>
<p>Python uses <strong>reference counting</strong> for memory management. It means that objects created in Python have a reference count variable that keeps track of the number of references that point to the object. When this count reaches zero, the memory occupied by the object is released. Let's see an example to make it more clear</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> sys

a = <span class="hljs-string">'Hello World'</span>
b = a
c = a

sys.getrefcount(a) <span class="hljs-comment"># outputs 4</span>
</code></pre>
<p>For the above example, the variable <code>a</code> is referenced in 4 places. The variable was referenced during the statements <code>a = 'Hello World'</code>, <code>b = a</code>, <code>c = a</code> and <code>sys.getrefcount(a)</code>.</p>
<p>Now, this reference counting system needs protection from a race condition. Otherwise, threads may try to increase or decrease the reference values simultaneously. If this happens then it would cause memory leaks, or, incorrectly release memory when the object/variable is still in use. This is where GIL comes into play. It's a <strong>single lock</strong> on the <strong>interpreter itself</strong>. It enforces the rule that any Python bytecode must acquire the interpreter lock before it can be executed.</p>
<p><strong>Alternative Python Interpreters</strong>: One thing to note, GIL is only used in the CPython implementation of the Python language. CPython is written in C. This is the official and most popular implementation that you download from the Python website. Just so you know, there are other interpreter implementations of Python, such as <strong>Jython</strong> (written in Java), <strong>IronPython</strong> (written in C#) and <strong>PyPy</strong> (written in Python). These implementations don't have GIL. Although, they are not popular and very few libraries support them. Also, in later portions, you will know although seemingly obstructive, why GIL was chosen as the best solution.</p>
<h2 id="the-impact-of-gil-in-multithreaded-python-program">The impact of GIL in multithreaded Python program</h2>
<p>As GIL locks the interpreter itself, parallel execution of the program is not possible for a single process. So even if you create one hundred threads, all of them will run in a single core because of the GIL. The following figure clarifies how it would look</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1622793650732/BJDKgNNrk.png" alt="Copy of multi-core.png" /></p>
<p>For C++, a hundred threads have been distributed in four cores. For Python, all the one hundred threads are running under the same core because of GIL.</p>
<h2 id="the-remedy">The Remedy</h2>
<p>It is possible to run a Python program utilizing all the cores available to you. How? Using multiprocessing instead of multithreading. For the record, I will show how to easily create a thread pool and process pool in Python. Of course, there are other ways to create threads and processes. But the one I'm going to show is more than enough in most cases.</p>
<p><strong>In Python, when to use multithreading and when to use multiprocessing?</strong><br />If your program does I/O heavy tasks, go for multithreading. Doing multiprocessing here would be a bad idea because of extra overhead. On the other hand, if your program does mathematical calculations, go with multiprocessing. Using thread, in this case, might result in decreased performance. If your program does both I/O and CPU related tasks, then you have to use a hybrid of both.</p>
<h3 id="multithreading-with-threadpoolexecutor">Multithreading with <code>ThreadPoolExecutor</code></h3>
<p>Let's say you have a program that scrapes web pages. Web requests are I/O bound operation, so threads are perfect here. Look at the code below:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> concurrent.futures <span class="hljs-keyword">import</span> ThreadPoolExecutor, wait

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">scrape_page</span>(<span class="hljs-params">url</span>):</span>
    <span class="hljs-comment"># ... scraping logic</span>

    <span class="hljs-comment"># remove the following line when you have written the logic</span>
    <span class="hljs-keyword">raise</span> NotImplementedError

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">batch_scrape</span>(<span class="hljs-params">urls</span>):</span>
    tasks = []

    <span class="hljs-keyword">with</span> ThreadPoolExecutor(max_workers=<span class="hljs-number">8</span>) <span class="hljs-keyword">as</span> executor:
        <span class="hljs-keyword">for</span> url <span class="hljs-keyword">in</span> urls:
            <span class="hljs-comment"># for executor.submit, the first argument will be the name of the function to execute. All the argument after that will be passed as the executing function's argument</span>
            tasks.append(executor.submit(scrape_page, url))

    wait(tasks)


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    urls = [<span class="hljs-string">'https://google.com'</span>, <span class="hljs-string">'htpps://facebook.com'</span>]
    batch_scrape(urls)
</code></pre>
<p>In the given code example, 8 threads will be spawned. We mentioned it using the <code>max_workers</code> argument.</p>
<h3 id="multiprocessing-with-processpoolexecutor">Multiprocessing with <code>ProcessPoolExecutor</code></h3>
<p>Fortunately, <code>ThreadPoolExecutor</code> and <code>ProcessPoolExecutor</code> uses the same interface. So, the code will be almost similar to the previous one. For this example, we will assume we're encoding video files, which is a CPU intensive task</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> concurrent.futures <span class="hljs-keyword">import</span> ProcessPoolExecutor, wait

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">encode_video</span>(<span class="hljs-params">file</span>):</span>
    <span class="hljs-comment"># ... encoding logic</span>

    <span class="hljs-comment"># remove the following line when you have written the logic</span>
    <span class="hljs-keyword">raise</span> NotImplementedError

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">batch_encode</span>(<span class="hljs-params">files</span>):</span>
    tasks = []

    <span class="hljs-keyword">with</span> ProcessPoolExecutor(max_workers=<span class="hljs-number">4</span>) <span class="hljs-keyword">as</span> executor:
        <span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> files:
            tasks.append(executor.submit(encode_video, file))

    wait(tasks)


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    filePaths = [<span class="hljs-string">'file1.mp4'</span>, <span class="hljs-string">'file2.mp4'</span>]
    batch_encode(filePaths)
</code></pre>
<p>Here, 4 processes will be created. All four process can run in parallel because each process has its own interpreter. Thus, the GIL limitation doesn't matter in this case.</p>
<h2 id="why-gil">Why GIL?</h2>
<p>Now that you know how to run your Python program utilizing multiple cores, you might wonder why use GIL instead of other solutions. Also, why not remove GIL?</p>
<p>Python is a very popular and widely used language. With many good sides, there are some bad sides like GIL (or, is it really a bad side? let's see). If it was not for GIL, Python would not be so popular nowadays. Let's see the reasons</p>
<ol>
<li><p>Other languages like Java/C++ use different locking mechanisms but with the cost of decreased performance for single-threaded programs. To overcome single-threaded performance issue they use something like JIT compilers</p>
</li>
<li><p>If you try to add multiple locks, there might be a <strong>deadlock</strong> situation. Also constantly releasing and acquiring locks has performance bottlenecks. It's not very easy to overcome these things while keeping awesome language features. GIL is a single lock and simple to implement.</p>
</li>
<li><p>Python is popular and widely used because of its underlying support for C extension libraries. C libraries needed a thread-safe solution. GIL is a single lock on the interpreter, so there is no chance of deadlocks. Also, it's simpler to implement and maintain. So ultimately GIL was chosen to support all those C extensions</p>
</li>
<li><p>Developers and researchers tried to remove GIL in the past. But as a result, they saw a significant performance drop for single-threaded applications. You should note that most general applications are single-threaded. Also, the underlying C libraries on which Python heavily depends got completely broken. A major thing like GIL cannot be removed without causing backward compatibility issues or slowing down performance. But still, researchers are trying to get rid of GIL and it's a topic of interest for many.</p>
</li>
<li><p>Ultimately, it seemed that the GIL limitations are not causing any impact when it comes to writing large and complex applications. After all, multiprocessing is still there to solve such problems. Today's modern computers have enough resource and memory to tackle multiprocessing related overheads.</p>
</li>
</ol>
<p>That's it for today. I hope you learnt something new and interesting. If you like my article, please follow and subscribe to my  <a target="_blank" href="https://muhib.me">blog</a> . Also, if you have any questions or feedback, drop a comment below. Thank you.</p>
]]></content:encoded></item><item><title><![CDATA[Starting Web Development in 2022: The Complete Guide (with Resources)]]></title><description><![CDATA[If you're a beginner and want to have a tech career, you might be confused about all the career specialization choices. There are things like Machine Learning/AI, Data Science, Game Development, Quality Assurance, Cyber Security and of course, Web De...]]></description><link>https://blog.muhib.me/web-development-career-in-2022</link><guid isPermaLink="true">https://blog.muhib.me/web-development-career-in-2022</guid><category><![CDATA[Web Development]]></category><category><![CDATA[webdev]]></category><category><![CDATA[Flask Framework]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Career]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Mon, 31 May 2021 15:28:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1622472668073/zHW-tI4xv.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you're a beginner and want to have a tech career, you might be confused about all the career specialization choices. There are things like Machine Learning/AI, Data Science, Game Development, Quality Assurance, Cyber Security and of course, Web Development.</p>
<p>If you have already made up your mind and you have your reasons to choose a certain career path (excluding Web Dev), then, this post is not for you. Otherwise, I will try to convince you why you should start with Web Development as the first step:</p>
<ol>
<li><p>It has a high demand in the job market</p>
</li>
<li><p>Web is the most accessible platform, anyone from anywhere can access it. All they need is an internet connection and a device capable of handling a web browser. If you make an Android app, it will be only runnable on Android devices. But if you make a Web app, everyone can use it</p>
</li>
<li><p>No matter what you choose as a tech career, you will be directly or indirectly involved with web development. Even if you're an AI Engineer/Machine Learning Engineer, still you would need basic knowledge of Web Development. So, learning Web Dev is not a bad investment in any scenario, even if you switch to Data Science or AI.</p>
</li>
<li><p>Ever used Uber? Of course you did (or at least some similar service). What does it do? It gives a ride-sharing platform and nothing more. Although the app seems very nice, it's actually the backend code that's doing all the magic, which also falls under the web category. They even have a dedicated Research and Development team called  <a target="_blank" href="https://eng.uber.com">Uber Engineering</a> where they get millions of investments and they're constantly bringing revolutionary changes in Software Engineering. Most of the work they do there is related to making the 'ride sharing' platform better, which might have seemed 'simple' to you a few minutes earlier. Interesting, right? You might store some data in a database, do some CRUD (No worries if you don't know the term) operations and make a nice looking web page. But you will be stuck when you're given a complicated system like Uber, which is running at a large scale and millions of users are using it at once.</p>
</li>
</ol>
<p>The gist is, web development can be very challenging and interesting work. But to face those challenges, you need to get a job as an engineer. So, let's guide you on that path. I am a Software Engineer working with web-based SaaS product, so I think my knowledge is valid enough for you.</p>
<p>Originally inspired by the well known  <a target="_blank" href="https://roadmap.sh/">Developer Roadmaps</a>, I shall share a mini roadmap with narrowed down choices (so that it's much easier for you to decide), my own experience and my learning resources so that you don't have to waste time to compile these things and look into the vastness of resources with great confusion.</p>
<blockquote>
<p>Why follow my choices? Well, the technologies I listed here are widely popular and has a high demand. If you can grasp the whole roadmap, you would have the capability to tackle any other technology in future if required.</p>
</blockquote>
<p>But before doing that, let's get familiar with some job titles that relate to web development:</p>
<p><strong>Frontend Engineer (Client-side)</strong></p>
<ul>
<li>Turn web design (provided by UI designer) into code.</li>
<li>Implement user interactions like button events, visual feedbacks etc.</li>
<li>Implement data model and data state. Decide how data is going to be stored and manipulated throughout the application</li>
</ul>
<p><strong>Backend Engineer (Server-side)</strong></p>
<ul>
<li>Design and implement database schema</li>
<li>Take system architectural decisions. Decide how to scale up your application to thousands or millions of users</li>
<li>Implement business logic for your unique product (like what happens on the server-side when a customer requests a ride in Uber)</li>
<li>Use tools and technologies to provide data insights</li>
</ul>
<p><strong>DevOps Engineer</strong></p>
<ul>
<li>Bridges the gap between Developers (who write code) and the Operations (who run the code) team. In simple terms, a backend/frontend engineer writes the code, while the DevOps engineers main responsibility is to serve the written code to customers</li>
<li>Automates the deployment pipeline using CI/CD (Continuous Integration and Deployment). By deployment, I mean from writing the code to serving it to end customers (<a target="_blank" href="https://www.guru99.com/software-development-life-cycle-tutorial.html">SDLC</a>).</li>
<li>Manage the servers and network. Ensure systems are running properly without downtime</li>
<li>Not directly involved with the implementation of the product</li>
</ul>
<p><strong>Full-Stack Software Engineer</strong></p>
<ul>
<li>Works in both Frontend and Backend</li>
<li>In most companies, the title is generally 'Software Engineer'</li>
<li>Small to moderate companies offer full-stack roles. For bigger companies, the product is so complex that a full-stack role is not possible. In those cases, they offer specific Backend or Frontend positions</li>
</ul>
<p><strong>Site Reliability Engineer (SRE)</strong></p>
<ul>
<li>Engineers who solve operational/scale/reliability problems and maintain infrastructure</li>
<li>It's an overlap of DevOps and Backend Engineering, or we can say a glorified form of DevOps Engineering</li>
<li>Has somewhat involvement with the software product by providing reliability consultations (like what DB to use or not to use, how to scale properly etc)</li>
<li>Not really involved in writing code for the actual software, rather routine maintenance work</li>
</ul>
<p><em>Please note, based on your company, you might be simply called a <strong>Software Engineer</strong> regardless of which above category you fall into.</em></p>
<p>In this article, I will guide you to the barebones, which is Frontend and Backend. These guidelines will be a starting point. I will also link a post of mine where you can get an idea of DevOps. There is no different career path for SRE. Just learn Backend Engineering and DevOps properly, that's it.</p>
<h2 id="heading-the-roadmap">The Roadmap</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1660074156419/I0bJymaFQ.png" alt="Untitled Diagram.drawio.png" /></p>
<p>If the rendering of the image is unclear, please use this direct link of the  <a target="_blank" href="https://viewer.diagrams.net/?tags=%7B%7D&amp;highlight=0000ff&amp;edit=_blank&amp;layers=1&amp;nav=1#R7V1bc9o4FP41zGQfyliSr48JJOl0kiYtO9t2X3YUrIAb26K2SKC%2FfiWwAFsGnICxaAgzAR%2Fbsn3Od666uIU60eQ6waPhLfVJ2IKGP2mhbgtC4EKPfwnKNKMY0J5TBkngz2nGktALfhN5YEYdBz5JM9qcxCgNWTDKE%2Fs0jkmf5Wg4SehL%2FrBHGvo5wggPiELo9XGoUr8FPhvOqa5lLOkfSTAYyisDI9sTYXlwRkiH2KcvKyR02UKdhFI2%2FxVNOiQU3Mvz5WrN3sWNJSRmVU6gv5%2Bnw39vv3T%2Bu0fP3Tj4%2FeEn%2BIAy%2BaRsKp%2BY%2BJwB2WZMY%2F51kdBx7BPRjsG3fo6jUeEAmrAhHdAYhzeUjjgdiOMIY9NMonjMKCcNWRRme8kkYN9Xfv8QrbetbKs7yS4225hmG480ZlmDwMq2OzSkyezOkcH%2FPI%2FTU5bQJ7Ky52L2yc64wlEQiib%2FIYmPY8zJKi8z9qZ0nPTJBgZmxwmmrZyYSeCa0IiwZMoPSEiIWfCcRxXOwDlYHLc49Z4G%2FFagkWkSMtD8lEyPXDvfAsPJgLDspCUI%2BI%2BVu1iSZtB4BUxM4wST44CJ2Tb547mWaXrc%2FDpWDjUAWW1bPL4NDGQBy4Z1oajX%2Fe5%2B7j6k9Hp0FwVPAzOi15IJa0C0BMflklrA1A4AWoLmx8qecgBx8SbTlZPE5o%2FVfcvTZlvyPAVQ4u%2FqaoGcgvh3gtJcVpuOc3eEWE78r7UYWbvPOBxnV7rB8WAsvG0RBEsRC6m8DANGeiM848ELjyry4lRYvNDm1%2BrsM0kYmbQ2aaPcK81fpkZeZnxflgEBkF5%2BuBIMyNP2zlxTYW4L2iHLmDCLhiR%2F7F9jEWBwNiDPM%2FsiOlmS7IH47oQEx%2FykDo%2FeWuI5bBwJrs%2F%2Fc8pX8oj7jCZBPJDX4bc9v9S8iT3LlN9pxzBqlakL3ZxMIXAaFqqtCPV%2Byq1drPCWPyHbxMDM2T4GYVgg4TAYxHyzz%2FlGOP1C8Cvgwe55tiMKfH9mdsskljfFZU62HlEhkI99HKBIyiwRFKxLUI4iqE%2F4Gaf9JBixk7Bg3lYCqBrLg0oLwiajjteErcuoIxdzLEOQNVFHUbj7c5HbYxG3ajDi7TsA3i06cRUd7pJUqBU07jHj%2Bhanxx%2BnQNB0oAI3lxf%2BQOWrnGvWqJReRaWUIZAuSumpSokZfsDpEeYMSOqePrqI1ACTpmyQENXUvbeoZZHSSWm5XsNRi5ri3dJ4QLtqqvXeZGUarmayUjM31evF%2FrnojRDcDnGaBv28yKq6kZXKlPOq0tRbymCHrI9W9lmoos9aQYNVggZJ27Xg6nl5MEqfKpuYP7lSUlUaMs18Q8ApNFRzhR%2BqWe0hQPw%2BMWyeMFwHhtG7S%2FU1yDZg1RIAMiqi%2FjDZBlRLANeBADNnShrQeUGcM5%2BGCqi0Tz5M18xrdOPFbeQoXNS8L293VdvaHb53XZQqtl0Xq0ZRh9FFc7PhPsDwguNAVHOAMfc%2BgKEqYEpHEvzxjv4gIwmqS79J4yDvcsVRfyMPx%2BeUbbtYnW%2FaKZv2yew2Y3ZRVcXTzE%2BrUdwJMHoBpmpp4UCAcU%2BA0RwwllaAQWon1VXCmUNi%2F%2Fg8frGwZspJDY15fGv3Ibh7Vs83xdJHr54yndqunnqNm7F2T7yamxbwHvFj6VV0lfe9Yt4vcP%2Bp1LoPafQwTrdb9sOLp7oH8Jx8zmcCS%2FEAbokDcGtL%2BVT%2F%2BvHv25sW7Ih6d693fE4WSpskWey6DTtZUx270TtK1irxS%2FOstRTWfiW4rw671p63loU0462ljtXUJTHT0QNX7ey3bK08sCxCnjJybQGjV0Zub04ZT4BpHjCOVoCR971xJFkYBqOUbHfNOB3NV3V4DCYCXlpH%2B04hFLU81acjW3XpyK5JFLZ10t1GdNeq2rMqZ%2BBrorv2qUdQd8Do1SNon3oEdQeMXj2Cljqa451EBwDKQZCL8EAtBh40PLBKZoSdlhyY1V%2BdQuULqpHcQecYWWpNcXXRgavP1Cftn6eJfAAU1vUwkdrneljJqSXLs6sER%2BSFJk9%2FyfVUHhK5lMpViNMnRY761zNdp51fbMp2kMJ5IOfuHaaiqU7MO%2BtelPB87TxY7dnuAKgf29WpZGd3X29L%2BN77cnMe9ockmh4f513T1I7zMpusamsuJyOO%2BiOEPTBs7XivBlPlxmbdPG79mQ4NoBvT1bDo7K5bZmpmXKfHuJIEQMjVjO1yBa5T1r%2FfZHL7MkqtPefy2amFibzQKAxbqTYheF%2FzeO2yHoTc%2BoZL4MnFDMWOD%2BlMWuf8AIBGE3Wlwx5nMKu6hOEfWoVwYU60wFRsyUFrEG6FelDekLxiOBhSmQ%2FOxaeM%2BYs9dWanhXVmXHUKUOlMf%2BCZdZly1LQp13tl57pNLYA2aOdnawMD5ltZs2xCSVvA2NxSzYbbUcOxznAedRnnsZrk6Ved2mQx6oysHasAAk%2B1y15JiFffIqdq2eoIQ2euAUXlQurqsbJgkWNsXR0gjlqUug1CkjIObJ6JG6J1aNzi2MeMJied2aAzdgXZAstpl8Qz9Ym3wjpKf8TQ9jLdckpq7SVGC1l1Mb9kBUnSD7LlXO7FG1mgcXYf9J%2FE1ePpXyftWitdmYQtZFsyW106iYNolqsq0sGLDs5q1WERna4NVUtk8%2Bb0ZBHBrpXu9jEDmbpuH1HY2JiBX%2BefqOsHTjAxWfj1JZ7%2B7EQl75Ko8rqDh9lHLQJciBs%2FH0YcJNDoYT%2BavfzgdjwMHlbLhm%2BtMdyHZLZgrfHM7Y64uYeQDtqRaL4dCfojFa33LiX7ZveBha0IRQBQrTihp53ai%2BFBqNCvggw1Fi43PXsIhkuXm1FL%2B3uOhau98ELhYgmvN%2FnrfOWHx71tdQBKXbFwKV%2FVdPFuxAJhm48E8G9yzDuK0XILYVe5IPeULbbE%2FHv5irp5nWD5pj90%2BT8%3D">Roadmap</a>. Please go through the roadmap carefully as we will be referencing this for the rest of the article. Estimated time duration to complete the roadmap following only one Backend path would be around <strong>6-8 months.</strong> Also, this is the barebones of web development and there are a lot of things that you will have to learn later. But for now, this roadmap is perfect for beginners.</p>
<h2 id="heading-pick-a-programming-language">Pick a Programming Language</h2>
<p>This is the first step. As I have listed, my preferred choices are Python and Javascript. These two are very promising languages and they are never going to go away. Let me share the benefits of picking either of these languages</p>
<h3 id="heading-python">Python</h3>
<ul>
<li>It's easier to learn, difficult to master. It looks like almost natural language</li>
<li>Has powerful and battle-tested (read 'mature') web tools and frameworks</li>
<li>Great community</li>
<li>If you're thinking of switching to Machine Learning, AI or Data Science later, go blindly with Python. Because literally speaking, Python is the 'heart' of those sectors</li>
</ul>
<h3 id="heading-javascript">Javascript</h3>
<ul>
<li>The most popular and loved language</li>
<li>Great community</li>
<li><p>This is the language with diverse possibilities. If you learn this language, you can do Web Frontend, Server programming (backend), cross-platform mobile app development, desktop app development, game development and even for Machine Learning (experimental) and Embedded Systems programming. Although, I would not recommend this language for the last two. But you can see the picture, this language has the most diverse amount of use cases.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Jeff_Atwood">Jeff Atwood</a>, one of the founders of the life-saving platform (for devs) Stack Overflow, said this back in 2007</p>
</li>
</ul>
<blockquote>
<p>Any application that can be written in JavaScript, will eventually be written in JavaScript. - Jeff Atwood</p>
</blockquote>
<p>Popularly known as <em>Atwood's Law</em>, this is totally true nowadays. Recently, Google released  <a target="_blank" href="https://github.com/google/zx">zx</a>, which is a JS scripting library that might have the capability of replacing Bash/Shell scripting in future (just my personal opinion, but it's very promising though).</p>
<p>So make a decision and pick one language. Both of them is fine. <strong>Remember, which language you pick will affect your choice for the Backend section</strong>. Eventually, you should target to cover the whole roadmap, not just a specific path. So, look into the benefits and decide which language suits you better and start learning.</p>
<p>Okay, if you still can't decide, go with JavaScript.</p>
<p><em>You might have heard of <strong>Node.js</strong>, it's a programming language. It's identical to JavaScript, with absolutely zero difference. It is given a different name because it can run outside a web browser environment, unlike JavaScript.</em></p>
<p><strong>Learning resources are provided at the end of the article</strong></p>
<h2 id="heading-design-patterns">Design Patterns</h2>
<blockquote>
<p>Design patterns are typical solutions to common problems in software design. Each pattern is like a blueprint that you can customize to solve a particular design problem in your code</p>
</blockquote>
<p>Design Patterns are the most valuable but most underestimated skill. It relates to how you should structure your code in an Object-Oriented Design environment. In some cases, you will not be using these pre-defined patterns directly. But these are required so that you understand common OOP principles and even use customized versions of these patterns when you're working with large codebases.</p>
<p>Unless you have a thirst for learning, you don't need to go through all the patterns. Just focus on those listed below:</p>
<p><strong>Creational Patterns:</strong> Factory, Abstract Factory, Singleton, Builder</p>
<p><strong>Structural Patterns:</strong> Adapter, Decorator, Facade</p>
<p><strong>Behavioral Pattern:</strong> Command, Observer, Visitor</p>
<p><em>Don't know what Object Oriented Programming is? no worries, follow the roadmap and it will come on its own accord</em></p>
<h2 id="heading-database">Database</h2>
<p>Databases are used to store information. There are many diverse database choices. Mainly divided into SQL and No-SQL categories. I have made the choice easier for you. You're a new learner. So, it doesn't matter which database you choose to learn first. In an ideal scenario, you should learn both MongoDB and Postgres (at least at some point in future).</p>
<p>You need to be fluent with at least one database technology before jumping into web dev. <strong>If you previously chose the Python language, take Postgres (SQL). Otherwise, MongoDB (No-SQL database).</strong> Just so you know, you can use SQL databases with JavaScript too. I just recommend MongoDB because its syntax and usage matches JavaScript. Also, most JS-based web dev tutorials cover MongoDB by default. Although relatively new, MongoDB is being widely adopted by many companies. It can overcome many design limitations of a traditional SQL database. But don't think one is superior to another. Both have their own advantages and disadvantages.</p>
<h2 id="heading-version-control-with-git-and-github">Version Control with Git and GitHub</h2>
<p>Any software is subject to change, it can change daily, or even hourly. This is why Software Engineering exists in the first place. Version control systems like Git and GitHub are tools that allow you to record changes in your codebase and revert to a previous point if something fails. Also, it gives you the necessary tools to collaborate with other developers. It's a must-have knowledge no matter which tech sector you work in.</p>
<h2 id="heading-frontend">Frontend</h2>
<p>You have to start with Frontend first. You have to learn HTML, CSS, SCSS (CSS on steroids) and React. React is a front-end framework that makes front-end development much easier. There are also other frontend frameworks, but learning React is the best choice as it has the best features of the bunch and also high demand in the job market.</p>
<h2 id="heading-backend">Backend</h2>
<p>Now you have to choose either of the paths. The choice should depend on what you picked in the Language section. We will be focusing on how to build <a target="_blank" href="https://www.smashingmagazine.com/2018/01/understanding-using-rest-api">REST APIs
</a> because this convention is widely used in every type of mobile or web applications you see around you. All the provided tutorials for the backend has REST APIs covered.</p>
<h3 id="heading-python-path">Python Path</h3>
<p>Flask is a Python-based framework to write web applications using the Python language. It's easy to learn and very extendable. There's another framework named Django. But Django automates a lot of stuff. Personally, I don't prefer Django. On the other hand, Flask gives you a lot of control. Starting a project with Flask is much easier compared to Django. As Flask gives you much control, you will be able to learn a lot of things because those will be implemented by your own hand</p>
<p>As for database choice, there is only Postgres. Please note, you can use any database with Python. Not just Python, you can use ANY DATABASE with ANY LANGUAGE. But in this path, I have selected Postgres. Later when you master the whole roadmap, you can also use MongoDB with Flask if you want</p>
<p><strong>ORM (Object Relational Mapping)</strong>: ORM is an <em>abstraction layer</em> that sits on top of the database. Using ORM, you can use the programming language's own feature to manipulate and access data, instead of using a query language like SQL.</p>
<p>Let's say you want to select all students from the student table whose age is greater than 18. Also, assume you're using MySQL database. But before fetching the data, let's create a table where the data will be stored. We have to use SQL to issue the commands</p>
<pre><code><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> students (
  <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span> PRIMARY <span class="hljs-keyword">KEY</span>,
  <span class="hljs-keyword">name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">50</span>),
  age <span class="hljs-built_in">INT</span>
);
</code></pre><p>Running this SQL will create a table. Now to store some data:</p>
<pre><code><span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> students <span class="hljs-keyword">VALUES</span> (<span class="hljs-number">1</span>, <span class="hljs-string">'John'</span>, <span class="hljs-number">17</span>);
<span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> students <span class="hljs-keyword">VALUES</span> (<span class="hljs-number">1</span>, <span class="hljs-string">'Doe'</span>, <span class="hljs-number">19</span>);
</code></pre><p>Now, to fetch the students whose age is greater than 18</p>
<pre><code><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">from</span> students <span class="hljs-keyword">WHERE</span> age &gt; <span class="hljs-number">18</span>;
</code></pre><p>The above is a MySQL specific database query. SQL is quite similar to natural language. The given query will return all students having age greater than 18.</p>
<p>Now, if you use ORM with your Python application, you don't need to know the SQL at all. Instead, you will do something like this to create a table (Python example):</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Student</span>:</span>
  id = db.Column(...)
  name = db.Column(...)
  age = db.Column(...)
</code></pre>
<p>The above is a <code>class</code>, which you will learn during your OOP portion of your selected language.</p>
<p>Inserting records</p>
<pre><code class="lang-python">student = Student(<span class="hljs-string">'John'</span>, <span class="hljs-number">18</span>); <span class="hljs-comment"># id will be calculated automatically</span>
student.save()
</code></pre>
<p>To get all students whose age is greater than 18</p>
<pre><code class="lang-python">Student.query.filter_by(age &gt; <span class="hljs-number">18</span>).all()
</code></pre>
<p>As you can see, ORM allows you to use Python syntax to query and manipulate the database. You don't even need to know SQL (although you have to because otherwise, you won't know how to use ORM efficiently).</p>
<p>More importantly, using ORM saves you from a lot of troubles, for example, it prevents SQL injection which is a hacking method. Also, you can switch to any SQL database at a later point. For example, let's say we're using MySQL. Later if we want to switch to Postgres, we don't have to change the above code at all. How does ORM do that? Well, it's just an abstraction. Based on which database engine you're using, it can generate the equivalent dialect for you. So, the ORM will convert the Python statement <code>Student.query.filter_by(age &gt; 18).all()</code> into</p>
<pre><code><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> students <span class="hljs-keyword">WHERE</span> age &gt; <span class="hljs-number">18</span>;
</code></pre><p>Not only Python, but every language also offers some kind of ORM to work with. For Python, the most popular one is SQLAlchemy. You will have to learn that.</p>
<h3 id="heading-nodejs-path">Node.js Path</h3>
<p>Don't worry about the title, JavaScript and Node.js both are the same as I stated earlier. For server programming, you will have to get out of the browser environment thus calling it Node.js seems appropriate here. In this path, the web framework is Express, the database is MongoDB. MongoDB is a No-SQL database that is quite different from a SQL database. At some point in future, you should know both MongoDB and Postgres.</p>
<p>The ODM (Object Document Mapping) is Mongoose. ODM and ORM are the same things. But as this is a No-SQL database, there are some changes in the terms and definitions</p>
<h2 id="heading-clean-code-and-refactoring-optional">Clean code and refactoring (Optional)</h2>
<p>For the curious-minded people out there. This will definitely help when you start your first job. You can go through this much later if you want. Clean code and refactoring is a skill that comes through experience. But still, you have to know some concepts so that you get directed to the right path.</p>
<h2 id="heading-resources">Resources</h2>
<p>The section you've been waiting for! Here, most of the resources I share were used for my own learning. For some parts, you have to follow multiple tutorials. Please note, <em>order matters in those cases</em>.</p>
<p>Many Udemy resources are paid. Although pirated contents are available, you are encouraged to spend on the courses because it's worth investing in. So, here we go:</p>
<h3 id="heading-language">Language</h3>
<h4 id="heading-python">Python</h4>
<p><a target="_blank" href="https://www.udemy.com/course/the-python-mega-course">The Python Mega Course</a> </p>
<h4 id="heading-javascript">JavaScript</h4>
<p> <a target="_blank" href="https://www.udemy.com/course/the-complete-javascript-course">The Complete Javascript course by Jonas</a></p>
<p>Please note, this will also include some basic HTML, CSS. To learn JavaScript, there is no way to avoid HTML, CSS. But no worries, the instructor will guide you through smoothly.</p>
<h3 id="heading-clean-code-and-refactoring">Clean Code and Refactoring</h3>
<p><a target="_blank" href="https://refactoring.guru/refactoring">Refactoring.guru</a> </p>
<h3 id="heading-design-patterns">Design Patterns</h3>
<p> <a target="_blank" href="https://refactoring.guru/design-patterns">Refactoring.guru: Design Patterns</a> </p>
<h3 id="heading-database">Database</h3>
<h4 id="heading-postgres">Postgres</h4>
<p><a target="_blank" href="https://www.udemy.com/course/the-ultimate-mysql-bootcamp-go-from-sql-beginner-to-expert">MySQL Database Bootcamp</a></p>
<p>MySQL and Postgres are quite the same in syntax, only the engine is different. There's no good tutorial for Postgres in my knowledge so follow the MySQL one.</p>
<h4 id="heading-mongodb">MongoDB</h4>
<p> <a target="_blank" href="https://www.udemy.com/course/mongodb-the-complete-developers-guide">MongoDB - The Complete Guide by Academind</a> </p>
<h3 id="heading-git-and-github-version-control">Git and GitHub (Version Control)</h3>
<ol>
<li><a target="_blank" href="https://githowto.com">Git HowTo</a></li>
<li><a target="_blank" href="https://learngitbranching.js.org">Branching</a></li>
<li><a target="_blank" href="https://lab.github.com/githubtraining/introduction-to-github">Introduction to GitHub</a> </li>
</ol>
<p>As you can see, there are multiple resources. You have to go through all of them, in order. Don't worry, these courses are very small. It would take you at most 1 week to master the basics.</p>
<h2 id="heading-frontend">Frontend</h2>
<h3 id="heading-html-css-scss">HTML, CSS, SCSS</h3>
<ol>
<li><a target="_blank" href="https://www.udemy.com/course/design-and-develop-a-killer-website-with-html5-and-css3">HTML5 and CSS3 By Jonas</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=_a5j7KoflTs">SCSS (or Sass) for Beginners  </a> </li>
</ol>
<h3 id="heading-react">React</h3>
<p> <a target="_blank" href="https://www.udemy.com/course/react-the-complete-guide-incl-redux">React 16: The Complete Guide by Academind</a> </p>
<p><em>Things like Redux, Redux Thunk are obsolete nowadays. It's also difficult to understand. React has introduced 'Context API' which works as a replacement for Redux. So, you can safely skip or skim through the Redux related sections.</em></p>
<h2 id="heading-backend">Backend</h2>
<h3 id="heading-python-path">Python Path</h3>
<ol>
<li><a target="_blank" href="https://www.udemy.com/course/rest-api-flask-and-python">Build REST APIs with Flask</a> (Very average tutorial, misses a lot of things. But still a bit better than others. You have to follow it because it shows some modern techniques)</li>
<li><a target="_blank" href="https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world">Flask Mega tutorial by Miguel Grinberg</a> (Read the whole series. This will be the series that you will take as reference point while writing Flask code. Forget the bad practices introduced to you in the previous tutorial)</li>
</ol>
<p>Just a reminder, where you see these numbered tutorials, you have to follow all of them, <strong>in order</strong>. These are not options, but <strong>mandatory</strong>.</p>
<h3 id="heading-nodejs-path">Node.js Path</h3>
<ol>
<li><a target="_blank" href="https://www.udemy.com/course/nodejs-master-class">Node.js: The Complete Guide to REST APIs by Mosh</a> </li>
<li><a target="_blank" href="https://www.udemy.com/course/nodejs-express-mongodb-bootcamp">Node.js, Express and MongoDB By Jonas</a></li>
</ol>
<p>The given tutorials cover everything from the roadmap.</p>
<h2 id="heading-where-to-go-from-here">Where to go from here</h2>
<p>Now you have a solid basic understanding to create robust Web solutions. Soon, I will release another article with a roadmap of advanced topics. Stay tuned! For now, you can look into the Cloud section. I have a great starting point I've provided in my blog titled  <a target="_blank" href="https://muhib.me/cloud-deployment-beginners">Cloud Deployment for absolute beginners</a>.</p>
<h2 id="heading-some-tips-for-new-learners">Some tips for new learners</h2>
<ul>
<li>Don't rush. Take your time to learn these things. Learn everything thoroughly</li>
<li>Do Projects. This is extremely important. Don't fall into the <em>learning loop</em>. Be ready to get your hands dirty as soon as possible</li>
<li>Every project you do, keep it in GitHub. This is extremely important</li>
<li>Try to get involved in  <a target="_blank" href="https://opensource.guide/how-to-contribute">open-source contributions</a> . It will drastically boost your profile</li>
<li>Don't forget that Data Structures and Algorithms are important and might be asked in company interviews. This is not a Computer Science roadmap, so discussing algorithms is out of scope. But you should have a basic understanding. You can use  <a target="_blank" href="https://leetcode.com">Leetcode</a> (Easy + Medium levels) to practice interview questions.</li>
<li>Don't waste time on Coursera certificates. Instead, invest time in doing projects. By far, I haven't seen any company that judges a candidate by their Coursera certificates. I'm discouraging this because most people try to gather as much certificate as possible, without learning anything valuable. Even for a beginner, a company will look into how much real experience you have building things and solving problems, not those fancy certificates you showcase on Linkedin.</li>
<li>It's much better to pick few things and master them instead of being a <em>jack of all trades</em></li>
<li>There is no universal tech stack that can get you a job in any company. When hiring beginners, most good companies are tech agnostic</li>
<li>Even if you don't know a tech stack, you can learn that easily because now you have a strong fundament</li>
</ul>
<p>Thank you for reading this far. If you have any questions or feedback, please don't hesitate to drop a comment. This will encourage me a lot.</p>
<p>If you liked this article, please share it with your circle. Also, don't forget to follow my <a target="_blank" href="https://muhib.me">blog</a>. Have a nice day!</p>
]]></content:encoded></item><item><title><![CDATA[Cloud deployment for absolute beginners]]></title><description><![CDATA[Let's say you have created an awesome web application that uses some Machine Learning to suggest movies you might like.  Now what? You have to share it with the world so that people can use it, right? This is where deployment comes into play. 
In thi...]]></description><link>https://blog.muhib.me/cloud-deployment-beginners</link><guid isPermaLink="true">https://blog.muhib.me/cloud-deployment-beginners</guid><category><![CDATA[Cloud]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Ahmed Sadman Muhib]]></dc:creator><pubDate>Sat, 22 May 2021 13:35:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1621686908001/fi6U2KB4E.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let's say you have created an awesome web application that uses some Machine Learning to suggest movies you might like.  Now what? You have to share it with the world so that people can use it, right? This is where deployment comes into play. </p>
<p>In this post, I will give a high-level idea of cloud deployment. You will be introduced to different terminologies and use cases. I will refrain from going into low-level technical details of deployment (like, how to host a Node.js web app). There are already a lot of articles available for that and I have linked them in this post.</p>
<p>Besides, there are a lot of posts explaining the deployment process. But rarely those articles give the whole idea of cloud deployment in a beginner-friendly way, thus this post. If you're new to cloud computing, you will find it worthy. After reading this, I hope many of your confusions will be cleared.</p>
<p>The basics you need to know:</p>
<ul>
<li>I assume you already know basic web development and you want to deploy your application</li>
<li>Good command over Linux</li>
</ul>
<p>Things that are discussed in this post:</p>
<ul>
<li>What is cloud deployment and how does it work?</li>
<li>As a beginner, where should I start learning?</li>
<li>Which cloud provider to use?</li>
<li>What is the difference between Heroku and AWS</li>
<li>What is localhost and private networks?</li>
<li>NGINX/Apache? What are these?</li>
<li>Networking essentials</li>
</ul>
<p>...and many more</p>
<h2 id="what-do-you-mean-by-cloud-deployment">What do you mean by <em>Cloud Deployment?</em></h2>
<p>Well, to deploy your application you can do the following:</p>
<ol>
<li>Buy a server computer</li>
<li>Get a public IP to expose the server on the internet</li>
<li>Configure the OS to run your stack. For example, if your code is written in Python, install necessary packages (like Flask, Django etc) and configure them properly</li>
<li>Configure a web server to host your application to the internet</li>
<li>Keep your server running 24/7 at any cost. Because if your server is down, your application will be unreachable</li>
</ol>
<p><strong>Seems scary, right?</strong></p>
<p>To add on top of that, please note that as your application grows, you will need more and more servers to handle the load. So, now you have to maintain multiple servers.</p>
<p>The above scenario is almost obsolete nowadays. Unless you're handling very sensitive data (like state secrets), you will be using a cloud provider to host your application on the internet.</p>
<p>So, basically, what a cloud provider does, solves points 1, 2, 3 (partially) and 5 for you. By just using some Web UI, you can spin up new computers for you in less than a few minutes. It will be automatically configured with an OS, will have a public IP and will never be down (well, almost never). This computer is residing in a remote place in a large data centre among many computers (like cloud particles in the sky), we can see it (read 'access it') but don't know exactly where it is located, just like the 'Cloud', thus the term 'Cloud Computing'.</p>
<p>How do they do it? They have enough money and manpower to handle millions of computer and resources at once. They serve you this service through some sophisticated mechanism.</p>
<p>There are currently many cloud providers. The leading ones are  <a target="_blank" href="https://aws.amazon.com">Amazon Web Services (AWS)</a> ,  <a target="_blank" href="https://cloud.google.com">Google Cloud Platform</a> ,  <a target="_blank" href="https://azure.microsoft.com/en-us">Microsoft Azure</a> ,  <a target="_blank" href="https://www.digitalocean.com">DigitalOcean</a>  etc. If you're already tinkering with deployments, you might have also heard of  <a target="_blank" href="https://www.heroku.com">Heroku</a>,  <a target="_blank" href="https://www.netlify.com/">Netlify </a> and  <a target="_blank" href="https://vercel.com/">Vercel</a>. There are very clear differences between these two type of providers.</p>
<h2 id="heroku-vs-aws">Heroku vs AWS</h2>
<p>You can host your web application using both of these providers. But in Heroku, automation is the key. Heroku will automatically configure the OS and the tech stack for you. You just have to tell Heroku that you want to deploy a Node.js application and that's it! Thus, it will solve point 3 from above along with others. Also, it will automate the deployment process using GitHub, so that each time you push some code, your application will be automatically deployed. </p>
<p>But, this is not what cloud deployment actually is. First of all, you will have little to no control over how your application is deployed and maintained. </p>
<p>Secondly, these providers don't actually give you a computer/server, so you cannot remotely access those computers and do custom things on your own. They just provision you with some resource to run your web application and abstracts away from all the other things. </p>
<p>Thirdly, such providers are much more costly than AWS or Google Cloud platform because of the extra automation. For example, if you want to run a production application in Heroku, you will have to pay a minimum of 5$ for each application. On the other hand, DigitalOcean will give you a server for 5$ where you can run 2-3 applications at once.</p>
<p>If you just want to host a hobby project, Heroku/Netlify is the best option. Because the basic usage tier for Heroku/Netlify is FREE. But if you really want to get into the world of deployments (DevOps), or even kickstart your Software Engineering career, you should get your hands dirty by using AWS, DigitalOcean or similar providers.</p>
<p>Remember, using cloud providers requires that you have some idea of <a target="_blank" href="https://linuxize.com/post/basic-linux-commands">basic Linux commands</a>. No, they won't give you nice little graphical interfaces to work with. The servers are mostly Linux based. You will have to run all your operations through the command line just like the good old days.</p>
<p><strong>Now the question, where should I start?</strong> </p>
<p>Well, pick a cloud provider, spin up a server and start tinkering with the command line. See how things work. Maybe follow a tutorial on how to configure your freshly picked server. But before going to that, let's decide on which cloud provider to use.</p>
<h2 id="why-digitalocean">Why DigitalOcean?</h2>
<p>Contrary to popular opinions, I would advise starting with DigitalOcean.</p>
<p><strong>Pros:</strong></p>
<ul>
<li>It's much cheaper compared to other providers</li>
<li>Has a clean and easy-to-use UI</li>
<li>Has a lot of documentation written in a beginner-friendly way <strong>(most important point)</strong></li>
</ul>
<p><strong>Cons (don't worry about these now):</strong></p>
<ul>
<li>Has few services (for example, no support for automatic load balancing)</li>
<li>Has small tier of computing resources, there's not a lot of options compared to other providers</li>
<li>Some advanced networking and access management might not be possible or has to be done manually</li>
<li>Availability is not as reliable as GCP or AWS.</li>
</ul>
<p>If you're a beginner, there's a chance that the cons went over your head. At an entry-stage, those cons can be ignored.</p>
<p>All cloud providers will provide you with one thing, a computer system to work with. So, there's no learning difference at all. If you can work with DigitalOcean, you can work with AWS, Google Cloud Platform (GCP) or any other. In terms of learning, the only difference is their UI, access management and extra services they provide.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1621681288185/JcWzSArIW.png" alt="DigitalOcean pricing comparison" />
<em>DigitalOcean pricing comparison for a 1Core - 2GB memory instance</em></p>
<p><strong>How to use DigitalOcean?</strong></p>
<p>I'm not going to give you a step by step guide. If you're reading this, you should already know how to register for a service and add a credit card for payment.</p>
<p>You will be billed on an hourly basis. So if a specific computer costs 0.015$/hour and you keep that computer running for whole one month (24/7), it would cost you roughly 10$ at the end of the month.</p>
<p>In the DigitalOcean world, a single computing instance is called a <em>Droplet</em>. When you create a Droplet (a computer, or a computing instance), you can access that droplet and do whatever you want with it (like hosting web apps, playing with the terminal or even break the whole system apart 😉 )</p>
<p>Now how to create the droplet? Well, if there is an already well-written guide on the internet, there's no point of re-writing it, so follow this guide on  <a target="_blank" href="https://docs.digitalocean.com/products/droplets/how-to/create/">how to create your first droplet
</a>. Awesome documentation, right?</p>
<p><strong>What distribution/image to choose?</strong></p>
<p>We love Linux for servers. So I would recommend, from the Distributions tab, creating a plain Ubuntu machine with the cheapest plan (5$) for a start. This will give you a vanilla server to start with.</p>
<p>You could've also chosen some pre-built images from the Marketplace, then you wouldn't need to manually configure your server (discussed below). So for example, if you're hosting a WordPress website, you could have chosen that and the newly created server would come with Wordpress installed with all the necessary things configured.</p>
<p><em>But, we are learners, we don't want to automate things for us, because there is no learning in that case. So, don't use Marketplace images for now.</em></p>
<p><strong>What is SSH?</strong></p>
<p>Now that you have created your first remote computer, you have to access it using SSH (Secure Shell Protocol). In simple terms, SSH uses a cryptographic network protocol to securely connect you to a remote computer, from where you can access the computer through a terminal.</p>
<p><strong>Let's connect</strong></p>
<p>Now, let us see  <a target="_blank" href="https://docs.digitalocean.com/products/droplets/how-to/connect-with-ssh/openssh/">how to connect to your first droplet using SSH.</a>.</p>
<p>Well done! You're connected to your remote computer/server. Now it's time to <a target="_blank" href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04">configure your server</a>. Yes, a server needs some basic configuration to start with.</p>
<p>Okay, you have a server set up properly. Now, you have to install the necessary software to run your web application. For example, if you want to run a Python application, you have to install Python and the necessary packages. </p>
<p>But till now, you have hosted your application in <em>localhost</em> using a development server. Now, you're on an actual remote server and want the whole world to see your app (or maybe not the world, just you, so that you can test), so there are some changes on how to deploy your application. </p>
<p>I will provide you with some documentation of how to deploy your applications in DigitalOcean. I suggest digging into these articles only after completing this article of mine. Although these are written by DigitalOcean people, you can use these docs to deploy your apps to any server having any providers:</p>
<ol>
<li><a target="_blank" href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-18-04">How To Set Up a Node.js Application for Production on Ubuntu 18.04</a> </li>
<li><a target="_blank" href="https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04">How To Serve Flask Applications with Gunicorn and Nginx on Ubuntu 18.04</a></li>
<li><a target="_blank" href="https://www.digitalocean.com/community/tutorials/how-to-deploy-a-react-application-with-nginx-on-ubuntu-20-04">How To Deploy a React Application with Nginx on Ubuntu 20.04</a> </li>
</ol>
<p><em>Don't forget to praise DigitalOcean's nicely explained documentations.</em></p>
<h2 id="server-networking-101">Server networking 101</h2>
<p>The above documentations seems nice, but as a learner, you have to be familiar with some basic server networking terminologies.</p>
<h3 id="localhost">localhost</h3>
<p>Localhost, simply accessed by the URL <code>localhost</code> or <code>127.0.0.1</code>, is a hostname that refers to 'this' computer's network. By this, I mean the current computer I'm working with. It's useful to test different applications because the data is not sent over the internet, instead, all the data stays on the computer. In this case, your computer gets a simulated web server where you can load the necessary files of a program into the web servers and check its functionality.</p>
<p>Please note, the idea of referring to your own computer's virtual server while accessing <code>localhost</code>, is called the <em>loopback</em> mechanism.</p>
<p><em>But, did you know, if you host an application in your localhost, people connected to the same network can easily access your application? How?</em></p>
<p>In a private network (like connecting to a Wifi Router), your computer will have its own private IP address. As you're already on a network, other users should be able to access your computer if they know the IP address. By access, I mean several things. For example, users on the same network can <code>ssh</code> into your computer. Also, they can access hosted applications (like your web application).</p>
<p>What <code>localhost</code> or <code>127.0.0.1</code> basically does, it points to your own computer. For all OS, localhost is a standard to create a loopback address. </p>
<p>Let's say, your private IP address is <code>192.168.30.5</code>. You're serving Node.js application on port 5000, so in your own computer, you would access it as <code>localhost:5000</code> or <code>127.0.0.1:5000</code>. Now, if another user on the same network wants to access your application, he has to visit <code>192.168.30.5:5000</code>. That's it. Beware, Your application is not available to the public internet, after all, you're in a <em>private network</em>.</p>
<p>To find your IP address, in Windows, type <code>ipconfig</code> in the command prompt. For Linux, generally, it is <code>ip addr show</code>. From the list, you have to find your Wifi Adapter and get the <em>IPv4</em> address that starts with <code>192.168.x.x</code>.</p>
<h3 id="ports">ports</h3>
<p>At the software level, a port is a logical construct that refers to a specific process running on the server. The ports starting from <code>0</code> to <code>1023</code> is reserved by the operating system. For own use cases, the common port range is <code>3000</code> and upwards. For a specific web application, the port is specified at the end of the IP address, using a colon:</p>
<pre><code>127<span class="hljs-selector-class">.0</span><span class="hljs-selector-class">.0</span><span class="hljs-selector-class">.1</span><span class="hljs-selector-pseudo">:5000</span>
</code></pre><p>In the above example, the port number is <code>5000</code>. The server which is listening to <code>5000</code> will get the request. When the server is active (listening), port <code>5000</code> will be blocked and no other process can use it.</p>
<p>You can run multiple web applications in one machine by using different port address. Let's say you have a Node.js API running on PORT <code>5000</code>, Frontend running on PORT <code>5001</code> and database service is running on PORT <code>27017</code>. Assuming your droplet's IP address is <code>10.220.20.23</code>, you can access those as:</p>
<pre><code><span class="hljs-attribute">10</span>.<span class="hljs-number">220</span>.<span class="hljs-number">20</span>.<span class="hljs-number">23</span>:<span class="hljs-number">5000</span> // API
<span class="hljs-attribute">10</span>.<span class="hljs-number">220</span>.<span class="hljs-number">20</span>.<span class="hljs-number">23</span>:<span class="hljs-number">5001</span> // Frontend
<span class="hljs-attribute">10</span>.<span class="hljs-number">220</span>.<span class="hljs-number">20</span>.<span class="hljs-number">23</span>:<span class="hljs-number">27017</span> // database
</code></pre><h3 id="127001-vs-0000">127.0.0.1 vs 0.0.0.0</h3>
<p>Based on previous discussions, you already know what <code>localhost</code> or <code>127.0.0.1</code> is. When deploying your application, you might also need to use the address <code>0.0.0.0</code> in your server config. In the context of servers, <code>0.0.0.0</code> means all IPv4 addresses on the local machine. If a host has two IP addresses, <code>192.168.1.1</code> and <code>10.1.2.1</code>, and a server running on the host listens on <code>0.0.0.0</code>, it will be reachable at both of those IPs.</p>
<h3 id="what-are-nginx-and-apache">What are Nginx and Apache?</h3>
<p>To process incoming connections from the outside world (the public internet), you need a web server.</p>
<ul>
<li>A web server knows how to talk to the internet using HTTP and HTTPS network protocols</li>
<li>It can route requests to different services based on the request type (fancy name is <em>Reverse Proxy</em>). You might have the backend API and frontend hosted on the same machine. Nginx/Apache can redirect API/backend requests to API service and frontend requests to frontend service</li>
<li>Helps you set up domain names</li>
<li>Creating different rules for different URLs. For example, you might want to redirect users from 'oldsite.com' to 'newsite.com'.</li>
<li>Caching</li>
<li>SSL</li>
</ul>
<p>...and a lot of things.</p>
<p>Things that a web server like Nginx can do is outside the scope of this article. The above listed are the very basic things.</p>
<p>A web server is essential to run your web application. In a regular setup, you will always use nginx/apache to serve your application. Even if in some cases you're not using them directly, do know that it is being used in the top levels somewhere.</p>
<p><strong>Then what are Gunicorn and uWSGI in the Python world?</strong></p>
<p>Gunicorn or uWSGI are <em> <a target="_blank" href="https://en.wikipedia.org/wiki/Application_server">application servers</a> </em>. To talk to Python application we need  <a target="_blank" href="https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface">WSGI</a>.  Gunicorn and Nginx have WSGI implemented, where Nginx/Apache doesn't. Nginx/Apache is used for more general-purpose server works. Gunicorn or uWSGI works as a middleman between Nginx and the Python web application. </p>
<p>So, in a Python set-up, Nginx will be responsible for reverse proxying, caching, SSL, serving static files etc. While dynamic requests that should be handled by the Flask/Django application will be passed to Gunicorn/uWSGI. The interaction between these two are as follows:</p>
<ol>
<li>nginx receives the incoming request from the internet</li>
<li>Based on the Nginx config it can decide if this request needs to be passed to Gunicorn/uWSGI</li>
<li>Gunicorn passes the request to the Python application</li>
<li>The application sends back the result to Gunicorn after processing</li>
<li>Gunicorn sends back the result to Nginx</li>
<li>nginx replies to the user with the response</li>
</ol>
<p><strong>What if my user increases and I have to handle 1000 req/sec? The current deployment process is too lengthy and counter-productive, how do I automate it...?</strong></p>
<p>Woah! Slow down. We just scratched the surface here. Cloud deployment is a whole different topic on which you can do full-year courses. Nowadays, the sector is called DevOps and people working on DevOps are called DevOps Engineers. Also, Site Reliability Engineers (similar to DevOps but not identical). Once you're comfortable with the basics, you can do courses on DevOps and learn more. An interesting world awaits you.</p>
<h2 id="where-to-go-from-here">Where to go from here?</h2>
<p>Once you are confident that you understand the basics of server deployment, try these:</p>
<ul>
<li>Learn shell scripting. It's the most underrated tool for an Engineer working in the technical or IT sector. Whenever you want to automate something or add custom behavior you have to do shell scripting in Linux. Start learning from a  <a target="_blank" href="https://dev.to/godcrampy/the-missing-shell-scripting-crash-course-37mk">crash course here.</a> </li>
<li>Learn Docker. It's the most used deployment tool no matter where you go. For this, you can follow  <a target="_blank" href="https://www.udemy.com/course/docker-mastery/">Docker Mastery course in Udemy.</a> </li>
<li>Learn Jenkins. You can use  <a target="_blank" href="https://www.udemy.com/course/learn-devops-ci-cd-with-jenkins-using-pipelines-and-docker/">CI/CD Jenkins course from Udemy.</a></li>
<li>If you're really serious about DevOps and want to pursue your career in this role, you should also learn  <a target="_blank" href="https://www.udemy.com/course/learn-devops-the-complete-kubernetes-course/">Kubernetes</a>  </li>
</ul>
<p>That's it for today, folks. I will try to write more awesome articles for both beginners and advanced level users in the future. I will also share my technical experiences here. Stay tuned. If you like this article, please share it with your network. Thank you for reading this to the end.</p>
]]></content:encoded></item></channel></rss>