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
RuboCop Server Mode の仕組み
Search
Hayato Kawai
March 06, 2024
1
270
RuboCop Server Mode の仕組み
「Gotanda.rb#57」で発表した LT 資料です。
https://gotanda-rb.connpass.com/event/310542/
Hayato Kawai
March 06, 2024
Tweet
Share
More Decks by Hayato Kawai
See All by Hayato Kawai
巨大 tfstate に立ち向かう技術
fohte
0
200
RubyKaigi で LT 初登壇したきっかけと感想
fohte
1
850
Datadog Logs を活用して SLO 監視基盤を構築する
fohte
2
770
The Journey of rubocop-daemon into RuboCop
fohte
1
1k
Ruby as Shell script
fohte
1
470
rubocop-daemon 裏話: OSS の苦悩
fohte
2
550
Ruby を使ったプロダクト開発を支えるオブザーバビリティ基盤
fohte
2
130
インシデントコマンダーやってみた
fohte
5
990
Ruby でもなんとかなる - ISUCON13 公式反省会
fohte
0
140
Featured
See All Featured
Six Lessons from altMBA
skipperchong
27
3.5k
A Modern Web Designer's Workflow
chriscoyier
693
190k
How To Stay Up To Date on Web Technology
chriscoyier
788
250k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Designing for humans not robots
tammielis
249
25k
YesSQL, Process and Tooling at Scale
rocio
168
14k
Documentation Writing (for coders)
carmenintech
65
4.4k
Unsuck your backbone
ammeep
668
57k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
231
17k
The Art of Programming - Codeland 2020
erikaheidi
52
13k
What's in a price? How to price your products and services
michaelherold
243
12k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
Transcript
RuboCop Server Mode の仕組み Gotanda.rb#57 2024-03-06 - Hayato Kawai (@fohte)
あなた誰 名前: @fohte (ふぉーて) 川井 颯人 (Hayato Kawai) 所属: ウォンテッドリー株式会社
趣味: 🎮 🎹
RuboCop 使ってますか?
持ち帰ってほしいこと • Server Mode で RuboCop の起動を高速化できる ◦ プロセスを永続化することで高速化
RuboCop を爆速にしたい • RuboCop は速くない ◦ だいたい 2 秒〜 かかる
▪ 1 ファイルに対しても 1 秒前後かかる ◦ コーディング中はすぐにフィードバックしてほしい ▪ 1 秒も待ちたくない!
rubocop-daemon gem を作りました (2018 年)
RuboCop 本体に 取り込まれました 🎉 (2022 年) https://github.com/ruboco p/rubocop/pull/10706 Big Thanks
to @koic
詳しくは RubyKaigi 2022 の @koic さんの発表にて https://speakerdeck.com/koic/make-rubocop-super-fast
注意事項 • 今回は rubocop-daemon の実装を紹介します ◦ RuboCop の Server Mode
と内部実装は同じなので、読み替え可能 ◦ rubocop-daemon と Server Mode はコマンド体系が少し異なります ◦ 詳細はドキュメントを参照してください : https://docs.rubocop.org/rubocop/usage/server.html
RuboCop はコマンド実行のたびに読み込み直すから遅い • 通常の RuboCop はコマンド実行のたびに RuboCop を読み込む $ rubocop
… require 'rubocop' RuboCop::CLI.new.run ターミナル RuboCop $ rubocop … require 'rubocop' RuboCop::CLI.new.run
RuboCop はコマンド実行のたびに読み込み直すから遅い • この中でも require 'rubocop' が遅い $ rubocop …
require 'rubocop' RuboCop::CLI.new.run ターミナル RuboCop $ rubocop … require 'rubocop' RuboCop::CLI.new.run
require 'rubocop'は遅い % ruby -rbenchmark -e '$LOAD_PATH.unshift("/path/to/rubocop/lib"); Benchmark.bm { |x|
x.report { require "rubocop" }}' user system total real 0.573636 0.217166 0.790802 ( 0.815585) https://github.com/rubocop/rubocop/pull/10706#issuecomment-1152382752
require 'rubocop'は遅い • require 'rubocop' のみで約 0.8 秒かかる ◦ RuboCop
のコア機能である「lint」は処理していない ▪ lint するともう少し時間はかかるが、 1 ファイルだけであれば短い ▪ ファイル数に比例して長くなる
require 'rubocop'は遅い • 💡 つまりこれをキャッシュすればよいのでは? ◦ これが rubocop-daemon のアプローチ
rubocop-daemon の高速化アプローチは単純 • require 'rubocop' したプロセスを サーバーとして用意 (デーモン化) ◦ このサーバーにリクエストする
◦ アプリケーションサーバーを起動し続け、リクエストを待ち受けて処理するのと同じ rubocop-daemon (server) $ rubocop-daemon exec … ターミナル $ rubocop-daemon exec …
rubocop-daemon の RuboCop 実行フロー • rubocop-daemon をサーバーとして起動する rubocop-daemon (server)
rubocop-daemon の RuboCop 実行フロー • rubocop-daemon サーバーにリクエストする ◦ サーバーでは RuboCop
の内部メソッド (RuboCop::CLI#run) を 呼び出している rubocop-daemon (client) rubocop-daemon (server) 1. RuboCop 実行 リクエスト
rubocop-daemon の RuboCop 実行フロー • サーバーが lint 結果を返す rubocop-daemon (client)
rubocop-daemon (server) 1. RuboCop 実行 リクエスト 2. 実行結果返却
❯ ruby -rbenchmark -e 'Benchmark.bm { |x| x.report { `rubocop
/path/to/file 2>&1 >/dev/null` }}' user system total real 0.000099 0.000637 0.602601 ( 0.886394) ❯ ruby -rbenchmark -e 'Benchmark.bm { |x| x.report { `rubocop-daemon exec -- /path/to/file 2>&1 >/dev/null` }}' user system total real 0.000050 0.000564 0.073490 ( 0.090813) • 実行時間が 0.89 秒 -> 0.09 秒 (約 10 倍速) に短縮 🎉 rubocop-daemon で 10 倍弱高速化できる
余談: 今は LSP Mode もある • RuboCop 1.53 から LSP
Mode が追加された ◦ https://docs.rubocop.org/rubocop/usage/lsp.html • LSP = Language Server Protocol ◦ VSCode 発 ◦ エディタ上でコード補完や定義元ジャンプなど様々な機能を提供するための プロトコル ▪ LSP サーバーに対し、エディタがサーバーに問い合わせる ▪ Server Mode と同じような仕組み
LSP Mode と Server Mode はプロトコルが違うだけ • LSP Mode: LSP
を喋る ◦ JSON-RPC でフォーマットが策定されている ◦ 通信は TCP/IP が多い • Server Mode: 独自プロトコルを喋る ◦ "#{token} #{dir} #{command} #{args}\n#{body}" というフォーマット ▪ RuboCop では version 情報が追加されていたりする ◦ 通信は TCP/IP
エディタから使うなら LSP Mode がよさそう • LSP は多くのモダンなエディタで実装されている ◦ プラグインが提供されている場合も多い •
Server Mode だと、エディタが Server Mode の プロトコルを喋る必要がある ◦ それ用の実装が必要 ◦ エディタから rubocop コマンドを実行するのも手 ▪ ただしサーバーに通信するための処理もあるので若干のオーバーヘッドがある
(再掲) 持ち帰ってほしいこと • Server Mode で RuboCop の起動を高速化できる ◦ プロセスを永続化することで高速化
(宣伝) 明日裏話をします Omotesando.rb #95 にて OSS の苦悩をはなします