<?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: Deepal Jayasekara</title>
    <description>The latest articles on DEV Community by Deepal Jayasekara (@deepal).</description>
    <link>https://dev.to/deepal</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%2F168130%2Ffead3985-3ad0-46e6-941e-6222f824c138.JPG</url>
      <title>DEV Community: Deepal Jayasekara</title>
      <link>https://dev.to/deepal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deepal"/>
    <language>en</language>
    <item>
      <title>How Not To Measure Time in Programming</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Sat, 12 Mar 2022 00:02:54 +0000</pubDate>
      <link>https://dev.to/deepal/how-not-to-measure-time-in-programming-aka-how-the-likes-of-datenow-will-ruin-your-metrics-4n2k</link>
      <guid>https://dev.to/deepal/how-not-to-measure-time-in-programming-aka-how-the-likes-of-datenow-will-ruin-your-metrics-4n2k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;a.k.a. how the likes of Date.now() will ruin your metrics.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://blog.insiderattack.net/how-not-to-measure-time-in-programming-11089d546180?source=rss----57f0c4748c10---4"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bDFoCnST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2Ai2YWFiBfzqKfmo_k3V8RxQ.jpeg" alt="" width="880" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you fly between two airports that are in two different time zones, would you calculate the time it took for you to fly, by checking the difference between the ‘wall clock’ times of either airport?&lt;/p&gt;

&lt;p&gt;If your answer is ‘no’, then let me explain why you shouldn’t do the same in your code, using a little but a very interesting experiment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.insiderattack.net/how-not-to-measure-time-in-programming-11089d546180?source=rss----57f0c4748c10---4"&gt;Continue reading on Deepal’s Blog »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>monitoring</category>
      <category>performance</category>
    </item>
    <item>
      <title>Atomic Microservices Transactions with MongoDB Transactional Outbox</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Thu, 17 Feb 2022 00:23:54 +0000</pubDate>
      <link>https://dev.to/deepal/atomic-microservices-transactions-with-mongodb-transactional-outbox-2ba7</link>
      <guid>https://dev.to/deepal/atomic-microservices-transactions-with-mongodb-transactional-outbox-2ba7</guid>
      <description>&lt;p&gt;&lt;a href="https://blog.insiderattack.net/atomic-microservices-transactions-with-mongodb-transactional-outbox-1c96e0522e7c?source=rss----57f0c4748c10---4"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UQbiGI5Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2AP6QjGN3OhhVWYCGy8BiJ_A.jpeg" alt="" width="880" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Atomic Transactions with Polled Outbox&lt;/p&gt;

&lt;p&gt;One of the drawbacks of the microservices architecture is the difficulty to implement atomic transactions. While this limitation can be overcome by using patterns such as Saga, there are certain situations where we can use an alternative approach to solve this problem without having to implement the rather complicated Saga pattern.&lt;/p&gt;

&lt;p&gt;Let’s consider a scenario where we need to dispatch an event when a user verifies their email after signing up. The event will then be consumed by other services for reporting, updating the customer profile on a CRM system and sending a customer a welcome email.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.insiderattack.net/atomic-microservices-transactions-with-mongodb-transactional-outbox-1c96e0522e7c?source=rss----57f0c4748c10---4"&gt;Continue reading on Deepal’s Blog »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>systemdesignintervie</category>
      <category>architecture</category>
      <category>database</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Use Streams to Build High-Performing Node.js Applications</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Wed, 09 Feb 2022 13:33:20 +0000</pubDate>
      <link>https://dev.to/appsignal/use-streams-to-build-high-performing-nodejs-applications-1lba</link>
      <guid>https://dev.to/appsignal/use-streams-to-build-high-performing-nodejs-applications-1lba</guid>
      <description>&lt;p&gt;The moment you type something on a keyboard, read a file from a disk or download a file over the internet, a stream of information (bits) flows through different devices and applications.&lt;/p&gt;

&lt;p&gt;If you learn to work with these streams of bits, you'll be able to build performant and valuable applications. For example, think of when you watch a video on YouTube. You don't have to wait until the full video downloads. Once a small amount buffers, it starts to play, and the rest keeps on downloading as you watch.&lt;/p&gt;

&lt;p&gt;Node.js includes a built-in module called &lt;code&gt;stream&lt;/code&gt; which lets us work with streaming data. In this article, we will explain how you can use the &lt;code&gt;stream&lt;/code&gt; module with some simple examples. We'll also describe how you can build pipelines gluing different streams together to build performant applications for complex use cases.&lt;/p&gt;

&lt;p&gt;Before we dive into building applications, it's important to understand the features provided by the Node.js &lt;code&gt;stream&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;Let's get going!&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Node.js Streams
&lt;/h2&gt;

&lt;p&gt;Node.js &lt;code&gt;streams&lt;/code&gt; provides four types of streams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Readable Streams&lt;/li&gt;
&lt;li&gt;Writable Streams&lt;/li&gt;
&lt;li&gt;Duplex Streams&lt;/li&gt;
&lt;li&gt;Transform Streams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://nodejs.org/api/stream.html#stream_types_of_streams"&gt;See the official Node.js docs for more detail on the types of streams&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's look at each stream type at a high level.&lt;/p&gt;

&lt;h3&gt;
  
  
  Readable Streams
&lt;/h3&gt;

&lt;p&gt;A readable stream can read data from a particular data source, most commonly, from a file system. Other common uses of readable streams in Node.js applications are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;process.stdin&lt;/code&gt; - To read user input via &lt;code&gt;stdin&lt;/code&gt; in a terminal application.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;http.IncomingMessage&lt;/code&gt; - To read an incoming request's content in an HTTP server or to read the server HTTP response in an HTTP client.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Writable Streams
&lt;/h3&gt;

&lt;p&gt;You use writable streams to write data from an application to a specific destination, for example, a file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;process.stdout&lt;/code&gt; can be used to write data to standard output and is used internally by &lt;code&gt;console.log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next up are duplex and transform streams, which you can define as 'hybrid' stream types built on readable and writable streams.&lt;/p&gt;

