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
ryota kise
June 25, 2022
Programming
0
6.6k
Node.jsデザインパターンを読んで
テックベンチという社内のLT会で発表した資料です。
Node.jsのアーキテクチャにおける、libuvの部分の話について深ぼって話しました。
ryota kise
June 25, 2022
Tweet
Share
More Decks by ryota kise
See All by ryota kise
構造体初期化の方法について
mmmommm
0
120
Node V18 について
mmmommm
0
14
Other Decks in Programming
See All in Programming
FigmaとPHPで作る1ミリたりとも表示崩れしない最強の帳票印刷ソリューション
ttskch
39
18k
コードレビューで学ぶ!Kotlinオブジェクト指向デザインパターン
akkie76
2
180
Code Reviews
bkuhlmann
4
880
Elm 0.19.0 Changes
bkuhlmann
0
480
OpenAPIを中心に考えるAPI開発入門 / Introduction to API Development with a Focus on OpenAPI
seike460
PRO
2
120
HUIT新歓2024「競技プログラミング、やってみませんか?」
slephy2784
1
250
Designing for tomorrow's programming workflows
honnibal
PRO
2
110
Folding Cheat Sheet #3
philipschwarz
PRO
0
110
Ruby Function Composition
bkuhlmann
1
330
今の SmartHR にエンジニアで入社するとどうなるの?
daisukeshinoku
5
4.6k
単体テストを書かない技術 #phpcon_odawara
o0h
PRO
25
7.8k
Ruby GitHub Packages
bkuhlmann
0
620
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
72
8.2k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
60
14k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
18
6.9k
Stop Working from a Prison Cell
hatefulcrawdad
266
19k
Web development in the modern age
philhawksworth
202
10k
Pencils Down: Stop Designing & Start Developing
hursman
117
11k
Git: the NoSQL Database
bkeepers
PRO
422
63k
Building a Modern Day E-commerce SEO Strategy
aleyda
16
6.4k
Put a Button on it: Removing Barriers to Going Fast.
kastner
58
3k
How to Ace a Technical Interview
jacobian
272
22k
Designing for humans not robots
tammielis
247
25k
Faster Mobile Websites
deanohume
297
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/