ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Single Thread, Event Loop, and Blocking Code
    Framework/Node.js 2020. 2. 21. 21:16

    1. Overview

    1.1 Event Loop

    The event loop is automatically started by node.js when your program starts. This is responsible for handling event callbacks though.

    The event loop is responsible for basically running that code when a certain event occurs you could say, it's aware of all these callbacks and basically well, execute said code. 

    It's important to understand that this operation is not handled by the event loop, just the callback that we might have defined on write file once it's done. That code will be handled in the event loop but that code will finish fast, so basically the event loop will only handle callbacks that contain fast-finishing code.

    1.2 Worker Pool

    This worker pool is kind of totally detached of your javascript code and it runs on different threads, it can spin up multiple threads, it's closely intervened with your operating system you're running the app on.

    This worker pool is, therefore, doing all the heavy lifting.

    Once the worker is done, so for example once we read a file, it will trigger the callback for that read file operation and since the event loop is responsible for the events and the callbacks, this will, in the end, end up in the event loop.

    2. Description

    2.1 Event Loop

    2.1.1 Timer

    Basically there is setTimeout and setInterval.

    Basically you set a timer and always pass a method, a function that should be executed once that timer completes and node.js is aware of this and at the beginning of each new loop iteration.

    At the beginning of each new iteration it checks if there are any timer callbacks it should execute. 

    Once that timer completes and node.js is aware of this and at the beginning of each new loop iteration, it executes any due timer callbacks.

    2.1.2 Pending Callbacks

    If we had written or read a file, we might have a callback because that operation finished and it will then also execute these callbacks.

    It's important to understand that node.js will leave that phase at a certain point of time and that can also mean that if there are too many outstanding callbacks, it will continue its loop iteration and postpone these callbacks to the next iteration to execute them.

    2.1.3 Poll

    The pull phase is basically a phase where node.js will look for new IO events and basically do its best to execute their callbacks immediately if possible.

    Now if that's not possible, it will defer the execution and basically register this as a pending callback.

    If there are any timer callbacks due to be executed and if that is the case, it will jump to that timer phase and execute them right away.

    2.1.4 Check

    setImmediate callbacks will be executed in a so-called check phase.

    setImmediate is a bit like setTimeout or setInterval, just that it will execute immediately but always after any open callbacks have been executed.

    2.1.5 Close Callbacks

    if you had any close events, this would be the point of time where node.js executes their appropriate callbacks.

    So roughly spoken, we have timer callbacks, we then have any IO related callbacks and other event callbacks and setImmediate followed by close event callbacks

    2.1.6 Exit

    Since in a server environment we create a server with creating a server and then listen to incoming requests with listen, this is an event which never is finished by default and therefore, we always have at least one reference and therefore we don't exit in a normal node web server program.

    3. Example

    // Assume thread pool size is 4
    
    const https = require('https')
    const crypto = require('crypto')
    const fs = require('fs')
    
    const start = Date.now()
    
    function doRequest() {
        https.request('https://www.google.com', res => {
            res.on('data', () => {
            });
            res.on('end', () => {
                console.log(Date.now() - start);
            });
        }).end();
    }
    
    function doHash() {
        crypto.pbkdf2('a', 'b', 100000, 512, 'sha512', () => {
            console.log('Hash:', Date.now() - start);
        });
    }
    
    doRequest()
    
    fs.readFile('multitask.js', 'utf8', () => {
        console.log('FS: ', Date.now() - start);
    });
    
    doHash()
    doHash()
    doHash()
    doHash()
    
    // output
    433
    Hash: 586
    FS:  587
    Hash: 618
    Hash: 626
    Hash: 715

    4. Reference

    https://en.wikipedia.org/wiki/Node.js

    'Framework > Node.js' 카테고리의 다른 글

    Data Caching with Redis  (0) 2020.02.22
    Enhancing Node Performance  (0) 2020.02.21
    The Internals of Node.js  (0) 2020.02.21

    댓글

Designed by Tistory.