Skip to content

Instantly share code, notes, and snippets.

@mame
Created March 21, 2024 03:12
Show Gist options
  • Save mame/c69bcc2d7b4c1b109180b2bda5ebb443 to your computer and use it in GitHub Desktop.
Save mame/c69bcc2d7b4c1b109180b2bda5ebb443 to your computer and use it in GitHub Desktop.

Rubyアソシエーション開発助成金2023 メンター報告書

  • プロジェクト: Ruby Playground for CRuby Developer
  • 開発者: 齋藤 優太
  • メンター: 遠藤 侑介

プロジェクト概要

プルリクエストをレビューする際、不具合が確かに修正されていることを確認したり、新機能の使い勝手を試したりするために、その変更を実際に動かしたいことがしばしばある。特にRuby開発の場合、新しい構文やメソッドの提案を実際に動かして実験することで、読み書きのしやすさやコーナーケースの挙動を評価することは非常に重要である。

Webアプリの開発では、この目的のために「ステージング環境」と呼ばれる検証用環境を用意するプラクティスがある。しかし通常、ステージング環境には設置・維持管理コストがかかる。そのため、余力のあるチームでしか利用されていない。

このプロジェクトでは、RubyのWebAssembly/WASIビルドとCIを活用して、プルリクエストの変更内容を誰でもビルドなしでブラウザ上で手軽に試せる仕組みをRuby本体向けに開発する(便宜上、この仕組みをサーバレスステージングと呼ぶことにする)。

計画の達成状況

期待を大幅に上回る速度・品質で進捗し、大きな成果を残した。

プレイグラウンドの開発

プルリクエストの変更内容をブラウザ上で試すことができるプレイグラウンドを開発した。これはすでにGitHub Pagesに設置されている。

https://ruby.github.io/play-ruby

このプレイグラウンドは、対応するプルリクエストのGitHub Actionsで生成されるWebAssembly/WASIビルドのアーティファクトを読み込み、実行する。この工夫により、追加のメンテナンスコストをほとんど発生させずに実現された。

この開発には、実験や細かいUI改善を含めて、2週間程度で完了した。

WebAssembly/WASIのRubyGems / Bundler対応

サーバレスステージングを一般のRubyプログラムに広げていくためには、外部Gemを利用できることが不可欠である。そこで、Gemfileに指定されたGemをWebAssembly/WASIにパッケージするツールrbwasm buildを開発した。

ruby/ruby.wasm#358

この開発は、およそ1ヶ月程度で完了した。その後、第三者がrbwasm buildを活用してRailsアプリをブラウザ上で動作させることに成功したことが報告された。

https://twitter.com/palkan_tula/status/1758008374128697708

WebAssembly/WASIの拡張ライブラリを含むGemの対応

残りの期間は、拡張ライブラリを含むGemの対応に費やした。これはRubyのWebAssembly/WASIビルドの長年の課題で、2つの大きなチャレンジがあった。

  1. RubyのWebAssembly/WASIビルドが拡張ライブラリをロードできるようにする
  2. RubyGemsでクロスビルドができるようにする(WebAssembly/WASIに限らない長年の課題)

このプロジェクトでは、次の開発を行い、1つめの課題を解決した。

  • WebAssembly/WASIの最新仕様であるWasm Component Modelを利用したdlopen相当を実装した。
  • RubyのWebAssembly/WASIをPICビルドに対応させた。
  • Wasm Component Modelのバイナリ生成ツールをAsyncifyに対応させた。

また、2つめの課題を解決するために、次の作業と試作を行った。

  • Ruby本体やrake-compilerが拡張ライブラリをどのようにクロスビルドを行っているかを調査した。
  • それを踏まえ、mkmf本体でクロスビルドをサポートさせる方針を立て、改良を試作した。
  • 改良されたmkmfと、代表的な拡張Gemであるnokogiriを用いて、拡張Gemのクロスビルド対応の方針を立案した。
  • RubyGemsやBundlerにクロスビルドを対応させる方針を検討した。

現在、mkmfへの変更を提案し、採択されたところである。

https://bugs.ruby-lang.org/issues/20345

メンターとして果たした役割

週1回、進捗を確認するオンラインミーティングを行い、問題や解決方法について議論した。 WebAssembly/WASIについては開発者自身が非常に詳しいので、メンターとしては主にMRI特有の注意点をコメントしたり、デモの見せ方について意見したりした。

まとめ

本プロジェクトでは、プルリクエストの変更内容を誰でもブラウザ上で手軽に試せる仕組み(サーバレスステージング)をRuby本体向けに開発した。RubyのWebAssembly/WASIビルドとGitHubのインフラを巧みに利用することで、ほとんど追加コストなしで実現されている。

また、この仕組みを一般のRubyプログラムの開発でも利用可能にしていくための準備として、RubyのWebAssembly/WASIビルドの最大の課題のひとつであった拡張ライブラリ対応問題を解決した。加えて、RubyGemsのクロスビルド対応という(WebAssembly/WASIビルドに限らない)別の大きな問題を解決する目処を立てた。

メンター(遠藤)は当初サーバレスステージングの利便性にやや懐疑的であったが、極めて低コストで導入できたこと、実際のRuby本体の開発で利用されはじめたことをみて、そのポテンシャルの高さに驚いた。Ruby本体に限らず、一般のプログラムの開発でもいずれ活用されはじめ、WebAssembly/WASIのキラーアプリのひとつになるのではないかと期待している。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment