WASI 0.3.0 版本正式发布
速览
WASI 0.3.0 版本现已正式发布。该版本继续完善 WebAssembly 系统接口,旨在提升 WebAssembly 在更广泛场景下的互操作性与安全性。此次更新为开发者提供了更稳定的 API 支持,推动了 WebAssembly 生态的演进。
AI 深度解读
WASI 0.3.0 发布:异步原生化与组件模型的重构
背景
WebAssembly System Interface (WASI) 是 WebAssembly 在非浏览器环境(如服务器、边缘计算、边缘设备)中访问系统资源的标准接口。随着 WebAssembly 从简单的沙箱脚本向更复杂的系统级应用演进,其接口设计需要适应现代编程范式,特别是异步 I/O 和组件模型(Component Model)的发展。
此前,WASI 0.2 版本在支持异步操作时采取了一些“变通”手段(acrobatics),因为当时的 WebAssembly 组件模型尚未原生支持异步原语。这导致开发者在编写代码时需要处理复杂的中间状态和资源传递,API 的使用体验并不 ergonomic(易用/符合人体工程学)。
随着 WebAssembly 组件模型原生支持异步(async),WASI 子组(WASI Subgroup)投票正式批准了 WASI 0.3.0 版本。这一版本的核心目标是将 WASI 重新建立在组件模型的异步原语之上,从而简化接口设计,消除之前为了模拟异步而引入的复杂性。
核心内容
WASI 0.3.0 的变更主要集中在接口层面的重构,旨在利用组件模型的原生异步能力,使 API 更加直观和简洁。以下是各个核心包的具体变更解读:
1. wasi:cli(命令行接口)
wasi:cli 的文件结构保持不变(包括 stdin.wit、stdout.wit、stderr.wit、run.wit、exit.wit、terminal.wit、environment.wit),但 stdio 的处理方式发生了根本性变化。
- WASI 0.2 模式:
stdin返回一个input-stream对象,开发者需要从中读取。stdout返回一个output-stream对象,开发者通过命令式方式(imperatively)向其写入数据。
- WASI 0.3 模式:
stdin:通过read-via-stream函数,返回一个元组,包含stream<u8>和一个future<result<_, error-code>>。stdout:方向发生翻转。开发者不再获取流对象,而是直接传入一个stream<u8>数据流,并接收一个future,该future在写入完成时解析。- 新增类型:引入了
wasi:cli/types接口,包含共享的error-code变体(如io、illegal-byte-sequence、pipe)。
这种变化使得 I/O 操作更符合异步编程的自然流向:数据作为参数传入,结果通过 Future 返回。
2. wasi:sockets(网络套接字)
网络访问模型从基于资源的能力传递(capability resource threading)转变为基于世界导入(world imports)的直接访问。
- 资源简化:WASI 0.2 中的
network资源被移除。在 0.2 中,网络访问需要通过能力资源传递给每个bind/connect/lookup调用。0.3 中,网络访问权限直接通过世界导入授予。 - 异步函数合并:
- WASI 0.2 中,每个网络操作分为“开始”和“完成”两个阶段(如
start-bind/finish-bind),并依赖subscribe()返回的pollable来驱动状态机。 - WASI 0.3 中,这些成对的函数合并为单一的
async func。 - 例如,
bind、connect、listen、accept现在都是异步函数,直接返回结果或错误码。
- WASI 0.2 中,每个网络操作分为“开始”和“完成”两个阶段(如
- TCP/UDP 统一:
- TCP 的
finish-connect不再内联返回 TCP 流对,而是返回普通结果;字节 I/O 现在通过套接字资源自身的流方法处理。 - UDP 的入站/出站数据报流资源被移除,替换为简单的
async send和async receive。 - 错误码统一:TCP、UDP 和名称查找的错误码合并为单一的
error-code变体,新增了connection-broken情况,并保留了开放的other(option<string>)尾部以容纳自定义错误。
- TCP 的
3. wasi:http(HTTP 客户端与服务器)
这是本次发布中可见度最高的重组部分,主要涉及资源数量的大幅缩减和处理器(Handler)模型的现代化。
- 资源合并:
- WASI 0.2 拥有复杂的资源矩阵,涵盖入站/出站 × 请求/响应/正文,以及两个异步专用资源(
future-trailers,future-incoming-response),共计 8 种资源。 - WASI 0.3 仅保留
request和response两种资源。 - 正文(Body)直接表示为
stream<u8>。 - 尾部(Trailers)表示为
future<result<option<trailers>, error-code>>。 future-incoming-response消失,因为普通的future<result<response, error-code>>已足以胜任。
- WASI 0.2 拥有复杂的资源矩阵,涵盖入站/出站 × 请求/响应/正文,以及两个异步专用资源(
- Handler 模型异步化:
- WASI 0.2 的
incoming-handler使用response-outparam参数来绕过缺乏原生异步返回值的限制。 - WASI 0.3 的
handler是一个异步函数,直接返回result<response, error-code>。 - 客户端侧的
client接口同样镜像了这一变化,send函数变为异步,直接返回响应结果。
- WASI 0.2 的
- 中间件支持:
- 旧的
proxy世界被service世界取代。 - 新增
middleware世界,既导入又导出handler。这为处于请求路径中的组件提供了原生支持:world service { import wasi:cli/stdout; import wasi:cli/stderr; import wasi:cli/stdin; import client; export handler; } world middleware { include service; import handler; // 上游处理器 }
- 旧的
4. wasi:filesystem(文件系统)
文件系统的 I/O 操作也切换到了 stream 加 future 的模式。
- 流式读写:
read-via-stream:现在返回tuple<stream<u8>, future<result<_, error-code>>>,允许并发读取并等待完成状态。write-via-stream:接受stream<u8>和偏移量,返回future<result<_, error-code>>。
- 目录迭代:
- 从基于资源的迭代器(
directory-entry-stream)切换为流。 read-directory现在返回tuple<stream<directory-entry>, future<result<_, error-code>>>,简化了目录遍历的实现。
- 从基于资源的迭代器(
5. wasi:clocks(时钟)
此部分的变更主要是命名规范化,旨在与生态系统其他部分(如 POSIX、Rust std::time)保持一致。
- 重命名:
wall-clock更名为system-clock。datetime更名为instant。wasi:filesystem中的时间戳类型也相应更新。
- 类型共享:新增
types.wit以共享duration = u64别名。 - 单调时钟简化:
monotonic-clock移除了返回pollable的subscribe-instant和subscribe-duration调用。调用者现在直接await主机提供的定时器future,这与 WASI 其他部分的模式保持一致。
关键要点
- 异步原生化:WASI
