2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
リンクをコピー
記事をブックマーク
齋藤優太氏(以下、齋藤):いやぁ~、緊張しますね(笑)。みなさんおはようございます。
会場:おはようございます。
齋藤:「Ruby meets WebAssembly」ということで、今日は最近少し話題になっているRubyとWebAssemblyの話をしようと思います。よろしくお願いします。
(会場拍手)
RubyがWebAssembly上で動くようになったので、今日の話はその紹介になります。何事もなければRuby3.2の機能として出荷される予定です。今日は始めに、なぜWebAssembly対応をするのかというモチベーションを紹介して、RubyのWasm対応デモを交えながらWebAssemblyのユースケースについて紹介します。後半は、Wasm対応にあたってどのようなことをしたのかという具体的な技術的な内容になると思います。
あらためまして、Rubyのコミュニティでは初めましての方が多いと思うので、少しだけ自己紹介をさせてください。齋藤といいます。インターネットでは「kateinoigakukun」というハンドルネームで活動しています。本業は早稲田大学の学生なのですが、GoodNotesというノートアプリの会社で、ソフトウェアエンジニアとしても働いています。
Rubyとの関わり方としては、2021年のKeynoteで、遠藤さん(Yusuke Endoh氏)が紹介されていたTypeProf for IDEのお手伝いをクックパッドのインターンとしたり、秋頃からは、CRubyのWebAssembly対応の作業をやっています。その流れで2022年の頭からは、CRubyのコミッターとしてWasmポートのメンテナーをしています。
SwiftでもコミッターとしてWebAssembly対応をやっていたり、Link-time-optimizationの実装や、コンパイラからインタプリタまでいろいろとやっています。
さっそくですが、内容に入っていきましょう。始めに、モチベーションですね。RubyとSwiftって何から何まで違う言語ですよね。そんな2つの言語でコミッターをしている変な人なんですが、もちろんRubyは大好きな言語です。
なんといってもRubyは書いていて楽しいですよね。さっと書けるし、文字どおりなんでもできる言語なので、思ったとおりに自由にプログラムが書けます。ライブラリもエコシステムも成熟しているので必要な機能をさっと作れる、これも良い部分ですね。
そうは言っても、Rubyにはなかなか難しいところもあります。当たり前のことかもしれませんが、Rubyで書いたプログラムを実行するためには、Rubyインタプリタを実行するマシンにインストールする必要があります。例えばWebブラウザ、モバイルOSなど、制限された環境だと、特にCRubyをインストールするのは難しいです。
というわけで、ユーザーにRubyをインストールさせない場合、たいていサーバーサイドで実行することになると思います。ただこれは、プログラムのユーザーにとっては優しいですが、プログラムの開発者にとっては優しくありません。特にちょっとしたプログラムを公開したいだけの場合、サーバーの管理コストとかは考えたくないですよね。
それからもう1つ大きな難しさとして、Rubyのインストールバトルがあります。Rubyのインストールは初学者が躓きがちなポイントで、環境ごとにトラブルシュートする必要がある難しい問題です。今ではruby-buildなどでかなり簡単になっていますが、それでも「BUILD FAILED」という文字列を何度も見たことがあると思います。
これらの難しさを解消することは、Rubyへの入り口を広げるだけではなく、みなさんの日々のプログラミングライフの中でRubyを使える機会を増やせるんじゃないかなと思います。
さて、ではどうやってこれらの難しさを解消するのがよいでしょうか? その選択肢の1つがWebAssemblyです。WebAssemblyははっきり言ってしまうと、プログラムの配布形式におけるゲームチェンジャーです。
おそらく名前しか聞いたことがないという方もいるので軽く解説すると、WebAssemblyはスタックマシン向けの命令フォーマットの仕様です。これはその名のとおり、Webブラウザでプログラムを動かすことをメインの目的として設計されています。
アーキテクチャやプラットフォームに依存せずにポータブルであること。ソースの言語に非依存であること。第三者から提供された信頼できないプログラムを安全に実行できること。というのがメインのデザインゴールとなっています。
WebAssemblyが何を解決するのかというのを先ほどの課題と照らし合わせてみると、現代では、どの環境にもブラウザがありますよね。Rubyがブラウザで動くようになれば実質的にどこでも動くようになります。ということで、プラットフォームサポートの幅がぐんと広がりますね。
もう1つのインストールの問題ですが、ブラウザ上で動けば明示的なインストールが必要なくなるので、初学者が環境構築で躓くことがぐんと減るのではないかと思います。
WebAssemblyのレイヤーとしては、C、C++、Swiftなどのさまざまな言語からコンパイルされるx86やARMと同様となります。コンパイルされた.wasmのファイルは、Webブラウザ上で実行されます。
具体的には、まずはコンパイラで.wasmファイルを作って、ブラウザ上でJavaScriptを使って、.wasmファイルをダウンロードして、最後にブラウザの実行エンジンでWasmプログラムを起動するという流れになっています。
さて、ここでCRubyを使ってRubyをブラウザ上で動かす場合を考えていきましょう。流れとしては、Cで書かれたRubyインタプリタを.wasmファイルにコンパイルして、それをブラウザ上にロードして、起動されたRubyインタプリタでRubyプログラムを実行します。
さて、ここで、どのぐらい手軽にブラウザで動かせるのかをデモしたいと思います。こんな感じでscriptタグを読み込みます。ここでRubyインタプリタがロードされているので、Rubyのスクリプトを書くことができます。「 type="text/ruby"」。なかなかかっこいいですね。
これでRubyを書けるので、とりあえず適当にHTTPサーバーを立てます。実際にブラウザで起動してみると「Hello」が表示されていますね。
(会場拍手)
というわけで、Rubyがブラウザで動いています。「やったね!」ということで。でも「Hello」というワードだけではつまらないですよね。もう少し複雑な、今日の運勢を占ってみましょう。先ほどと同じようにscriptをロードしておいて、とりあえずJavaScriptとの連携が見たいですね。このようにJavaScriptライブラリがあるので、こんな感じでRubyが書けます。
(会場拍手)
JavaScriptとも無事に連携できましたね。ここからおみくじを引いていきたいです。ズルをします。JavaScriptのAPIがそのままRubyのプログラムとして自然に書けます。これはRubyの表現力のおかげですね。これでイベントリスナーが書けて、ブロックでコールバックできるようになったので、ここで今日の運勢をサンプルしてみましょう。結果をDOMに書き込みます。
ということで、なんかエラーが出ていますが……なんて言っているんでしょうか。「undefind、buton」綴りが違うんですね。「t」が足りないと。今度こそ、いけていそうですね。おみくじを引きます。「あ〜、Unlucky」。
(会場笑)
これは何度でも引けるんですよね。「Lucky」になりました。
(会場拍手)
ということで、Rubyでおみくじが書けました。これはおもちゃですよね。もうちょっと複雑なデモをしたいと思います。今のコードは、github.com/ruby/ruby.wasmというリポジトリにあるので、あとでチェックしてみてください。
これが本題ですね。次のデモは、なんとirb(Interactive Ruby)が動きます。これ見えますかね? 普通のirbですね。これはブラウザで動いているんですよ。コンソールじゃないんですよ。ここで時間を表示してみますか。UTCですね。ここ実は、gemがインストールできて、syntax_treeというRubyのフォーマットがあったり、lintだったりできるやつがあるんですけど。
これはピュアRubyで書かれているので、ここのデモにちょうどいいんですよね。なかなかダウンロードが終わらないですね。…本当だ。これだからデモは怖いですね(笑)。今度はなんだ。gemだ、本当だ(笑)。みなさんのほうが詳しいですね。
(会場笑)
ようやくインストールできました。これで……え、今度は何。なんだなんだ。いいや、こっちができたので、じゃあsyntax_treeはいったん置いておいて、SVGのデモをしましょう。これはSVGをRubyで組み立てられるgemで、今適当に書いたんですが、こんな感じでSVGが生成されるわけですね。これはブラウザ上で動いているので、これをそのまま表示してみましょう。
(会場拍手)
よかった。こっちはうまくいった。ということで、irbがだいたい動きます。こちらはインターネットに公開しているので、ぜひお気に入りのgemで試してみてください。
いかがでしたか? ここからは、今デモしたWebAssemblyがどのように動いているのかを紹介します。
実はバニラなWebAssembly自体には、ファイルシステムへのアクセス方法は既定されていません。システムの時計にもアクセスできませんし、もちろんネットワークにもアクセスできません。では、先ほど見たTime.nowは何を返しているのでしょうか? お察しのとおり、WebAssembly自体でできないことは外側のホスト環境、ここではJavaScriptにやってもらおうという感じになっています。
実際にTime.nowが呼ばれると、CRubyの中でclock_gettimeシステムコールが呼ばれて、最終的にData.nowが呼ばれて結果が返ってくるわけですね。
ただ、ここでWebAssemblyが今やWebだけのものではなくなってきているという話が出てきます。sandboxによるセキュリティ機構やバイナリのポータビリティは、Webブラウザ以外の場所でもうれしいですよね。
例えば、サーバーレスプラットフォームはだいたい関数のロジックをデプロイするわけですが、プラットフォーム側がWasmさえサポートしていれば、ユーザーはいろいろな言語でロジックを書けるわけです。これはプラグインシステムなどでも同じようなうれしさがあると思います。というわけで、WebAssemblyはブラウザのJavaScriptと常に一緒に実行されるわけではないという状況になってきています。
そこで、WASIという標準化されたシステムコールの仕様が出てきました。WASIは、WebAssembly System Interfaceの略で、プラットフォームに非依存なシステムコールインターフェイスを定義します。システムスタックとしては、MuslなどのlibcがWASIのインターフェイスを通して実際のWASIの実装を呼び出します。
ここ数年、Node.js、Deno、WasmをCLIから実行するWasmtime、サーバーレス環境であるFastlyのCompute@EdgeやCloudflare Workers。また最近は、VSCodeの拡張機能がWASI対応をしたり、ログ収集ツールのFluent BitのプラグインシステムがWASIをサポートしたりしています。
また、言語側でもサポートが広がっています。CやC++、Rust、Swiftなどがサポートしていて、ここに今回Rubyが加わりました。ただ、他の言語とちょっと事情が違うのが、RubyはRubyインタプリタと.rbファイルを配布しないといけません。
あとは、そもそもWasmに対応しているブラウザ以外の環境だと、だいたいOne Binaryしか受け付けてくれないんですよね。「.rbファイルを別途ホストのファイルシステムに配置してから起動してくださいね」というのはなかなか面倒ですよね。というわけで、ホストから読み取っていた.rbファイルを、こうしてバイナリに埋め込むためのwasi-vfsという仮想ファイルシステムを開発しました。とりあえずRubyを動かすためにRead-onlyなインメモリのファイルシステムをサポートしています。
このVFSは、WASIのインターフェイスをプロキシする感じで動くので、実はRuby以外でも使えます。風の噂でCPythonがこれで使えたと聞きました。
ブラウザ以外で動く例として、サーバーレスのデモをしたいと思います。先ほど名前を出したFastlyのCompute@Edgeで動くデモを作ってきました。
今回のスクリプトはこんな感じです。FastlyのCompute@Edgeは、HTTPリクエストをCDNのEdgeサーバーでハンドルするサービスなので、リクエストを受け取ってレスポンスを返すロジックを書いていきます。
リクエストを受けるとWasmファイルは実行されるので、トップレベルにレスポンスを組み立てるロジックを書いていきます。これは単純にHTMLを組み立てて、現在の時間をTime.nowでWASIのインターフェイスを通して取得して、あとはRubyのバージョンや環境を書き出して、クライアントに送ります。
この.rbファイルをこんな感じで.wasmファイルに埋め込みます。この.wasmファイルにはRubyインタプリタと.rbファイルが含まれているわけですね。
今のスクリプトをデプロイした環境がこちらです。アクセスしてみてください。というわけでRubyがEdgeで動きました。
(会場拍手)
でもこれはクライアントと見分けがつかないですよね(笑)。
(会場笑)
リロードすると時間が増えます。楽しい。という感じです。
内容に戻ると、Ruby3.2ではWebAssemblyとWASIのサポートが入ります。ポートしたRubyがむき出しの状態だとみなさん使いにくいと思うので、ruby.wasmというリポジトリで、npmパッケージとビルド済みのWasmファイルを配布しています。実は先ほどのデモも、このnpmパッケージを使ってちょちょいと作っていました。みなさんぜひお気軽にお試しください。
(次回へつづく)
関連タグ:
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05