<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nguyen Dinh Khai</title>
    <description>The latest articles on DEV Community by Nguyen Dinh Khai (@dinhkhai0201).</description>
    <link>https://dev.to/dinhkhai0201</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1298242%2F3352d4c4-5387-4d12-aba9-43afdbca3358.jpeg</url>
      <title>DEV Community: Nguyen Dinh Khai</title>
      <link>https://dev.to/dinhkhai0201</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dinhkhai0201"/>
    <language>en</language>
    <item>
      <title>How the Event Loop Handles Microtasks and Macrotasks</title>
      <dc:creator>Nguyen Dinh Khai</dc:creator>
      <pubDate>Sun, 15 Sep 2024 13:36:15 +0000</pubDate>
      <link>https://dev.to/dinhkhai0201/how-the-event-loop-handles-microtasks-and-macrotasks-4hi7</link>
      <guid>https://dev.to/dinhkhai0201/how-the-event-loop-handles-microtasks-and-macrotasks-4hi7</guid>
      <description>&lt;p&gt;In JavaScript, microtasks and macrotasks are two types of asynchronous tasks that the event loop manages, but they are handled in different ways. Understanding how they work is crucial for predicting the execution order of asynchronous code.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Macrotask Queue (Task Queue)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Macrotasks are placed into their own queue, often referred to as the task queue or macrotask queue.&lt;/li&gt;
&lt;li&gt;Examples of macrotasks include: setTimeout, setInterval, I/O events, and DOM events (like click and load).&lt;/li&gt;
&lt;li&gt;The event loop takes each macrotask from this queue to execute, but only after all microtasks in the microtask queue have been processed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Microtask Queue
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Microtasks have their own queue called the microtask queue.&lt;/li&gt;
&lt;li&gt;Examples of microtasks include: .then() of Promise, MutationObserver.&lt;/li&gt;
&lt;li&gt;The microtask queue has a higher priority than the macrotask queue. After each macrotask is executed, the event loop will process all the microtasks in this queue before moving on to the next macrotask.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How the Event Loop Handles Microtasks and Macrotasks:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Event Loop starts a new cycle.&lt;/li&gt;
&lt;li&gt;Execute all synchronous code in the call stack.&lt;/li&gt;
&lt;li&gt;When the call stack is empty

&lt;ul&gt;
&lt;li&gt;Execute all microtasks in the microtask queue. If a microtask adds more microtasks, they will be executed immediately within the same cycle.&lt;/li&gt;
&lt;li&gt;Move to the first macrotask in the macrotask queue and execute it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Repeat this process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Macrotask 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Microtask inside Macrotask 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Macrotask 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;End&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
End
Microtask 1
Microtask 2
Macrotask 1
Macrotask 2

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Explanation:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;console.log('Start'): Executes immediately and prints "Start".&lt;/li&gt;
&lt;li&gt;setTimeout(..., 0) (Macrotask 1): Added to the macrotask queue.&lt;/li&gt;
&lt;li&gt;Promise.resolve().then(...) (Microtask 1): Added to the microtask queue.&lt;/li&gt;
&lt;li&gt;setTimeout(..., 0) (Macrotask 2): Added to the macrotask queue.&lt;/li&gt;
&lt;li&gt;Promise.resolve().then(...) (Microtask 2): Added to the microtask queue.&lt;/li&gt;
&lt;li&gt;console.log('End'): Executes immediately and prints "End".&lt;/li&gt;
&lt;li&gt;Microtasks: The event loop will process all microtasks in the microtask queue before processing any macrotasks:

&lt;ul&gt;
&lt;li&gt;Prints "Microtask 1".&lt;/li&gt;
&lt;li&gt;Prints "Microtask 2".&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Macrotasks:

