大小仅为Rust四分之一!MoonBit 现已支持Wasm组件模型

news2024/11/24 5:45:14

使用 MoonBit 开发 Wasm 组件模型

在这里插入图片描述

Wasm组件

WebAssembly(Wasm)是一种新的低级虚拟指令集标准(low-level virtual instruction set standard),用于沙箱模型。低级的,意味着它接近原生速度。虚拟的,意味着它可以在包括浏览器和操作系统在内的多个运行时(runtime)上运行,例如wasmtime或wamr。它是沙箱模型,这意味着它不能与外界交互,除非使用FFI。不过FFI只能返回数字,因此通过线性内存进行数据传输是更有效的方法。许多编程语言都可以编译成Wasm,包括Java、JavaScript/TypeScript、Python、Rust以及当然还有MoonBit。

那么如何结合用不同编程语言实现的Wasm组件呢?我们便需要引入组件模型(component model),一个统一接口的提案。通过组件模型,我们可以定义一个高级抽象的API。只要接口匹配,组件就可以与不同组件结合。

本文将介绍如何使用MoonBit编写一个输出“Hello World”的小型HTTP服务器。通过本教程我们可以看出,MoonBit在开发Wasm组件模型时实现了高兼容性和互操作性,同时能够显著减少输出大小。

操作步骤

我们将编写一个小型HTTP服务器,它将使用MoonBit打印“Hello World”。先决条件如下:

  • wit-deps

  • wit-bindgen with MoonBit(目前需要从源代码构建,因此还需要Rust工具链)

  • wasm-tools

  • wasmtime

  • 当然还有MoonBit工具链。

定义WIT(Wasm Interface Type)

首先,你需要使用WIT定义接口(如何使用详见官方手册)。

wit/deps.toml中指定依赖项。本教程中仅使用wasi-http版本0.2.0。

http = "https://github.com/WebAssembly/wasi-http/archive/v0.2.0.tar.gz"

使用wit-deps更新依赖项,在wit/deps文件夹中可以看到所有依赖项。

然后我们在wit/world.wit中指定“世界”对应于生成的Wasm:

package moonbit:example;

world server {
  export wasi:http/incoming-handler@0.2.0;
}

一个“世界”可以包含其他“世界”,或导入/导出接口。这里我们导出wasi:http版本0.2.0的incoming-handler接口,因为HTTP服务器需要导出一个传入处理程序接口,以便运行时可以使用它来处理传入请求并生成响应。

生成代码

在这一步骤,我们会使用wit-bindgen生成代码。你可以利用这个命令安装:

cargo install wit-bindgen-cli --git https://github.com/peter-jerry-ye/wit-bindgen/ --branch moonbit

获得wit-bindgen命令后,只需使用适当的子命令(moonbit)和WIT文件的位置(wit)执行它。还有参数用于指定类型是否应派生Showtrait 或Eqtrait。

wit-bindgen moonbit wit --derive-show --derive-eq --out-dir .

你将获得以下内容:

.
├── ffi
│  ├── moon.pkg.json
│  └── top.mbt
├── gen
│  ├── ffi.mbt
│  ├── interface_exports_wasi_http_incoming_handler_export.mbt
│  ├── moon.pkg.json
│  └── worlds_server_export.mbt
├── interface
│  ├── exports
│  │  └── wasi
│  │     └── http
│  │        └── incomingHandler
│  │           ├── moon.pkg.json
│  │           ├── README.md
│  │           └── top.mbt
│  └── imports
│     └── wasi
│        ├── clocks
│        │  └── monotonicClock
│        │     ├── moon.pkg.json
│        │     ├── README.md
│        │     └── top.mbt
│        ├── http
│        │  └── types
│        │     ├── moon.pkg.json
│        │     ├── README.md
│        │     └── top.mbt
│        └── io
│           ├── error
│           │  ├── moon.pkg.json
│           │  └── top.mbt
│           ├── poll
│           │  ├── moon.pkg.json
│           │  ├── README.md
│           │  └── top.mbt
│           └── streams
│              ├── moon.pkg.json
│              ├── README.md
│              └── top.mbt
├── moon.mod.json
├── wit // contents ignored here
└── worlds
   └── server
      ├── import.mbt
      ├── moon.pkg.json
      └── top.mbt

生成的项目有四个文件夹:

  • ffigen是生成的帮助Wasm绑定的文件,可以忽略。gen目录包含项目入口。

  • interface包含所有导入到所选“世界”的接口。分为importsexportsimports提供所有导入的函数和类型,而exports包含你所要导出的函数以及一个空实现(panic())。

  • worlds包含"世界"。与interface类似,它包含一个import.mbt,提供“世界”级别的导入函数和类型,以及一个top.mbt,包含导出函数的模板。

然后你可以像开发一般MoonBit应用一样继续开发。此时moon check --target wasm应该能够成功通过。你可以通过运行moon doc --serve查看API以及类型或函数的注释文档。别忘了执行moon fmt来格式化程序。

开发

