WASI 0.3、Component Model 非同期 ABI を組み込み ratify
WASI Subgroup は WASI 0.3.0 を ratify し、仕様を安定版とした。WASI 0.2 で wasi:io が担っていた pollable・入出力ストリームは Component Model の canonical ABI に取り込まれ、stream<T>・future<T>・async が第一級の型として定義される。0.2 から 0.3 へのインターフェース変更の多くは機械的な置き換えにとどまる。
0.2 では各コンポーネントが独自のイベントループを持ち、ストリーミングや非同期 API を使うコンポーネントは他コンポーネントと合成できなかった。0.3 ではホストが全コンポーネント共有のイベントループを管理し、ランタイムがスケジューリングを担う。非同期モデルは readiness ではなく completion ベースで、async func を直接 import/export できる。0.2 の start-foo / finish-foo / subscribe という三段階の呼び出しは不要になる。
ストリームの終端エラーは、0.2 では読み取りごとにインラインで返され、読み取りを途中で止めると正常終了とエラーを区別しにくかった。0.3 ではストリーム本体とは独立して解決する future を併せて返し、消費量に依存せず状態を追える。
wasi:http は wasi:http/service と wasi:http/middleware の二つの world に再編された。middleware は 0.2 の proxy world に代わり、リクエストを下流の handler へ渡せる。service chaining により、マイクロサービス同士をネットワーク越しではなく同一プロセス内で直接合成できる。ランタイムがプロセス内合成を選べば、サービス間呼び出しはミリ秒からナノ秒規模に短縮できるとされる。
利用可能時期は次のとおりである。
- 仕様は安定版。今日コンパイルしたプログラムは将来も動作が保証され、0.3.x のパッチはおおむね二か月ごとに出る。
- Wasmtime 45 が最新 RC を実行可能。Wasmtime 46 で WASI 0.3.0 と Component Model Async がデフォルト有効になる。
- JavaScript 向け toolchain の jco は WASI 0.3 をサポート済みで、デフォルト有効化は近いリリースで予定されている。
- Rust・Go・JavaScript・Python などの guest toolchain 向け対応は並行して進行中である。
バインディング生成器は async func を各言語の慣用的な非同期 API に写像できる。Rust の wit-bindgen では wasi:http/handler の handle: async func が async fn handle になる。Python・JavaScript・C#・C 向けの guest バインディングも進行中で、Go は goroutine 上のブロッキング呼び出しを ABI 境界で park/resume する componentize-go の経路がある。
WASI 0.2 (wasi:io) | WASI 0.3 (Component Model) |
|---|---|
resource pollable | future<T> |
resource input-stream | stream<T> |
resource output-stream | stream<T>(書き込み方向) |
poll(list) | future への await(ランタイム処理) |
リソースの subscribe() | 呼び出しが future<...> を返す |
start-foo / finish-foo | foo: async func(...) |