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
ngx_mrubyとfiberの話 (未完成版)
Search
Ryo Okubo
January 24, 2018
Programming
2
320
ngx_mrubyとfiberの話 (未完成版)
ngx_mruby のかんたんな紹介と、 fiber を組み込んで色々やりたかったけど挫折してる話
Ryo Okubo
January 24, 2018
Tweet
Share
More Decks by Ryo Okubo
See All by Ryo Okubo
UbieのAIパートナーを支えるコンテキストエンジニアリング実践
syucream
2
1.2k
メルカリ・メルペイの成長を支える データ基盤とはどんなものか
syucream
7
7.1k
バッチとストリーミング、それぞれの障害に立ち向かう
syucream
3
3.7k
How Scala works at Mercari
syucream
2
1.1k
Production-ready stream data pipeline in Merpay, Inc
syucream
2
13k
データとML周辺エンジニアリン グを考える会 #2 イントロ
syucream
0
640
マイクロサービスにおける ログ収集の課題と取り組み
syucream
7
2.7k
Stream Data Pipeline for Microservices in Merpay
syucream
6
1.2k
メルペイにおける、マイクロサービスに寄り添うログ収集基盤 / Microservices-frendly Data Pipeline
syucream
0
18k
Other Decks in Programming
See All in Programming
Introducing RemoteCompose: break your UI out of the app sandbox.
camaelon
2
460
フロントエンド開発のためのブラウザ組み込みAI入門
masashi
7
3.7k
Vueのバリデーション、結局どれを選べばいい? ― 自作バリデーションの限界と、脱却までの道のり ― / Which Vue Validation Library Should We Really Use? The Limits of Self-Made Validation and How I Finally Moved On
neginasu
3
1.8k
オンデバイスAIとXcode
ryodeveloper
0
390
Developer Joy - The New Paradigm
hollycummins
1
410
Migration to Signals, Resource API, and NgRx Signal Store
manfredsteyer
PRO
0
140
Verilator + Rust + gRPC と Efinix の RISC-V でAIアクセラレータをAIで作ってる話 RTLを語る会(18) 2025/11/08
ryuz88
0
230
Designing Repeatable Edits: The Architecture of . in Vim
satorunooshie
0
240
ビルドプロセスをデバッグしよう!
yt8492
0
250
TransformerからMCPまで(現代AIを理解するための羅針盤)
mickey_kubo
7
6k
CSC305 Lecture 11
javiergs
PRO
0
320
CSC305 Lecture 13
javiergs
PRO
0
360
Featured
See All Featured
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
23
1.5k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.7k
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
[RailsConf 2023] Rails as a piece of cake
palkan
57
6k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
2.9k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
Documentation Writing (for coders)
carmenintech
76
5.1k
Transcript
ngx_mrubyとfiberの話 (未完成版) @syu_cream
whoami • @syu_cream • 仕事で Go, Scala, mrubyは趣味 • mruby
の実装に関する同人誌書いた ◦ https://www.amazon.co.jp/dp/B06XZ9LXSB • 作った mruby 関連プロダクト ◦ mruby-rspec ◦ mruby-serverspec ◦ mruby-k2hash ◦ mruby-rocksdb ◦ ts_mruby(mruby extension for Apache TrafficServer)
今日の話 • この会のテーマを見ると... • ngx_mruby, fiber 周りで試行錯誤した話需要あるかも? • と思ったのでそんな感じの話します
ngx_mruby • 設定や簡単なロジックを mruby で拡張可能にする nginx モ ジュール ◦ https://github.com/matsumotory/ngx_mruby
• ngx_mruby 利用例: ◦ ランダムに upstream を切り替える ◦ 特定 IP アドレス以外からのアクセスを遮断する
ngx_mruby 利用の具体例 • User-Agent が空なリクエストに400を返す ◦ 以下はnginx.confにインラインで書いてるけど別ファイルに分離可能
ngx_mruby における非同期処理 • 依存 mrbgems で容易に I/O でブロックする ◦ ノンブロッキング
I/O のサポートはしていない ◦ なので性能面でつらい場面が出る可能性がある • h2oでも試行錯誤してた ◦ https://www.slideshare.net/ichitonagata/h2o-x-mruby-72949986 • ngx_lua はノンブロッキング処理を頑張っている ◦ ngx.sleep, ngx.location.capture ◦ ngx.socket.tcp, ngx.socket.udp ◦ さらに気になる人は “nginx実践入門” もチェック!
ngx_mrubyでもノンブロッキングI/Oしたい! • nginx を使う以上イベント駆動の恩恵を受けたい • lua ならコルーチンで処理の継続ができる • mruby の場合...
継続可能な処理は fiber で表現可能 • まずノンブロッキング sleep を実装してみる ◦ 実用性で言うと subrequest が欲しいが難易度が高い ◦ 第一歩は簡単で分かりやすい目標にする
ngx_mruby fiber • ngx_mruby で fiber サポートを試みた ◦ まずは mruby
の実行コードを fiber に包んで VM に実行させる ◦ その後 fiber の具体利用例として sleep を実装する ▪ Nginx::Async.sleep という名前付けた
事前調査・学習の流れ • mruby の ソースコードをざっくり読む ◦ include/ 以下のヘッダと必要なら src/, mrbgems/mruby-fiber/
• ngx_mruby のソースコードを読む ◦ 特に src/http/ngx_http_mruby_module.c ◦ VM の実行部分を触ることになるので mrb_run() 周りを • echo-nginx-module のソースコードを読む ◦ ノンブロッキング sleep を実装している module ▪ えっ、 echo module って何だよ(哲学) ▪ src/ngx_http_echo_sleep.c が参考になった • nginx のソースコードをざっくり読む ◦ 上記で解決しなかった場合はサボらない
実装 • forkした以下のリポジトリにあります ◦ https://github.com/syucream/ngx_mruby • やったこと ◦ mrb_run() で実行する
RProc 構造体の値を fiber でラップ ◦ fiber を yield されるまで実行 ◦ Nginx::Async.sleepのC関数内で yield して nginx の timer をセット ▪ ngx_add_timer() にハンドラと秒数を渡す ◦ ハンドラ内で fiber を resume & nginx のイベントを進める ▪ ngx_http_core_run_phase() 経由で操作
Nginx::Async.sleep の動作 • コード例 ◦ 上がブロックする版、下がしない版 • 実際の動作 ◦ デモします
ngx_mruby によるノンブロッキング処理の展望 • sleep だけでは用途は限定される • subrequest が扱えるとやれることが多くなる ◦ ACL
設定を他 HTTP サーバに分離してそれを参照など • ngx_lua の ngx.socket.tcp など欲しいが、険しい道 ◦ mruby-redis とか使いたいライブラリに手を入れるの? ◦ 片っ端から ngx_mruby 用の修正入れるのは高コスト • Thread Pool と連携してなにかできないかな? ◦ https://www.nginx.com/blog/thread-pools-boost-performance-9x/ ◦ ブロックする処理の実装は無理して変更しない ◦ Thread Pool に投げるようにして、終わったら resume する
実装でハマった(ハマってる)箇所1 • mruby の fiber 操作の C 関数がつらい ◦ yield/resume
関数の 2 つしかない ◦ new する C 関数が無いので funcall 経由でオブジェクト生成 ▪ proc オブジェクトと fiber class の mrb_value を用意 ▪ mrb_funcall_with_block() に渡してオブジェクトを得る ◦ その後 mrb_fiber_resume() するも... • 本スライドでは Fiber を Proc オブジェクトでラップして Proc#call 経由で操作するメソッドを Ruby で実装☺
実装でハマった(ハマってる)箇所2 • 生成された mruby のコードの OP_STOP 命令問題 ◦ yield した後もちろん別の
mruby コードが実行される可能性ある ◦ そしてそのコードは末尾に OP_STOP を持つ ▪ mrb_generate_code() で生成されたコードは持つはず ◦ OP_STOP で VM が停止し、 fiber が resume できない事態に! ◦ 一旦 OP_STOP を OP_RETURN に置換するという荒業で対応 ▪ 過去に h2o がこの対策取ってたらしい ▪ 本来どうするべきなんだろうか ...
実装でハマった(ハマってる)箇所3 • 特定ハンドラでしか動作確認できていない ◦ 現状、 rewrite, access handler でしか動作しない ◦
content handlerとかで動かしたら死ぬ • nginx の理解がそもそも足りていない気がする
おわりに • ngx_mrubyの試行錯誤コード読み書き話ウケるかも! • と思ったのでそんな感じの話します • と意気込んだものの絶賛WIPです • それでも何かの参考になれば幸いです