以下是我们用于演示的实现最小输出的“Hello-World”服务器代码:

pub fn handle(
  request : @types.IncomingRequest,
  response_out : @types.ResponseOutparam
) -> Unit {
  let response = match request.path_with_query() {
      None | Some("/") => make_response(b"Hello, World")
      _ => make_response(b"Not Found", status_code=404)
    }
    |> Ok
  response_out.set(response)
}

fn make_response(
  body : Bytes,
  ~status_code : UInt = 200
) -> @types.OutgoingResponse {
  ...
}

完整示例见moonbit-docs/examples/wasi-http。

组件化

我们已经实现了一个核心Wasm,即一个遵循WebAssembly标准的Wasm。然而,我们需要将其转变为一个组件,以便可以将必要的信息——接口——一并分发。

你需要使用wasm-tools将核心Wasm嵌入到组件中。首先将WIT信息嵌入到核心Wasm的自定义部分中,此步骤需要指定编码为UTF-16。然后我们将核心Wasm转换为组件Wasm。

moon build --target wasm
wasm-tools component embed wit target/wasm/release/build/gen/gen.wasm -o target/wasm/release/build/gen/gen.wasm --encoding utf16
wasm-tools component new target/wasm/release/build/gen/gen.wasm -o target/wasm/release/build/gen/gen.wasm

如果你更喜欢使用npmpnpm,也可以使用JCO来完成此步骤。

使用

利用我们创建的Wasm,可以使用Wasmtime进行托管:

wasmtime serve target/wasm/release/build/gen/gen.wasm

你也可以使用JCO在Node.js或Deno上进行服务,或者使用WasmCloud或Spin进行托管。

比较

在这里插入图片描述

至此,我们已经实现了一个简单的仅输出 “Hello World” 的 HTTP 服务器。下表为 MoonBit 与主流编程语言生成的http-hello-world大小对比(基于WasmCloud的模板)

语言输出尺寸
Python17M
TypeScript8.7M
Rust100K
MoonBit27K

结论

我们展示了如何使用MoonBit创建一个遵循组件模型标准的Wasm。组件模型为创建可互操作的Wasm提供了新标准。比如我们能够通过从Spin中提取WIT文件,在5分钟内轻松构建一个无服务器AI应用。

通过支持WebAssembly组件模型,MoonBit增强了其在微服务架构和云原生应用中的应用场景,具有高编译性能和紧凑代码尺寸,允许在各种环境中快速部署和执行。

在8月18日,MoonBit将达到beta预览版本,表明着我们在语言方面已达到一定的稳定性,适合投入更加广泛的测试与实际应用环境。未来,我们将继续拓展MoonBit生态系统,优化文档和工具链,以提供更好的用户体验。敬请期待!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1995540.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全网最最最全的LVS详解!!!

1 LVS-集群和分布式 1.1 集群 LVS(Linux Virtual Server)集群,即Linux虚拟服务器集群,是一个在Unix/Linux平台下实现负载均衡集群功能的系统。它由国人章文嵩博士在1998年开发,是中国国内最早出现的自由软件项目之一…

yolov8 剪枝 - DepGraph

2024年8月5 5000张图片,2个类别。 yolov8n 初始: 185 layers, 3151904 parameters, 31936 gradients, 8.7 GFLOPs 经过三次finetune后: 185 layers, 2327024 parameters, 31936 gradients, 6.6 GFLOPs 经过第四次fintune后: …

“write()” 与 “ tcp缓冲区 ” 之间的关系