&lt;ul&gt;
&lt;li&gt;Executes the first setTimeout(..., 0) (Macrotask 1), printing "Macrotask 1".&lt;/li&gt;
&lt;li&gt;Executes the second setTimeout(..., 0) (Macrotask 2), printing "Macrotask 2".&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Summary:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Microtasks and macrotasks are placed into two separate queues: the microtask queue and the macrotask queue.&lt;/li&gt;
&lt;li&gt;The microtask queue is processed before the macrotask queue in the event loop.&lt;/li&gt;
&lt;li&gt;After every macrotask, the event loop processes all microtasks in the microtask queue before moving to the next macrotask in the macrotask queue.&lt;/li&gt;
&lt;li&gt;This ensures that microtasks (e.g., Promise callbacks) have a higher priority and are executed sooner than macrotasks.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How the Event Loop Works</title>
      <dc:creator>Nguyen Dinh Khai</dc:creator>
      <pubDate>Sun, 15 Sep 2024 13:10:55 +0000</pubDate>
      <link>https://dev.to/dinhkhai0201/how-the-event-loop-works-2boi</link>
      <guid>https://dev.to/dinhkhai0201/how-the-event-loop-works-2boi</guid>
      <description>&lt;p&gt;The event loop in JavaScript is a fundamental concept that allows JavaScript to perform non-blocking operations, despite being single-threaded. It is responsible for handling asynchronous operations by managing the execution of multiple pieces of code over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Event Loop Works:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Call Stack: This is where your code gets pushed and executed. When a function is called, it gets added to the call stack, and when the function completes, it is removed (popped) from the stack. JavaScript executes code in the call stack synchronously (one at a time).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Web APIs: JavaScript in the browser environment provides APIs like setTimeout, fetch, DOM events, etc. These APIs handle time-consuming tasks asynchronously. When these tasks are invoked, they are executed outside the call stack by the browser.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Callback Queue (Task Queue): When asynchronous operations like setTimeout or fetch complete, their callbacks are pushed into the callback queue. This is a list of functions that are ready to be executed once the call stack is empty.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Event Loop: The event loop constantly monitors the call stack and the callback queue. If the call stack is empty, the event loop takes the first callback from the callback queue and pushes it onto the call stack for execution. This cycle repeats, allowing JavaScript to handle asynchronous tasks efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Please check this code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;One&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Three&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Two&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One
Two
Three

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Explanation:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;console.log('One')&lt;/code&gt; is executed first and added to the call stack, then removed after execution.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;setTimeout&lt;/code&gt; is called, which sets a timer for 1 second. Its callback is sent to the &lt;code&gt;Web API&lt;/code&gt;, not directly to the call stack.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;console.log('Two')&lt;/code&gt; is added to the call stack and executed next.&lt;/li&gt;
&lt;li&gt;After the 1-second timer finishes, the callback &lt;code&gt;(() =&amp;gt; { console.log('Three'); })&lt;/code&gt; is placed in the callback queue.&lt;/li&gt;
&lt;li&gt;The event loop checks the call stack, sees it's empty, and pushes the callback from the callback queue to the call stack.&lt;/li&gt;
&lt;li&gt;The callback is executed, printing &lt;code&gt;Three&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>eventloop</category>
    </item>
    <item>
      <title>How to install oh-my-zsh and zsh-autosuggestions for macbook</title>
      <dc:creator>Nguyen Dinh Khai</dc:creator>
      <pubDate>Tue, 09 Jul 2024 10:09:02 +0000</pubDate>
      <link>https://dev.to/dinhkhai0201/how-to-install-oh-my-zsh-and-zsh-autosuggestions-for-macbook-3f07</link>
      <guid>https://dev.to/dinhkhai0201/how-to-install-oh-my-zsh-and-zsh-autosuggestions-for-macbook-3f07</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flrqja4xg9vnzvkcp5dp7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flrqja4xg9vnzvkcp5dp7.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install oh-my-zsh via curl&lt;/strong&gt;&lt;/p&gt;

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

sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Add autocomplete plugin&lt;/strong&gt;&lt;/p&gt;

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

git clone https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting
git clone https://github.com/zsh-users/zsh-completions.git ~/.oh-my-zsh/custom/plugins/zsh-completions
git clone https://github.com/zsh-users/zsh-history-substring-search.git ~/.oh-my-zsh/custom/plugins/zsh-history-substring-search


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Open .zshrc and paste those code at the end of the file&lt;/strong&gt;&lt;/p&gt;

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

# Terminal autocomplete fix
autoload -Uz compinit &amp;amp;&amp;amp; compinit

