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
400
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
Data Access Control で実現するより細かい権限制御
fohte
0
130
Datadog が支える Wantedly のシステム運用
fohte
0
56
Devin や Cursor などの生成 AI ツール導入に向けて何を取り組んだのか
fohte
2
280
Datadog Network Monitoring を活用して NAT Gateway 課金を 80 % 削減した話
fohte
2
700
Trace Metrics と Istio Metrics でサービス健全性を監視する
fohte
0
490
段階的リリースを実現する kube canary
fohte
1
210
巨大 tfstate に立ち向かう技術
fohte
1
1k
RubyKaigi で LT 初登壇したきっかけと感想
fohte
1
1.3k
Datadog Logs を活用して SLO 監視基盤を構築する
fohte
3
2.7k
Featured
See All Featured
Balancing Empowerment & Direction
lara
5
740
Unsuck your backbone
ammeep
671
58k
GitHub's CSS Performance
jonrohan
1032
470k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Building Flexible Design Systems
yeseniaperezcruz
329
39k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.8k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Being A Developer After 40
akosma
91
590k
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
How STYLIGHT went responsive
nonsquared
100
5.9k
The Cost Of JavaScript in 2023
addyosmani
55
9.2k
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 の苦悩をはなします