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
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ryota kise
June 25, 2022
Programming
10k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Node.jsデザインパターンを読んで
テックベンチという社内のLT会で発表した資料です。
Node.jsのアーキテクチャにおける、libuvの部分の話について深ぼって話しました。
ryota kise
June 25, 2022
More Decks by ryota kise
See All by ryota kise
構造体初期化の方法について
mmmommm
0
230
Node V18 について
mmmommm
0
58
Other Decks in Programming
See All in Programming
技術記事、AIに書かせるか、自分で書くか? 〜それでも私が自分の手で書く理由〜 / #QiitaConference
jnchito
2
1.3k
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
560
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
160
Claspは野良GASの夢をみるか
takter00
0
180
さぁV100、メモリをお食べ・・・
nilpe
0
140
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
520
Lemonade + Foundry Toolkit でお手軽アプリ開発
seosoft
1
320
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
670
The NotImplementedError Problem in Ruby
koic
1
700
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.2k
3Dシーンの圧縮
fadis
1
690
LLM Plugin for Node-REDの利用方法と開発について
404background
0
170
Featured
See All Featured
A Soul's Torment
seathinner
6
2.9k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
840
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
280
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
310
WENDY [Excerpt]
tessaabrams
11
38k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Side Projects
sachag
455
43k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
200
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
160
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.9k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
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/