plugins=(
    git
    docker
    asdf
    zsh-autosuggestions
    zsh-completions 
    zsh-history-substring-search 
    zsh-syntax-highlighting
)
source /PATH/TO/zsh-autosuggestions/zsh-autosuggestions.zsh
source /PATH/TO/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh


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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Change &lt;code&gt;/PATH/TO&lt;/code&gt; with the path to &lt;code&gt;zsh-autosuggestions&lt;/code&gt; and &lt;code&gt;zsh-syntax-highlighting&lt;/code&gt; in your local macbook&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Done :D&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>macbook</category>
      <category>development</category>
      <category>zsh</category>
    </item>
    <item>
      <title>Module not found: Can't resolve 'pino-pretty'</title>
      <dc:creator>Nguyen Dinh Khai</dc:creator>
      <pubDate>Tue, 07 May 2024 02:59:40 +0000</pubDate>
      <link>https://dev.to/dinhkhai0201/module-not-found-cant-resolve-pino-pretty-g6</link>
      <guid>https://dev.to/dinhkhai0201/module-not-found-cant-resolve-pino-pretty-g6</guid>
      <description>&lt;p&gt;Here's a simple way to fix the "Module not found: Can't resolve 'pino-pretty'" and "Module not found: Can't resolve 'encoding'" errors in your NextJS or ReactJS project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your next.config.js file in the root folder of your project.&lt;/li&gt;
&lt;li&gt;Add this line config.externals.push('pino-pretty', 'encoding');
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  webpack: (config) =&amp;gt; {
    config.resolve.fallback = { fs: false, net: false, tls: false };
    config.externals.push('pino-pretty', 'encoding');
    return config;
  },
};

module.exports = nextConfig;

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

&lt;/div&gt;



</description>
      <category>nextjs</category>
      <category>webpack</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Load Balancing with Docker Compose + Nginx + Nestjs</title>
      <dc:creator>Nguyen Dinh Khai</dc:creator>
      <pubDate>Thu, 25 Apr 2024 09:31:43 +0000</pubDate>
      <link>https://dev.to/dinhkhai0201/load-balancing-with-docker-compose-nginx-nestjs-220p</link>
      <guid>https://dev.to/dinhkhai0201/load-balancing-with-docker-compose-nginx-nestjs-220p</guid>
      <description>&lt;p&gt;Hello everyone.&lt;br&gt;
It's possible that you have encountered cases where your server is overloaded, laggy, and unable to process incoming requests.&lt;br&gt;
And when you face that case, there are several ways to address this issue, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Option 1: Identify the root cause of the code causing the error.&lt;/li&gt;
&lt;li&gt;Option 2: Increase server capacity.&lt;/li&gt;
&lt;li&gt;Option 3: Use Docker + Nginx to create load balancing to distribute incoming requests.&lt;/li&gt;
&lt;li&gt;etc,...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today, I will introduce how to implement Option 3. The technologies I am using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NestJS&lt;/li&gt;
&lt;li&gt;Docker: Nginx, PM2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1. Create a simple NestJs source code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
Please make sure that Node.js (version &amp;gt;= 16) is installed on your operating system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;br&gt;
Setting up a new project is quite simple with the Nest CLI. With npm installed, you can create a new Nest project with the following commands in your OS terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g @nestjs/cli
nest new load-balance-with-docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqrslmlnm3xzi5jerjcrx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqrslmlnm3xzi5jerjcrx.png" alt="Image description" width="595" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6q9gxfyzq4vpq1t5dd5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6q9gxfyzq4vpq1t5dd5p.png" alt="Image description" width="582" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then go to the source code folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd load-balance-with-docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you have a structure folder like the picture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz716xyn5lxhlmjojsta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz716xyn5lxhlmjojsta.png" alt="Image description" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Docker configuration **&lt;br&gt;
**Prerequisites&lt;/strong&gt;&lt;br&gt;
Install docker for your device: &lt;a href="https://docs.docker.com/engine/install/"&gt;https://docs.docker.com/engine/install/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to configure 3 parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nginx&lt;/li&gt;
&lt;li&gt;Server&lt;/li&gt;
&lt;li&gt;Pm2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.1 Nginx&lt;/strong&gt;&lt;br&gt;
Create a root directory, create a new folder named &lt;code&gt;nginx&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0j80n9ai614ab3yp94r0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0j80n9ai614ab3yp94r0.png" alt="Image description" width="326" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a file named Dockerfile in the nginx directory as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# nginx/Dockerfile
FROM nginx:stable-alpine
COPY default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above configuration snippet is a Dockerfile to build a Docker image based on the nginx:stable-alpine image.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;FROM nginx:stable-alpine&lt;/code&gt;: This line identifies the base image that the new image will be based on, in this case nginx:stable-alpine. Image nginx:stable-alpine is a stable version of Nginx on Alpine Linux.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;COPY default.conf /etc/nginx/conf.d/default.conf&lt;/code&gt;: This line copies the default.conf file to the /etc/nginx/conf.d/default.conf path in the image. The default.conf file contains the Nginx configuration that will be used when the container is launched.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;EXPOSE 80&lt;/code&gt;: This line specifies that the container will listen on port 80. However, using EXPOSE does not open the port on the host machine, it is just an instruction telling others which port the container will listen on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;CMD ["nginx", "-g", "daemon off;"]&lt;/code&gt;: This line defines the command that the container will execute when launched. In this case, the container will run the command nginx -g 'daemon off;' to start Nginx in non-daemon mode so that the container does not exit immediately after starting Nginx.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then create a default.conf file in the nginx directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# nginx/default.conf
upstream my-loadbalancer {
    server my-loadbalancer:3000;    
}