&lt;h3&gt;
  
  
  Duplex Streams
&lt;/h3&gt;

&lt;p&gt;A duplex stream is a combination of both readable and writable streams. It provides the capability to write data to a particular destination and read data from a source. The most common example of a duplex stream is &lt;code&gt;net.Socket&lt;/code&gt;, used to read and write data to and from a socket.&lt;/p&gt;

&lt;p&gt;It's important to know that readable and writable sides operate independently from one another in a duplex stream. The data does not flow from one side to the other.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transform Streams
&lt;/h3&gt;

&lt;p&gt;A transform stream is slightly similar to a duplex stream, but the readable side is connected to the writable side in a transform stream.&lt;/p&gt;

&lt;p&gt;A good example would be the &lt;code&gt;crypto.Cipher&lt;/code&gt; class which implements an encryption stream. Using a &lt;code&gt;crypto.Cipher&lt;/code&gt; stream, an application can write plain text data into the writable side of a stream and read encrypted ciphertext out of the readable side of the stream. The transformative nature of this type of stream is why they are called 'transform streams'.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side-note&lt;/strong&gt;: Another transform stream is &lt;code&gt;stream.PassThrough&lt;/code&gt;, which passes data from the writable side to the readable side without any transformation. Though this might sound trivial, Passthrough streams are very useful for building custom stream implementations and pipelines (e.g., creating multiple copies of one stream's data).&lt;/p&gt;

&lt;h2&gt;
  
  
  Read Data From Readable Node.js Streams
&lt;/h2&gt;

&lt;p&gt;Once a readable stream is 'connected' to a source that generates data (e.g., a file), there are a few ways to read data through the stream.&lt;/p&gt;

&lt;p&gt;First, let's create a sample text file named &lt;code&gt;myfile&lt;/code&gt;, with 85 bytes of 'lorem ipsum' text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur nec mauris turpis.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's look at two different methods of reading data from a readable stream.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Listen to 'data' Events
&lt;/h3&gt;

&lt;p&gt;The most common way to read data from a readable stream is by listening to &lt;code&gt;'data'&lt;/code&gt; events emitted by the stream. The following program demonstrates this approach:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;readable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./myfile&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="na"&gt;highWaterMark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Read &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bytes\n"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;"\n`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;highWaterMark&lt;/code&gt; property, passed as an option to &lt;code&gt;fs.createReadStream&lt;/code&gt;, determines how much data buffers inside the stream. The data is then flushed to the reading mechanism (in this case, our &lt;code&gt;data&lt;/code&gt; handler). By default, readable &lt;code&gt;fs&lt;/code&gt; streams have their &lt;code&gt;highWaterMark&lt;/code&gt; set to 64kB. We deliberately override this to 20 bytes to trigger multiple &lt;code&gt;data&lt;/code&gt; events.&lt;/p&gt;

&lt;p&gt;If you run the above program, it will read 85 bytes from &lt;code&gt;myfile&lt;/code&gt; in five iterations. You will see the following output in the console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read 20 bytes
"Lorem ipsum dolor si"

Read 20 bytes
"t amet, consectetur "

Read 20 bytes
"adipiscing elit. Cur"

Read 20 bytes
"abitur nec mauris tu"

Read 5 bytes
"rpis."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Use Async Iterators
&lt;/h3&gt;

&lt;p&gt;An alternative way of reading data from a readable stream is by using async iterators:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;readable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./myfile&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="na"&gt;highWaterMark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Read &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bytes\n"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;"\n`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run this program, you will get the same output as the previous example.&lt;/p&gt;

&lt;h2&gt;
  
  
  State of a Readable Node.js Stream
&lt;/h2&gt;

&lt;p&gt;When a listener is attached to a readable stream's &lt;code&gt;'data'&lt;/code&gt; events, the stream switches to a 'flowing' state (unless it is explicitly paused). You can inspect the stream's flowing state using the stream object's &lt;code&gt;readableFlowing&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;We can demonstrate this using a slightly modified version of our previous example with the &lt;code&gt;'data'&lt;/code&gt; handler:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;readable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./myfile&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="na"&gt;highWaterMark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bytesRead&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s2"&gt;`before attaching 'data' handler. is flowing: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readableFlowing&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Read &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bytes`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;bytesRead&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Pause the readable stream after reading 60 bytes from it.&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bytesRead&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pause&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`after pause() call. is flowing: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readableFlowing&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// resume the stream after waiting for 1s.&lt;/span&gt;
    &lt;span class="nx"&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;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s2"&gt;`after resume() call. is flowing: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readableFlowing&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s2"&gt;`after attaching 'data' handler. is flowing: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;readable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readableFlowing&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we read from &lt;code&gt;myfile&lt;/code&gt; via a readable stream, but we temporarily 'pause' the data flow for 1s after reading 60 bytes from the file. We also log the value of the &lt;code&gt;readableFlowing&lt;/code&gt; property at different times to understand how it changes.&lt;/p&gt;

&lt;p&gt;If you run the above program, you will get the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before attaching 'data' handler. is flowing: null
after attaching 'data' handler. is flowing: true
Read 20 bytes
Read 20 bytes
Read 20 bytes
after pause() call. is flowing: false
after resume() call. is flowing: true
Read 20 bytes
Read 5 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can explain the output as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When our program starts, &lt;code&gt;readableFlowing&lt;/code&gt; has the value &lt;code&gt;null&lt;/code&gt; because we don't provide any mechanism of consuming from the stream.&lt;/li&gt;
&lt;li&gt;After the 'data' handler is attached, the readable stream changes to 'flowing' mode, and &lt;code&gt;readableFlowing&lt;/code&gt; changes to &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Once 60 bytes are read, the stream is 'paused' by calling &lt;code&gt;pause()&lt;/code&gt;, which, in turn, changes &lt;code&gt;readableFlowing&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;After waiting for 1s, the stream switches to 'flowing' mode again by calling &lt;code&gt;resume()&lt;/code&gt;, changing &lt;code&gt;readableFlowing&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;. The rest of the file content then flows through the stream.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Processing Large Amounts of Data with Node.js Streams
&lt;/h2&gt;

&lt;p&gt;Thanks to streams, applications do not have to keep large blobs of information in memory: small chunks of data can be processed as they are received.&lt;/p&gt;

&lt;p&gt;In this section, let's combine different streams to build a real-life application that can handle large amounts of data. We'll use a small utility program that generates an SHA-256 of a given file.&lt;/p&gt;

&lt;p&gt;But first, let's create a large 4GB dummy file for testing. You can do this using a small shell command, as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On macOS: &lt;code&gt;mkfile -n 4g 4gb_file&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;On Linux: &lt;code&gt;xfs_mkfile 4096m 4gb_file&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After creating our dummy &lt;code&gt;4gb_file&lt;/code&gt;, let's generate the SHA-256 hash of the file without using the &lt;code&gt;stream&lt;/code&gt; module:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./4gb_file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;readErr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;readErr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;readErr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./checksum.txt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;writeErr&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;writeErr&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run the above code, you may get the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RangeError [ERR_FS_FILE_TOO_LARGE]: File size (4294967296) is greater than 2 GB
at FSReqCallback.readFileAfterStat [as oncomplete] (fs.js:294:11) {
code: 'ERR_FS_FILE_TOO_LARGE'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above error occurs because the JavaScript runtime cannot handle arbitrarily large buffers. The max size of a buffer that the runtime can handle depends on your operating system architecture. You can check this by using the &lt;a href="https://nodejs.org/api/buffer.html#bufferconstantsmax_length"&gt;&lt;code&gt;buffer.constants.MAX_LENGTH&lt;/code&gt;&lt;/a&gt; variable in the built-in &lt;code&gt;buffer&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;Even if we didn't see the above error, keeping large files in memory is problematic. The physical memory we have available will restrict the amount of memory our application can use. High memory usage can also cause poor application performance in terms of CPU usage, as garbage collection becomes expensive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reduce Your App's Memory Footprint Using &lt;code&gt;pipeline()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Now, let's look at how we can modify our application to use streams and avoid encountering this error:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stream&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hashStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;hashStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setEncoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./4gb_file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;outputStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createWriteStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./checksum.txt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hashStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;outputStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we use the streaming approach provided by the &lt;code&gt;crypto.createHash&lt;/code&gt; function. It returns a "transform stream" object &lt;code&gt;hashStream&lt;/code&gt;, generating hashes for arbitrarily large files.&lt;/p&gt;

&lt;p&gt;To feed the file content into this transform stream, we have created a readable stream — &lt;code&gt;inputStream&lt;/code&gt; — to &lt;code&gt;4gb_file&lt;/code&gt; using &lt;code&gt;fs.createReadStream&lt;/code&gt;. We pipe the output from the &lt;code&gt;hashStream&lt;/code&gt; transform stream to the writable &lt;code&gt;outputStream&lt;/code&gt; and the &lt;code&gt;checksum.txt&lt;/code&gt;, created using &lt;code&gt;fs.createWriteStream&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you run the above application, you will see that the &lt;code&gt;checksum.txt&lt;/code&gt; file populates with the SHA-256 hash of our 4GB file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;pipeline()&lt;/code&gt; vs &lt;code&gt;pipe()&lt;/code&gt; for Streams
&lt;/h3&gt;

&lt;p&gt;In our previous example, we used the &lt;code&gt;pipeline&lt;/code&gt; function to connect multiple streams. An alternative common approach is to use the &lt;code&gt;.pipe()&lt;/code&gt; function, as shown 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;inputStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hashStream&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outputStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, using &lt;code&gt;.pipe()&lt;/code&gt; in production applications is not recommended for several reasons. If one of the piped streams is closed or throws an error, &lt;code&gt;pipe()&lt;/code&gt; will not automatically destroy the connected streams. This can cause memory leaks in applications. Also, &lt;code&gt;pipe()&lt;/code&gt; does not automatically forward errors across streams to be handled in one place.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pipeline()&lt;/code&gt; was introduced to cater for these problems, so it's recommended you use &lt;code&gt;pipeline()&lt;/code&gt; instead of &lt;code&gt;pipe()&lt;/code&gt; to connect multiple streams. We can rewrite the above &lt;code&gt;pipe()&lt;/code&gt; example to use the &lt;code&gt;pipeline()&lt;/code&gt; function, as follows:&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;pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hashStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;outputStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pipeline()&lt;/code&gt; accepts a callback function as the last parameter. Any forwarded errors from any of the piped streams will call the callback, so it's easier to handle errors for all streams in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap Up: Reduce Memory and Improve Performance Using Node.js Streams
&lt;/h2&gt;

&lt;p&gt;Using streams in Node.js helps us build performant applications that can handle large amounts of data.&lt;/p&gt;

&lt;p&gt;In this article, we covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The four types of Node.js streams (readable, writable, duplex, and transform streams).&lt;/li&gt;
&lt;li&gt;How you can read data from readable Node.js streams by either listening to 'data' events or using async iterators.&lt;/li&gt;
&lt;li&gt;Reducing the memory footprint of your applications by using &lt;code&gt;pipeline&lt;/code&gt; to connect multiple streams.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A quick, small word of warning&lt;/strong&gt;: You likely won't encounter many situations where streams are a necessity, and a stream-based approach can increase the complexity of your application. Make sure you confirm that the benefits of using streams outweigh the complexity they'll bring.&lt;/p&gt;

&lt;p&gt;I'd encourage you to &lt;a href="https://nodejs.org/api/stream.html#stream"&gt;read the official Node.js &lt;code&gt;stream&lt;/code&gt; documentation&lt;/a&gt; to learn more and to explore more advanced use cases of streams out there.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;P.P.S. If you need an APM for your Node.js app, go and &lt;a href="https://www.appsignal.com/nodejs"&gt;check out the AppSignal APM for Node.js&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>node</category>
    </item>
    <item>
      <title>Experimenting with HTTP/3 — How the Next Gen Web is being built on UDP</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Sat, 23 Oct 2021 23:32:57 +0000</pubDate>
      <link>https://dev.to/deepal/experimenting-with-http3-how-the-next-gen-web-is-being-built-on-udp-4b7l</link>
      <guid>https://dev.to/deepal/experimenting-with-http3-how-the-next-gen-web-is-being-built-on-udp-4b7l</guid>
      <description>&lt;p&gt;&lt;a href="https://blog.insiderattack.net/experimenting-with-http-3-how-the-next-gen-web-is-being-built-on-udp-ba01cb88a495?source=rss----57f0c4748c10---4"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YTYCH0Hw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2ADa2fCrxCSz11y4FT2aGo7A.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HTTP3 is fundamentally different from its predecessors we knew. It ditches TCP and is built upon a novel UDP based protocol, QUIC.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.insiderattack.net/experimenting-with-http-3-how-the-next-gen-web-is-being-built-on-udp-ba01cb88a495?source=rss----57f0c4748c10---4"&gt;Continue reading on Deepal’s Blog »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>http3</category>
      <category>web</category>
      <category>webdev</category>
      <category>networking</category>
    </item>
    <item>
      <title>Abusing Network Protocols for Secret Communication</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Wed, 18 Aug 2021 18:47:28 +0000</pubDate>
      <link>https://dev.to/deepal/abusing-network-protocols-for-secret-communication-2efh</link>
      <guid>https://dev.to/deepal/abusing-network-protocols-for-secret-communication-2efh</guid>
      <description>&lt;p&gt;&lt;a href="https://blog.insiderattack.net/abusing-network-protocols-for-secret-communication-7c96cbdfca61?source=rss----57f0c4748c10---4"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8TRFDBAD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2AZrXiAvbdj8TqAdYWacriyQ.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How to hide your communication in plain sight with Network Covert Channels&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.insiderattack.net/abusing-network-protocols-for-secret-communication-7c96cbdfca61?source=rss----57f0c4748c10---4"&gt;Continue reading on Deepal’s Blog »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>informationsecurity</category>
      <category>security</category>
      <category>hacking</category>
    </item>
    <item>
      <title>NodeJS Streams in Practice</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Sun, 25 Jul 2021 20:19:53 +0000</pubDate>
      <link>https://dev.to/deepal/nodejs-streams-in-practice-6e2</link>
      <guid>https://dev.to/deepal/nodejs-streams-in-practice-6e2</guid>
      <description>&lt;p&gt;&lt;a href="https://blog.insiderattack.net/nodejs-streams-in-practice-980b3cdf4511?source=rss----57f0c4748c10---4"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_vYCEtEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2Ats-xtQqKqzzigDErF3ZPQw.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Turbo boost your Node.js application with Streams&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.insiderattack.net/nodejs-streams-in-practice-980b3cdf4511?source=rss----57f0c4748c10---4"&gt;Continue reading on Deepal’s Blog »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>node</category>
    </item>
    <item>
      <title>Starting Your Own Tech Blog</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Mon, 28 Jun 2021 21:52:23 +0000</pubDate>
      <link>https://dev.to/deepal/starting-your-own-tech-blog-98a</link>
      <guid>https://dev.to/deepal/starting-your-own-tech-blog-98a</guid>
      <description>&lt;p&gt;&lt;a href="https://blog.insiderattack.net/starting-your-own-tech-blog-bbc663fca981?source=rss----57f0c4748c10---4"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5CkCyXG7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2AgZ3TAIQeHSndmsrtxEHosg.jpeg" alt="" width="880" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tips and tricks for building your technical writing portfolio&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.insiderattack.net/starting-your-own-tech-blog-bbc663fca981?source=rss----57f0c4748c10---4"&gt;Continue reading on Deepal’s Blog »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>writing</category>
      <category>blogging</category>
      <category>writingtips</category>
      <category>writer</category>
    </item>
    <item>
      <title>A Visual Guide to NodeJS Streams</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Thu, 10 Jun 2021 01:18:28 +0000</pubDate>
      <link>https://dev.to/deepal/a-visual-guide-to-nodejs-streams-2k11</link>
      <guid>https://dev.to/deepal/a-visual-guide-to-nodejs-streams-2k11</guid>
      <description>&lt;p&gt;&lt;a href="https://blog.insiderattack.net/a-visual-guide-to-nodejs-streams-9d2d594a9bf5?source=rss----57f0c4748c10---4"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ibRFZr-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2AEa9ZoWv5Qpa2OHDkqR7neA.jpeg" alt="" width="880" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In NodeJS, stream module provides the capability to work with streams. Even if you haven’t used stream module explicitly there are a lots…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.insiderattack.net/a-visual-guide-to-nodejs-streams-9d2d594a9bf5?source=rss----57f0c4748c10---4"&gt;Continue reading on Deepal’s Blog »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>nodejstutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Understanding Async Resources with Async Hooks</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Sun, 16 May 2021 19:37:56 +0000</pubDate>
      <link>https://dev.to/deepal/understanding-async-resources-with-async-hooks-18h1</link>
      <guid>https://dev.to/deepal/understanding-async-resources-with-async-hooks-18h1</guid>
      <description>&lt;p&gt;&lt;a href="https://blog.insiderattack.net/understanding-async-resources-with-async-hooks-3416de574f30?source=rss----57f0c4748c10---4"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Yi98t5RN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2AkXXx-kB0kYg3PJJwED97FA.jpeg" alt="" width="880" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Advanced NodeJS Internals — Part 3&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.insiderattack.net/understanding-async-resources-with-async-hooks-3416de574f30?source=rss----57f0c4748c10---4"&gt;Continue reading on Deepal’s Blog »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>asynchronous</category>
      <category>asynchooks</category>
    </item>
    <item>
      <title>JavaScript Event Loop vs Node JS Event Loop</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Sun, 16 Aug 2020 00:01:57 +0000</pubDate>
      <link>https://dev.to/deepal/javascript-event-loop-vs-node-js-event-loop-2450</link>
      <guid>https://dev.to/deepal/javascript-event-loop-vs-node-js-event-loop-2450</guid>
      <description>&lt;p&gt;&lt;a href="https://blog.insiderattack.net/javascript-event-loop-vs-node-js-event-loop-aea2b1b85f5c?source=rss----57f0c4748c10---4"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nz3S-KDH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2A7okAv8x_Rg-fRzt94MGS1Q.jpeg" alt="" width="880" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A guide to understanding the distinction between the event loop in browser and Node&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.insiderattack.net/javascript-event-loop-vs-node-js-event-loop-aea2b1b85f5c?source=rss----57f0c4748c10---4"&gt;Continue reading on Deepal’s Blog »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>chrome</category>
      <category>firefox</category>
      <category>javascript</category>
      <category>safari</category>
    </item>
    <item>
      <title>Five Misconceptions on How NodeJS Works</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Thu, 19 Mar 2020 01:31:42 +0000</pubDate>
      <link>https://dev.to/deepal/five-misconceptions-on-how-nodejs-works-1he4</link>
      <guid>https://dev.to/deepal/five-misconceptions-on-how-nodejs-works-1he4</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6zm9cB1q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ATSzi-VbXOzl46iqf03lcag.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6zm9cB1q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ATSzi-VbXOzl46iqf03lcag.jpeg" alt="" width="880" height="460"&gt;&lt;/a&gt;Background Image Courtesy: &lt;a href="https://wallpapercave.com/mythology-wallpapers"&gt;&lt;/a&gt;&lt;a href="https://wallpapercave.com/mythology-wallpapers"&gt;https://wallpapercave.com/mythology-wallpapers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article is based on a Brown Bag session I did at&lt;/strong&gt; &lt;a href="https://www.comparethemarket.com/"&gt;&lt;strong&gt;comparethemarket.com&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;on “Five Misconceptions on How NodeJS Works”.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;NodeJS was born in 2009 and it has gained massive popularity throughout the years because of one reason. It’s just JavaScript! Well, it’s a JavaScript runtime designed to write server-side applications, but the statement that “It’s just JavaScript” is not 100% true.&lt;/p&gt;

&lt;p&gt;JavaScript is single-threaded, and it was not designed to run on the server-side where scalability was a critical requirement. With Google Chrome’s high-performance V8 JavaScript Engine, the super cool asynchronous I/O implementation of libuv, and with a few other spicy additions, Node JS was capable of bringing client-side JavaScript to the server-side enabling writing super-fast web servers in JavaScript that are capable of handling thousands of socket connections at a time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OPx6BMrB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A-0Sa0i_g-gcL9sJqvecKEw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OPx6BMrB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A-0Sa0i_g-gcL9sJqvecKEw.png" alt="" width="880" height="495"&gt;&lt;/a&gt;Building Blocks of Node JS&lt;/p&gt;

&lt;p&gt;NodeJS is a massive platform built with a bunch of interesting building blocks as the above diagram describes. However, due to the lack of understanding of how these internals pieces of Node JS work, many Node JS developers make false assumptions on the behaviour of Node JS and develop applications which lead to serious performance issues as well as hard-to-trace bugs. In this article, I’m going to describe five such false assumptions which are quite common among many Node JS developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Misconception 1 — EventEmitter and the Event Loop are related
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nodejs.org/api/events.html"&gt;NodeJS EventEmitter&lt;/a&gt; is intensively used when writing NodeJS applications, but there’s a misconception that the EventEmitter has something to do with the NodeJS Event Loop, which is incorrect.&lt;/p&gt;

&lt;p&gt;NodeJS Event Loop is the heart of NodeJS which provides the asynchronous, non-blocking I/O mechanism to NodeJS. It processes completion events from different types of &lt;strong&gt;asynchronous events&lt;/strong&gt; in a particular order.&lt;/p&gt;

&lt;p&gt;(Please check out my article series on the &lt;a href="https://blog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810"&gt;NodeJS Event Loop&lt;/a&gt;, if you are not familiar with how it works!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cnoFvu0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A2yXbhvpf1kj5YT-m_fXgEQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cnoFvu0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A2yXbhvpf1kj5YT-m_fXgEQ.png" alt="" width="880" height="550"&gt;&lt;/a&gt;NodeJS Event Loop&lt;/p&gt;

&lt;p&gt;In contrast, NodeJS Event Emitter is a core NodeJS API which allows you to attach listeners functions to a particular event which will be invoked once the event is fired. This behaviour looks like asynchronous because the event handlers are usually invoked at a later time than it was originally registered as an event handler.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;EventEmitter&lt;/code&gt; instance keeps track of all events and listeners associated with an event within the &lt;code&gt;EventEmitter&lt;/code&gt; instance itself. It does not schedule any events in the event loop queues. The data structure where this information is stored is merely a plain old JavaScript Object where the object properties are the event names (or “types” as someone may call) and the value of a property is one listener function or an array of listener functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AuBs5utX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A9dCC-WJOstRw8vL1v5C6cA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AuBs5utX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A9dCC-WJOstRw8vL1v5C6cA.jpeg" alt="" width="880" height="680"&gt;&lt;/a&gt;Oversimplified Diagram of how event handlers are attached to an event in EventEmitter&lt;/p&gt;

&lt;p&gt;When the &lt;code&gt;emit&lt;/code&gt; function is called on the &lt;code&gt;EventEmitter&lt;/code&gt; instance, the emitter will &lt;strong&gt;SYNCHRONOUSLY&lt;/strong&gt; invoke the listener functions registered to the event in a sequential manner.&lt;/p&gt;

&lt;p&gt;If you consider the following snippet:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The output of the above snippet would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;handler1: myevent was fired!
handler2: myevent was fired!
handler3: myevent was fired!
I am the last log line
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Since the event emitter synchronously executes all the event handlers, the line &lt;code&gt;I am the last log line&lt;/code&gt; won’t be printed until all the listener functions are invoked.&lt;/p&gt;
&lt;h2&gt;
  
  
  Misconception 2—All callback-accepting functions are asynchronous
&lt;/h2&gt;

&lt;p&gt;Whether a function is synchronous or asynchronous depends on whether the function creates any asynchronous resources during the execution of the function. With this definition, if you are given a function, you can determine that the given function is asynchronous if it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calls a native JavaScript/NodeJS asynchronous function (e.g, &lt;code&gt;setTimeout&lt;/code&gt;, &lt;code&gt;setInterval&lt;/code&gt;, &lt;code&gt;setImmediate&lt;/code&gt;, &lt;code&gt;process.nextTick&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Performs a native NodeJS async function(e.g, async functions in &lt;code&gt;child_process&lt;/code&gt;, &lt;code&gt;fs&lt;/code&gt;, &lt;code&gt;net&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Uses Promise API (includes the usage of async-await)&lt;/li&gt;
&lt;li&gt;Calls a function from a &lt;a href="https://nodejs.org/docs/latest/api/n-api.html"&gt;C++ addon&lt;/a&gt; which is written to be asynchronous (e.g, &lt;a href="https://www.npmjs.com/package/bcrypt"&gt;bcrypt&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Accepting a callback function as an argument does not make a function asynchronous. However, usually asynchronous functions do accept a callback as the last argument (unless it’s wrapped to return a &lt;code&gt;Promise&lt;/code&gt;). This pattern of accepting a callback and passing the results to the callback is called the &lt;strong&gt;Continuation Passing Style&lt;/strong&gt;. You can still write a 100% synchronous function using the Continuation Passing Style.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Synchronous functions and Asynchronous functions have a significant difference in terms of how they use the stack during the execution.&lt;/p&gt;

&lt;p&gt;Synchronous functions occupy the stack during the entire duration of its execution, by disallowing anyone else to occupy the stack until it returns.&lt;/p&gt;

&lt;p&gt;In contrast, asynchronous functions schedule some async task and return immediately hence removing itself from the stack. Once the scheduled async task is completed, any callback provided will be called and the callback function will be the one who occupies the stack again. At this point, the function which initiated the async task will no longer be available on the stack since it has already returned.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the above definition in your mind, try to determine whether the following function is asynchronous or synchronous.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In fact, the above function can be synchronous and asynchronous depending on the value passed to the &lt;code&gt;data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If data is a falsy value, the &lt;code&gt;callback&lt;/code&gt; will be called immediately with an error. In this execution path, the function is 100% synchronous as it does not perform any asynchronous task.&lt;/p&gt;

&lt;p&gt;If data is a truthy value, it’ll write data into &lt;code&gt;myfile.txt&lt;/code&gt; and will call the &lt;code&gt;callback&lt;/code&gt; after the file I/O operation is completed. This execution path is 100% asynchronous due to the async file I/O operation.&lt;/p&gt;

&lt;p&gt;Writing function in such an inconsistent way (where the function behaves both synchronously and asynchronously) is highly discouraged because it will make an application’s behaviour unpredictable. Fortunately, these inconsistencies can easily be fixed as follows:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;process.nextTick&lt;/code&gt; can be used to defer the invocation of callback function thereby making the execution path asynchronous.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Alternatively, you can use &lt;code&gt;setImmediate&lt;/code&gt; instead of &lt;code&gt;process.nextTick&lt;/code&gt; in this case, which will more or less give the same result. However, &lt;code&gt;process.nextTick&lt;/code&gt; callbacks have a higher priority comparatively thereby making it faster than &lt;code&gt;setImmediate&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you need to learn more about the difference between &lt;code&gt;process.nextTick&lt;/code&gt; and &lt;code&gt;setImmediate&lt;/code&gt;, have a look at the following article from my Event Loop series.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://blog.insiderattack.net/timers-immediates-and-process-nexttick-nodejs-event-loop-part-2-2c53fd511bb3" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JApGAbZL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/fit/c/96/96/1%2AEUKpom7_YjKK6iqhGmAIpA.jpeg" alt="Deepal Jayasekara"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://blog.insiderattack.net/timers-immediates-and-process-nexttick-nodejs-event-loop-part-2-2c53fd511bb3" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Timers, Immediates and Process.nextTick— NodeJS Event Loop Part 2 | by Deepal Jayasekara | Deepal’s Blog&lt;/h2&gt;
      &lt;h3&gt;Deepal Jayasekara ・ &lt;time&gt;Oct 9, 2020&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hnDHPsJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        blog.insiderattack.net
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Misconception 3— All CPU-intensive functions are blocking the event loop
&lt;/h2&gt;

&lt;p&gt;It is a widely known fact that CPU-intensive operations block the Node.js Event Loop. While this statement is true up to a certain extent, it is not 100% true as there are some CPU-intensive functions which do not block the event loop.&lt;/p&gt;

&lt;p&gt;In general, cryptographic operations and compression operations are highly CPU-bound. Due to this reason, there are async versions of certain &lt;a href="https://nodejs.org/api/crypto.html"&gt;crypto&lt;/a&gt; functions and &lt;a href="https://nodejs.org/api/zlib.html"&gt;zlib&lt;/a&gt; functions which are written in a way to perform computations on the &lt;code&gt;libuv&lt;/code&gt; thread pool so that they do not block the event loop. Some of these functions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;crypto.pbkdf2()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;crypto.randomFill()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;crypto.randomBytes()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;All &lt;code&gt;zlib&lt;/code&gt; async functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, as of this writing, there’s no way to run CPU-intensive operation on the &lt;code&gt;libuv&lt;/code&gt; thread pool using pure JavaScript. Yet, you can write your own &lt;a href="https://nodejs.org/api/n-api.html"&gt;C++ addon&lt;/a&gt; which will give you the ability to schedule work on the libuv thread pool. There are certain 3rd party libraries (e.g. &lt;a href="https://www.npmjs.com/package/bcrypt"&gt;bcrypt&lt;/a&gt;) which perform CPU-intensive operations and uses C++ addons to implement asynchronous APIs for CPU bound operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Misconception 4— All asynchronous operations are performed on the thread pool
&lt;/h2&gt;

&lt;p&gt;Modern operating systems have built-in kernel support to facilitate native asynchrony for Network I/O operations in an efficient way using event notifications (e.g, &lt;a href="https://en.wikipedia.org/wiki/Epoll"&gt;epoll&lt;/a&gt; in linux, &lt;a href="https://en.wikipedia.org/wiki/Kqueue"&gt;kqueue&lt;/a&gt; in macOS, &lt;a href="https://en.wikipedia.org/wiki/Input/output_completion_port"&gt;IOCP&lt;/a&gt; in windows etc.). Therefore, &lt;strong&gt;Network I/O is not performed on the libuv thread pool&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, when it comes to File I/O, there are a lot of inconsistencies across operating systems as well as in some cases within the same operating system. This makes it extremely hard to implement a generalised platform-independent API for File I/O. Therefore, File system operations are performed on the &lt;code&gt;libuv&lt;/code&gt; thread pool to expose a consistent asynchronous API.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dns.lookup()&lt;/code&gt; function in &lt;code&gt;dns&lt;/code&gt; module is another API which utilises the &lt;code&gt;libuv&lt;/code&gt; thread pool. The reason for that is, resolving a domain name to an IP address using &lt;code&gt;dns.lookup()&lt;/code&gt; function is a platform-dependent operation, and this operation is not a 100% network I/O.&lt;/p&gt;

&lt;p&gt;You can read more about how NodeJS handles different I/O operations here:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://blog.insiderattack.net/handling-io-nodejs-event-loop-part-4-418062f917d1" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JApGAbZL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/fit/c/96/96/1%2AEUKpom7_YjKK6iqhGmAIpA.jpeg" alt="Deepal Jayasekara"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://blog.insiderattack.net/handling-io-nodejs-event-loop-part-4-418062f917d1" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Handling IO — NodeJS Event Loop Part 4 | by Deepal Jayasekara | Deepal’s Blog&lt;/h2&gt;
      &lt;h3&gt;Deepal Jayasekara ・ &lt;time&gt;Aug 16, 2020&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hnDHPsJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        blog.insiderattack.net
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Misconception 5— NodeJS should not be used to write CPU-intensive applications
&lt;/h2&gt;

&lt;p&gt;This is not really a misconception, but rather was a well-known fact about NodeJS which is now obsolete with the introduction of Worker Threads in Node v10.5.0. Although it was introduced as an experimental feature, &lt;code&gt;worker_threads&lt;/code&gt; module is now stable since Node v12 LTS, therefore suitable for using it in production applications with CPU-intensive operations.&lt;/p&gt;

&lt;p&gt;Each Node.js worker thread will have a copy of its own v8 runtime, an event loop and a libuv thread pool. Therefore, one worker thread performing a blocking CPU-intensive operation does not affect the other worker threads’ event loops thereby making them available for any incoming work.&lt;/p&gt;

&lt;p&gt;If you are interested in learning how Worker Threads work in detail, I encourage you to read the following article:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://blog.insiderattack.net/deep-dive-into-worker-threads-in-node-js-e75e10546b11" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JApGAbZL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/fit/c/96/96/1%2AEUKpom7_YjKK6iqhGmAIpA.jpeg" alt="Deepal Jayasekara"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://blog.insiderattack.net/deep-dive-into-worker-threads-in-node-js-e75e10546b11" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Deep Dive into Worker Threads in Node.js | by Deepal Jayasekara | Deepal’s Blog&lt;/h2&gt;
      &lt;h3&gt;Deepal Jayasekara ・ &lt;time&gt;Jul 6, 2021&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hnDHPsJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        blog.insiderattack.net
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;However, at the time of this writing, the IDE support for worker threads is not the greatest. Some IDE’s does not support attaching the debugger to the code run inside a worker thread other than the main worker. However, the development support will mature over time as a lot of developers have already started adopting worker threads for CPU-bound operations such as video encoding etc.&lt;/p&gt;

&lt;p&gt;I hope you learned something new after reading this article, and please feel free to provide any feedback you have by responding to this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further Readings:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Designing APIs for Asynchrony (Isaac Z. Schlueter) &lt;a href="https://blog.izs.me/2013/08/designing-apis-for-asynchrony"&gt;https://blog.izs.me/2013/08/designing-apis-for-asynchrony&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;My Event Loop article series &lt;a href="https://blog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810"&gt;https://blog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>javascript</category>
      <category>softwaredevelopment</category>
      <category>programming</category>
      <category>node</category>
    </item>
    <item>
      <title>100% Unit Test Coverage — Is that a Myth?</title>
      <dc:creator>Deepal Jayasekara</dc:creator>
      <pubDate>Fri, 07 Feb 2020 19:46:11 +0000</pubDate>
      <link>https://dev.to/deepal/100-unit-test-coverage-is-that-a-myth-2pdi</link>
      <guid>https://dev.to/deepal/100-unit-test-coverage-is-that-a-myth-2pdi</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Yr_kzlP4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ADwuZ9s6rqRE4olCEHgAmXw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Yr_kzlP4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ADwuZ9s6rqRE4olCEHgAmXw.png" alt="" width="880" height="460"&gt;&lt;/a&gt;Background Image Courtesy: &lt;a href="https://www.goodfon.com/wallpaper/world-pc-technology-satellite.html"&gt;&lt;/a&gt;&lt;a href="https://www.goodfon.com/wallpaper/world-pc-technology-satellite.html"&gt;https://www.goodfon.com/wallpaper/world-pc-technology-satellite.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We all need to embrace the bitter fact that we all, as developers, hated writing unit tests at some point in our career. While some of us still keep hating writing tests (&lt;em&gt;which I don’t blame for&lt;/em&gt;), I kind of developed a weird interest in writing unit tests after working with a number of JavaScript (&lt;em&gt;mainly Node.js&lt;/em&gt;) projects over the time. And many times, I have seen people arguing about the acceptable unit test coverage both in meetings as well as online developer forums.&lt;/p&gt;

&lt;p&gt;After observing all those dramas, and after having terrible experiences myself throughout the years, I thought I should very briefly write down my two cents on writing unit tests with proper coverage. While I jot these down based on my experience in writing unit tests for Node.js applications, I strongly believe that these facts are universal for any type of application written in any programming language. And, I’m pretty sure you might have more experience than me regarding this topic, so feel free to let me know your opinions about this topic which certainly would help me, as well as the other readers.&lt;/p&gt;

&lt;p&gt;This article was originally posted in:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="https://blog.insiderattack.net/100-unit-test-coverage-is-that-a-myth-5aef67f85a09" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JApGAbZL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/fit/c/96/96/1%2AEUKpom7_YjKK6iqhGmAIpA.jpeg" alt="Deepal Jayasekara"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://blog.insiderattack.net/100-unit-test-coverage-is-that-a-myth-5aef67f85a09" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;100% Unit Test Coverage — Is that a Myth? | by Deepal Jayasekara | Deepal’s Blog&lt;/h2&gt;
      &lt;h3&gt;Deepal Jayasekara ・ &lt;time&gt;Feb 13, 2020&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hnDHPsJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        blog.insiderattack.net
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h4&gt;
  
  
  Why do you need unit tests? Isn’t integration tests sufficient?
&lt;/h4&gt;

&lt;p&gt;One problem with the unit tests is that if your unit tests are passing, it still doesn’t mean that your application will operate correctly. The reason is, as we all know, unit tests only stubs/mocks the dependencies and test the individual building blocks of your application. In contrast, “&lt;a href="https://en.wikipedia.org/wiki/Integration_testing"&gt;Integration tests&lt;/a&gt;” assert whether your application behaves properly once all those building blocks were put together. Then why do we write unit tests at all?? Why can’t we satisfy from integration tests?&lt;/p&gt;

&lt;p&gt;We need to understand the purpose of unit tests to answer this question.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unit tests are there to increase the developer confidence that whatever the change made in the future won’t break the existing functionality.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Can’t we get the same confidence level by integration tests? Not really.&lt;/p&gt;

&lt;p&gt;Running integration tests is usually an expensive operation as it involves communicating with real or at least near-real dependencies. This is not something you can do every time you make a code change as it affects productivity.&lt;/p&gt;

&lt;p&gt;Another reason is that it is extremely hard to reproduce and test all the execution paths including the edge-cases in integration tests whereas, in unit tests, it’s relatively easy to manipulate the execution path by fine-grained dependency stubbing to test those scenarios.&lt;/p&gt;

&lt;h4&gt;
  
  
  80% Coverage or 100% coverage
&lt;/h4&gt;

&lt;p&gt;I have seen many times in many projects that people agreeing to 80% as a good test coverage number. I’m strongly against this decision because I still do not have the answers to the following two questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do you quantify the acceptable test coverage? Who and how can come someone up with an exact number?&lt;/li&gt;
&lt;li&gt;If 80% coverage is acceptable, which 80% of the code would you cover?&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are a project manager, and you expect 80% of the unit tests coverage from your developers, you should know that they are going to leave the most critical 20% of the code untested and cover the most comfortable 80% just to make you happy!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my opinion, the tests should cover as much of your code as possible and preferably 100%. Any piece of code you left untested can be changed by another developer at any time, leading to a potential break of the functionality going unnoticed.&lt;/p&gt;

&lt;p&gt;However, as we all know, the test coverage is measured in multiple ways such as line coverage, branch coverage, function coverage etc. Obtaining 100% line coverage is not that hard. But, does 100% line coverage mean that the entire code is properly unit tested? This leads us to our next topic.&lt;/p&gt;

&lt;h4&gt;
  
  
  Line Coverage vs Branch Coverage
&lt;/h4&gt;

&lt;p&gt;A line is considered to be covered if any of the statements in that line was touched during the tests. But if the code execution splits into multiple &lt;strong&gt;branches&lt;/strong&gt; in a particular line, line coverage will not correctly cover all the possible &lt;strong&gt;execution paths&lt;/strong&gt;. The &lt;strong&gt;execution paths&lt;/strong&gt; , also known as &lt;strong&gt;branches&lt;/strong&gt; are the different paths your application logic might take during the execution. For example, the following line shows a statement with two branches.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isEveryoneHappy&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;happyFunc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sadFunc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above line is considered to be covered in test coverage tools if the code execution hit this line regardless of the value of &lt;code&gt;isEveryoneHappy&lt;/code&gt;. But depending on the value of &lt;code&gt;isEveryoneHappy&lt;/code&gt;, the code execution might take either happyFunc() or sadFunc() path which could probably result in two completely different outcomes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Therefore, branch coverage is much more powerful and a more accurate representation of the test coverage.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Achieving 100% branch coverage is not that hard at all, given that you write your code in a testable way and use the correct tools at your disposal to stub the dependencies and make your code follow the different branches.&lt;/p&gt;

&lt;p&gt;Last but not the least, always make sure that you have covered the most important assertions which are related to your application’s functionality when you write tests. 100% unit test coverage will not help you if you haven’t identified the most important functionalities that need to be tested. Once the source code is 100% covered and all the tests are properly written to assert all the required functionality, it’ll be a huge investment which will ease future development.&lt;/p&gt;




&lt;p&gt;I hope I left you something important to think about when writing unit tests. Anyway, this topic is open to suggestions, and feel free to let me know your thoughts on this in comments.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>unittesttools</category>
      <category>node</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