write()写入tcp缓冲区过程 write()将该文本写入到tcp缓冲区中本质是数据的拷贝,当write()调用完,数据不一定发给tcp发送缓冲区中 因为: 有没有拷贝成功,都不由write(&a…

史上最全Java初、中、高三级都适用的面试八股文(2024版含答案)

在Java编程的世界里,无论你是初出茅庐的新人,还是已经有一定经验的中级开发者,抑或是寻求突破的高级工程师,面试时总有一套通用的“八股文”知识点,就像是每位程序员的必备宝典。这套2024版的Java面试指南,…

mma.sync.aligned.m16n8k16.row.col.f16.f16.f16.f16测试

mma.sync.aligned.m16n8k16.row.col.f16.f16.f16.f16测试 1.参考文档2.numpy测试3.cuda kernel测试4.相关截图 本文演示了如何按PTX指令文档中的layout格式要求,加载数据,执行mma指令,并且跟numpy对比结果的一致性 1.参考文档 Matrix Fragments for mma.m16n8k16 with floatin…

MAVSDK添加自定义消息与函数实现云台(Gimbal)调整功能

1.找到action.proto文件并添加如下消息 2. 定义RPC方法AdjustGimbal方法如下: 3.运行generate_from_protos.sh重新根据.proto生成.cpp与.h文件 生成过程 生成完成 4. .proto生成的.h文件,成功包含同步与异步方法声明

零基础转行网络安全真的好就业吗?

网络安全作为近两年兴起的热门行业,成了很多就业无门但是想转行的人心中比较向往但是又心存疑惑的行业,毕竟网络安全的发展史比较短,而国内目前网安的环境和市场情况还不算为大众所知晓,所以到底零基础转行入门网络安全之后&#…

python自动化笔记:excel文件处理及日志收集

目录 一、openpyxl模块1.1、安装:pip install openpyxl1.2、openpyxl模块三大组件1.3、创建excel并写入数据1.4、读取excel 二、日志收集 一、openpyxl模块 1.1、安装:pip install openpyxl 注: openpyxl只支持xlsx格式,xls格式…

10+ Midjourney V6.1 提示:生成精美的角色海报

前言 近期图像生成界最大的更新是MidjourneyV6.1!我迫不及待地想要开始创作和分享,这次分享的重点是V6.1在角色创作方面的增强。 以下是半天测试的结果,包括提示,专注于角色摄影照片和角色插图。 网上关于这方面的教程虽然很多&…

【第22章】Spring Cloud之Gateway集成Knife4j(下)

文章目录 前言一、访问页面加权控制1. 加权控制2. 登录 二、生产环境如何屏蔽Knife4j、Swagger等Ui资源和接口1. 基于Spring Boot框架提供的Conditional条件控制相关Bean的生效2. 效果 三、聚合个性化配置1. 用户服务1.1 引入依赖1.2 Knife4j配置类1.3 控制器 2. 网关服务2.1 排…

JG08Z-GD系列 八轴智能测径仪系统介绍

1.测径仪: 主要用于轧制线,棒材,八个方向直径及椭圆度在线测量,轧制螺纹钢特钢尺寸在线测量。 2.功能介绍: (1)显示内容 主控室液晶显示器:管材截面的最大/最小直径、平均值、椭圆…

问题本记录(1):mac有网络但打不开网页

此学习类别,仅作为小许的问题本,方便后续再次遇到相关问题进行查看。 第一步: 第二步: 添加一个新的位置 第三步: 选择这个新建的位置,Wi-Fi显示已连接就 万事大吉啦啦啦

html+css+js+jquery实现一个 飘零的树叶

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>飘落的枫叶</title><style>.maple {position: absolute;top: 0;color: #ff0000;}</style><script src"https://www.jq22.com…

片上POR和BOR的区别

片上 POR 和 BOR 的区别 片上 POR&#xff08;Power On Reset&#xff09;和 BOR&#xff08;Brown-out Reset&#xff09;是微控制器中用于确保系统在电源异常情况下能够恢复正常运作的两种复位机制。 1. POR&#xff08;上电复位&#xff09; POR 是在微控制器上电时触发的…

多路RTSP转RTMP推送方案的两个选择

技术选型 RTSP转RTMP推送到流媒体服务器&#xff0c;说起来技术实现不难&#xff0c;简单来说&#xff0c;获取RTSP流后&#xff0c;拿到未经解码的H.264/H.265和audio数据&#xff0c;重新打包RTMP发送出去即可。需要注意的是&#xff0c;大多RTSP转RTMP模块&#xff0c;需要…

数学建模~~追逐仿真问题

目录 1.前景介绍 2.题目描述 3.核心思路 4.思路分析 5.代码分析 5.1准备工作 5.2设置循环 5.3终止循环 5.4绘制图形 5.5完整代码 1.前景介绍 今天上午的数学建模培训王老师介绍的这个数学建模相关的经验真的是让我受益匪浅&#xff0c;让我对于数学建模有了更加清晰的…

数据增强库albumentations使用指南

数据增强技术就是人为地生成真实数据集的不同版本以增加其数据大小。计算机视觉(CV)和自然语言处理 (NLP) 在模型训练过程中经常使用数据增强策略来处理数据稀缺和数据多样性不足的问题&#xff0c;避免模型因数据量而导致的过拟合、泛化性不足等问题。计算机视觉中常见的数据增…

Node.JS - 基础

目录 A. 简介 B. 安装和配置 C. npm A. 简介 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 一、运行原理 事件驱动和非阻塞 I/O 模型&#xff1a; Node.js 采用事件驱动、异步编程的方式。这意味着它不会在等待一个操作&#xff08;如读取文件或网络请求&a…

spfa算法判断是否存在负权回路

spfa算法判断是否存在负权回路 题目 当一个图中存在一个负权回路时&#xff0c;是无法利用spfa 算法去求最短路问题的&#xff0c;但是可以利用spfa 算法判断有没有负权回路 题目 给定一个 n n n 个点 m m m 条边的有向图&#xff0c;图中可能存在重边和自环&#xff0c; 边…

VisionPro二次开发学习笔记11-使用 Caliper和Fixture定位Blob工具检测方块

该示例演示了如何使用卡尺工具和夹具工具来固定 Blob 工具。示例代码将检测图像上部区域中小方块的存在。当点击“运行”按钮时&#xff0c;将读取一张新图像。卡尺工具将被运行&#xff0c;卡尺工具的输出 Y 信息将传递给夹具工具。夹具工具使用来自卡尺工具的 Y 信息和新图像…