server {
    listen 80;

    location / {
        proxy_pass http://my-loadbalancer/;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;upstream my-loadbalancer { server my-loadbalancer:3000; }&lt;/code&gt;: This snippet defines a group of servers (upstream) named "my-loadbalancer". In this case, there is only one back-end server running on port 3000.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;server { listen 80; ... }&lt;/code&gt;: This is the configuration for an Nginx server. It listens on port 80 to handle incoming HTTP requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;location / { proxy_pass http://my-loadbalancer/; }&lt;/code&gt;: This section defines a default location for all requests. It uses proxy_pass to redirect all requests to the upstream "backend". This allows Nginx to act as a proxy and redirect requests to the back-end server running on port 3000.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.2 Server&lt;/strong&gt;&lt;br&gt;
In the main directory, create a Dockerfile file for the server as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Use node:18 image
FROM node:18.0.0

# Set working directory
WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm install

# Copy source code
COPY . .

# Build app
RUN npm run build

# Install PM2 globally
RUN npm install pm2 -g

# Set environment variables
ENV PORT 3000

# Expose port
EXPOSE $PORT

# Start app
CMD ["pm2-runtime", "start", "ecosystem.config.js"]


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

&lt;/div&gt;



&lt;p&gt;Then create a docker-compose.yml file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '1'

services:
  nginx: 
    build: ./nginx
    ports:
      - "80:80"
    depends_on: 
      - my-loadbalancer
  my-loadbalancer:
    build: .
    environment:
      - PORT=3000 
    deploy:
      replicas: 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above configuration is a docker-compose file used to define and run services in a Docker environment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It first defines two services: nginx and my-loadbalancer.&lt;/li&gt;
&lt;li&gt;The nginx service is built from the ./nginx directory and exposes port 80 on the host and container.&lt;/li&gt;
&lt;li&gt;The nginx service also depends on the my-loadbalancer service before starting.&lt;/li&gt;
&lt;li&gt;The my-loadbalancer service is built from the current directory (the directory containing the docker-compose file) and sets the environment variable PORT=3000.&lt;/li&gt;
&lt;li&gt;Finally, the my-loadbalancer service is deployed with 4 replicas to create a load-balanced environment. You can change the number of replicas với sự tương thích của máy chủ server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.3 Pm2&lt;/strong&gt;&lt;br&gt;
Create a file &lt;code&gt;ecosystem.config.js&lt;/code&gt; in the root directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    apps: [{
      name: 'my-loadbalancer',
      script: 'dist/main.js',
      instances: 'max',
      autorestart: true,
      watch: false,
      max_memory_restart: '1G',
    }]
  };

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Done&lt;/strong&gt;&lt;br&gt;
Finally, to run the server, you can use the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxcnlv0690y4si2pzaj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxcnlv0690y4si2pzaj0.png" alt="Image description" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you can check the containers by &lt;code&gt;docker ps&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fku4w5eb9ycwv7itwngxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fku4w5eb9ycwv7itwngxx.png" alt="Image description" width="800" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally you can access the server at the url: &lt;a href="http://localhost:80"&gt;http://localhost:80&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b2jr2kpfjml9jw2gcam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b2jr2kpfjml9jw2gcam.png" alt="Image description" width="684" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check the stats of containers with the &lt;code&gt;docker stats&lt;/code&gt; command&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fihbyq9o7j1yhpvoyun8x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fihbyq9o7j1yhpvoyun8x.png" alt="Image description" width="800" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find the source code &lt;a href="https://github.com/DinhKhai0201/load-balancing-docker-nginx-nestjs-simple"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for reading. &lt;/p&gt;

</description>
      <category>docker</category>
      <category>loadbalance</category>
      <category>nginx</category>
      <category>nestjs</category>
    </item>
    <item>
      <title>Fix Code helper plugin(visual studio code) leak memory Macbook</title>
      <dc:creator>Nguyen Dinh Khai</dc:creator>
      <pubDate>Tue, 02 Apr 2024 07:37:31 +0000</pubDate>
      <link>https://dev.to/dinhkhai0201/fix-code-helper-pluginvisual-studio-code-leak-memory-macbook-8nf</link>
      <guid>https://dev.to/dinhkhai0201/fix-code-helper-pluginvisual-studio-code-leak-memory-macbook-8nf</guid>
      <description>&lt;p&gt;When you work with VSC for a long time, it will consume a lot of RAM, hindering your work process and making your computer sluggish. &lt;br&gt;
Here's how you can address that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open svcode &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0fy5sze5i14arperxomx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0fy5sze5i14arperxomx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Press the keyboard shortcut &lt;code&gt;Command + Shift + D&lt;/code&gt;and select &lt;code&gt;Preferences: Open user settings (JSON)&lt;/code&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1khdh13c1fw9lvwk8ny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1khdh13c1fw9lvwk8ny.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3.Add extra setting in &lt;code&gt;settings.json&lt;/code&gt;&lt;/p&gt;

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

{
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/CVS": true,
        "**/.DS_Store": true,
        "**/tmp": true,
        "**/node_modules": true,
        "**/bower_components": true,
        "**/dist": true
    },
    "files.watcherExclude": {
        "**/.git/objects/**": true,
        "**/.git/subtree-cache/**": true,
        "**/node_modules/**": true,
        "**/tmp/**": true,
        "**/bower_components/**": true,
        "**/dist/**": true
    }
}


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Restart the vs code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ivmsm80vsb9pnmj25fy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ivmsm80vsb9pnmj25fy.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It reduces from 1.2 GB to 100 MB of RAM. Sounds great!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>vscode</category>
      <category>memory</category>
    </item>
    <item>
      <title>Pick, Omit and Partial in Typescript</title>
      <dc:creator>Nguyen Dinh Khai</dc:creator>
      <pubDate>Sat, 24 Feb 2024 08:50:08 +0000</pubDate>
      <link>https://dev.to/dinhkhai0201/pick-omit-and-partial-in-typescript-b7b</link>
      <guid>https://dev.to/dinhkhai0201/pick-omit-and-partial-in-typescript-b7b</guid>
      <description>&lt;p&gt;A. Pick&lt;br&gt;
Use pick to create a new type from a previous type with only a few necessary keys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface User {
  name: string;
  age: number;
}

type PickUser = Omit&amp;lt;User, 'name'&amp;gt;;

// Resut
type PickUser = {
    name: string;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;B. Omit&lt;br&gt;
While Pick is handy, there are occasions when the inverse operation is required. We may need to construct a type that includes everything except a few fields from a preceding type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface User {
  name: string;
  age: number;
}

type OmitUser = Omit&amp;lt;User, 'name'&amp;gt;;

// Resut
type OmitUser = {
    age: number;
};

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

&lt;/div&gt;



&lt;p&gt;C. Partial&lt;br&gt;
This utility type facilitates swift creation of a type with optional or undefined properties based on an existing type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface User {
  name: string;
  age: number;
}

type PartialUser = Partial&amp;lt;User&amp;gt;;

// Resut
type PartialUser = {
    name?: string | undefined;
    age?: number | undefined;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
