Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Node.jsデザインパターンを読んで
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
ryota kise
June 25, 2022
Programming
10k
2
Share
Node.jsデザインパターンを読んで
テックベンチという社内のLT会で発表した資料です。
Node.jsのアーキテクチャにおける、libuvの部分の話について深ぼって話しました。
ryota kise
June 25, 2022
More Decks by ryota kise
See All by ryota kise
構造体初期化の方法について
mmmommm
0
220
Node V18 について
mmmommm
0
48
Other Decks in Programming
See All in Programming
RSAが破られる前に知っておきたい 耐量子計算機暗号(PQC)入門 / Intro to PQC: Preparing for the Post-RSA Era
mackey0225
3
120
条件判定に名前、つけてますか? #phperkaigi #c
77web
2
980
まかせられるPM・まかせられないPM / DevTech GUILD Meetup
yusukemukoyama
0
110
10年分の技術的負債、完済へ ― Claude Code主導のAI駆動開発でスポーツブルを丸ごとリプレイスした話
takuya_houshima
0
1.9k
KagglerがMixSeekを触ってみた
morim
0
370
安いハードウェアでVulkan
fadis
1
930
Rethinking API Platform Filters
vinceamstoutz
0
11k
Laravel Nightwatchの裏側 - Laravel公式Observabilityツールを支える設計と実装
avosalmon
1
320
「接続」—パフォーマンスチューニングの最後の一手 〜点と点を結ぶ、その一瞬のために〜
kentaroutakeda
5
2.5k
Smarter Angular mit Transformers.js & Prompt API
christianliebel
PRO
1
120
仕様漏れ実装漏れをなくすトレーサビリティAI基盤のご紹介
orgachem
PRO
9
5.1k
事業会社でのセキュリティ長期インターンについて
masachikaura
0
230
Featured
See All Featured
The Curse of the Amulet
leimatthew05
1
11k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
480
Optimising Largest Contentful Paint
csswizardry
37
3.6k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.4k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
97
Visualization
eitanlees
150
17k
Context Engineering - Making Every Token Count
addyosmani
9
800
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.2k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
480
WCS-LA-2024
lcolladotor
0
520
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Transcript
Node.jsデザインパターン を読んで 2022 / 6 / 23
ゴール - libuvとはなんなのか? - Reactor Patternとはなんなのか? - イベントループとはなんなのか? がなんとなく理解できるようになること
Node js 公式より Node.js はスケーラブルなネットワークアプリケーションを構築するために設計された非同期 型のイベント駆動の JavaScript 環境です。 特徴としては -
シングルスレッド - ノンブロッキング I / O + イベントループ(libuv) = 非同期 I / O が挙げられます
シングルスレッドとは - CPUの処理単位のことでCPUの利用単位としてはプロセスとスレッドがあり、プロ セスが一つ以上のスレッドをもつ - シングルスレッドは文字通りスレッド一つでプログラムを処理すること
補足 マルチスレッド マルチスレッドでは以下のように処理を複数のスレッドに分散させることができる。 シングルスレッドでは処理をスレッドに分散するのではなく時間軸で分散する
ノンブロッキングI / O ノンブロッキングI / O - I / O処理が走った時にI
/ O処理ができない場合は即座にエラーを返しブロックさせ ない方式 - データが処理可能になるまでリクエストを送る必要がある 非同期I / O - I / O処理が走った時に処理が完了するまでバックグラウンドで待機しI / O処理が 完了したタイミングで通知を返すことによってブロックしない方式
Busy Wait - ノンブロッキングI / Oの処理方法の一つ - I / Oの処理が戻されるまでループを回してポーリングする方法のこと
- この方法ではI / O処理可能になるまでループするためCPUを食うことになる
Reactor Pattern I / Oに基づいた処理はI / O完了の通知を受け取ってからデータを取り出し行う必要が ある シングルスレッドで複数の処理を行うために -
ノンブロッキングI / O - イベント多重分離(Event demultiplexing) - イベントループ がある dataを読み取ってinputに 代入する前にconsole.log に到達するので 何も出力されない
イベント多重分離(event demultiplexing) 一つにまとまった処理を複数に分離することをデマルチプレキシング(多重分離)という この機能はOSに提供されており、I / Oの完了が完了した時に〇〇するができるように この方法を使用することによって時間軸で処理を分散させシングルスレッドでも並行に 処理を実行することができる
libuv デマルチプレクサの実装はOSごとに異なっている(Linuxのepoll, macOSのkqueueな ど) OS差分を抽象化し吸収するために、Nodeのコア開発チームはlibuvというCのライブラ リを作成している。 libuvがこのあと出てくるイベントループや非同期処理をNode.jsに提供している
Reactor PatternでのI / Oリクエスト時の実際の動き - 基本的にはI / Oタスクのそれぞれにハンドラ( Node.jsではコールバック)を対応させる -
イベントループにおいて新イベントが生成・処理されるたびにハンドラが呼び出される
1 アプリがデマルチプレクサに対して I / O要 求を発行する その際にハンドラが指定され、 I / O要求の
発行はノンブロッキングな関数呼び出しな ので即座にアプリケーションに処理が戻る
2 I / O要求が届くとデマルチプレクサが キューに入れる
3, 4 - イベントループにおいて、キューの 中の全てのイベントが操作されて処 理される - 各イベントに対して、登録済みのハ ンドラが呼び出される
5a, 5b - ハンドラの呼び出しが完了するとイ ベントループで次のイベントが処理 される - ハンドラ内で更にI / O要求が発行さ
れた場合はイベントループに処理を 戻す前に1の処理を繰り返す
6 イベントループで全てのイベントが処理さ れると新しいイベントが送られてくるまで待 機する
Event Queue libuvから提供されるキューとNode.jsが提供するキューがある libuv - Expired timers / intervals queue
- IO Events Queue - Immediates Queue - Close Handlers Queue Node.js - nextTick Queue - microTask Queue libuvが提供しているキューはイベントループの各フェーズに紐づいており、フェーズが実行され る毎にNode.jsが提供しているキューが実行される
Event loop イベントループには6つのフェーズがあり、 3・4・5aがこの6つの順番で行われる それぞれのフェーズは実行するコールバッ クのFIFOキューをもつ JavaScriptの実行はidle,prepare以外のど こかのフェーズで実行され キューが空になるかコールバックの上限に 達したらイベントは次のフェーズへ遷移す
る
3, 4, 5a - イベントループにおいて、キューの 中の全てのイベントが操作されて処 理される - 各イベントに対して、登録済みのハ ンドラが呼び出される
- ハンドラの呼び出しが完了するとイ ベントループで次のイベントが処理 される 再掲
イベントループとキューの対応表 libuvは各フェーズ毎に結果を JavaScriptに伝える この時にnextTickQueueとmicroTaskQueue に入れられた内容を処理する
nextTickQueue process.nextTickのコールバックが実行される 非同期処理の中で最初に実行される
microTaskQueue Promiseオブジェクトのコールバックが実行される
nextTickの方が先に実行される
補足 イベントループ
イベントループ
Event loop (Timer) setTimer, setIntervalなどのタイマー系APIの期限切れコールバックが実行される
Event loop (pending callback) I / O操作の成功、エラーのコールバック関数が実行される この場合だと console.log(err) か
console.log(data)
Event loop (idle, prepare, poll) オプショナルなフェーズでpollフェーズが行われる場合はidle / prepareフェーズが行わ れる -
I / O をブロックしてポーリングする時間を計算する - キュー内のイベントをキューが空になるかシステム固有の上限に達するまで処理す る
Event loop (check) - setImmediateのコールバック専用のフェーズ - setImmediateで登録された全てのコールバックを実行する
Event loop (close callback) 全てのcloseフェーズのコールバックが実行される
実際に
Node.jsのアーキテクチャ
まとめ - Node.jsはイベントループ + ノンブロッキング I / O、非同期 I /
Oを使うことでI / O 待ちの時間を時間軸に分散している - イベントループ、I / O完了通知などの根幹の部分はOS差分を吸収するためにlibuv というライブラリを使用している
ご清聴ありがとうございました
参考資料 - https://www.oreilly.co.jp/books/9784873118734/ - https://blog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182 810 - https://zenn.dev/estra/books/js-async-promise-chain-event-loop - https://blog.takanabe.tokyo/2015/03/%E3%83%8E%E3%83%B3%E3%83%96%E3%83%AD%E
3%83%83%E3%82%AD%E3%83%B3%E3%82%B0i/o%E3%81%A8%E9%9D%9E%E5%90%8 C%E6%9C%9Fi/o%E3%81%AE%E9%81%95%E3%81%84%E3%82%92%E7%90%86%E8%A 7%A3%E3%81%99%E3%82%8B/ - https://blog.hiroppy.me/entry/nodejs-event-loop - https://engineer.recruit-lifestyle.co.jp/techblog/2019-12-13-node-async-io/ - https://nodejs.org/en/about/ - https://libuv.org/