@ drupflare/ 偿还
执行专断的网络大会 在云花岗工人.
目录
为什么是伯罗
Cloudflare工人禁止应要求生成WebAssembly代码. 工人不能打电话
new WebAssembly.Module, (中文(简体) ), WebAssembly.compile, (中文(简体) ), eval 或者说 new Function因此它不能运行代码
在部署时不知道.
博罗通过不编译来管理它 译者编为装入捆绑的同名船只 向口译员提供数据。 什么都没有产生,所以什么都没有 被封锁.
同样的属性使动态连接工作. 正在装入 -s SIDE_MODULE 构建通常意味着
生成一个 funcref 用于每个地址摄取符号,即代码生成。 对口译员a
函数指针是输入自身表格的索引,因此该步骤不存在.
挖洞船没有语言运行时间。 消费者提供一种;地窖处理收购、居住 保护安全.
QQ 安装
bun add @drupflare/burrow
这些类型预计全球工人,从 @cloudflare/workers-types 或者说 wrangler types。 。 。 .
QQ 快速启动
import wasm3 from '@drupflare/burrow/vendor/wasm3.wasm';
import { createInterpreter } from '@drupflare/burrow/interpret';
export default {
async fetch(request: Request) {
const vm = await createInterpreter({ module: wasm3 });
const guest = vm.load(new Uint8Array(await request.arrayBuffer()));
return Response.json({ answer: guest.call('main') });
}
};
主机功能为平版JavaScript,此功能在这里是合法的,因为来宾的 call_indirect 永远
触摸真正的真菌表 :
const guest = vm.load(bytes, {
imports: {
env: {
now: { signature: 'i()', fn: () => Date.now() | 0 },
log: { signature: 'v(ii)', fn: (ptr, len) => console.log(guest.readText(ptr, len)) }
}
}
});
执行路径
三个路径,由一个问题选择:您在部署时知道这个模块吗?
| 路径 | 对于 | 速度 |
|---|---|---|
interpret | 未知的部署字节 | 参见以下比率 |
import | 在捆绑中运出模块 | 1.00x,原产地 |
publish | 应在背景中变成本地字节 | 1.00x一次活下来 |
interpret 是默认的,因为它是唯一总是有效的. import 没有更好的,
更窄一点.
解释比例由来宾设定,而不是由地窖设定:
比率= 1 + D cy x G时
G按本地周期退休的宾客指令.
翻译员的管理费是添加剂的 几乎是不变的 所以决定比例的是多少 客人已经摊了 指针追逐64个米B 工作套装措施1.01x;同样的追逐 超过16个KiB量 4.41x;每字节变换量 20x.
将工作与路径匹配 . 内存和耐久的工作几乎一无所获.
使用小型工作集进行计算的工作属于捆绑中的工作,或者属于通过本地路径的工作
publish。 。 。 . 推进 用户.md 带有测量曲线和平面表.
动态图书馆
import { createLinker } from '@drupflare/burrow/dylink';
const linker = createLinker(vm);
const lib = linker.load(soBytes, { name: 'ext' });
lib.call('ext_run', 20, 22);
lib.readText(lib.address('greeting')!);
与主机运行时间相对应的链接,一个扩展共享主机的堆积,表格和符号,这就是什么 一个真正的扩展 ABI 需要 :
const host = vm.load(mainModuleBytes);
const ext = createLinker(vm, { host }).load(extensionBytes);
ext.call('ext_install'); // allocates from the host heap and calls back into it
收听图书馆的公开需求 而不是规模 因为图书馆的 .bss
占用文件中没有字节 :
const { memorySize, tableSize, needed } = linker.inspect(soBytes);
校对:Soup -s SIDE_MODULE: 口译库
压缩后,节点自己的zlib读取结果回放.
应请求加载时间可以买到达到,而不是速度. 热道上的任何东西都属于捆绑. 推进 用户.md 有成本模型 和适合它的工作形状.
宣布运行时间
import { Burrow, defineRuntime } from '@drupflare/burrow';
const php = defineRuntime({
name: 'php',
load: () => import('./runtimes/php.js'),
instantiate: async ({ loaded, io, lines }) => {
const mod = await loaded.PHPFactory({ stdout: lines(io.print) });
return { FS: mod.FS, callMain: (argv) => mod.callMain(argv) };
},
memory: { initial: 96 * 1024 * 1024, peak: 116 * 1024 * 1024 }
});
const burrow = new Burrow({ runtimes: [php] });
await using sh = await burrow.session('php');
await sh.evalText('<?php echo phpversion();');
load 一定是绕着字面的分光符来转 因为重建不能跟随一个计算出来的.
内存预算
Budget 追踪每个居民运行时间的线性内存 与隔离盖相对应 拒绝一个靴子
并首先驱逐最近使用最少的居民。 已申报数字从
每次运行后观察.
租房是连锁的:任何租房都没有被拆迁过,不能装入扔房的靴子
BudgetError 而不是让孤立者耗尽.
平行巷道
一个隔离有一条线. @drupflare/burrow/parallel 将一个任务分布在永久对象之间
同一工人,各自根据自己的执行背景,按顺序收集结果.
import { defineLane, LanePool } from '@drupflare/burrow/parallel';
import wasm3 from '@drupflare/burrow/vendor/wasm3.wasm';
export const BurrowLane = defineLane({
interpreter: wasm3,
tasks: { checksum: (input) => input.reduce((a, b) => (a + b) >>> 0, 0) }
});
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const pool = new LanePool(env.BURROW_LANES, { size: 16 });
const sums = await pool.map({ task: 'checksum' }, [new Uint8Array([1, 2]), 'text']);
return Response.json(sums.map((r) => r.number()));
}
};
"durable_objects": { "bindings": [{ "name": "BURROW_LANES", "class_name": "BurrowLane" }] },
"migrations": [{ "tag": "burrow-lanes", "new_sqlite_classes": ["BurrowLane"] }]
切片可以是来宾相机,从你的捆绑中取出命名的任务,也可以是运行时的评价. 池子重试 在备用道和篱笆上的故障会减慢切片的速度,并且接受一个切片的准确结果. 计量 一辆16跑道的暖水池 做了个解释性客运工作 在7.8-8.5x的一车道上需要3-4 s; 工作规模更短, 因为每片都支付 固定发送费用.
spawn 财务报告和审定财务报表 scope 给与类似线柄, atomic 财务报告和审定财务报表 mutex 坐标道,和 channel
相互间流出消息 . 推进 用户.md 涵盖
语义与测量.
医生
bunx burrow doctor ./runtimes/php.js
扫描对工人致命的图案的运行时间 : eval, (中文(简体) ), new Function,请求时间
编译, 仅限浏览器粘胶, 和未加保护 self.location 读取。 它报告发现,从来没有
因为源头扫描无法证明没有JIT 退出代码 0 表示
没有看到已知的脂肪.
• 警卫
洞穴运行代码 部署从未见过。 将相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相.
平台已经处理好了. 工人隔离是短暂的,没有文件系统,没有 子进程和无 syscalls,所以持久性形状的威胁不适用: 矿工可以继续运行, 没有什么可以安装的特洛伊人, 没有主机可以选择。 敌人 客人有一个请求.
剩下的是你交出的能力. 客人能达到东道主的距离 函数。 获取到网络的导入; 读取绑定的导入读取 您的数据; 需要指针和长度的数据可以被任意指针所传递。 供应最窄 完成此任务的进口,验证其内部的论据,而不是信任客人,并批准 您不会允许浏览器扩展 .
const vm = await createInterpreter({ module: wasm3, maxMemoryBytes: 64 * 1024 * 1024 });
const guest = vm.load(untrustedBytes, {
imports: {
env: {
// no fetch, no bindings, no clock the caller did not ask for
log: {
signature: 'v(ii)',
// cap the length here rather than trusting the one the guest passed
fn: (ptr, len) => console.log(guest.readText(ptr, Math.min(len, 4096)))
}
}
}
});
设定 maxMemoryBytes 对于任何你没有建造的客人. 没有它,客人可以长出记忆 直到
隔离就会消失 隔离OOM会失败 而不是一个.
连接到一个主机的动态库不从它中被沙盒取出. 他们有一个记忆和一个记忆 表格,所以一个库可以读取和写出主机持有的一切,并调用主机所能调用的任何东西. 这就是ABI的扩展 也是敌对图书馆想要的 所以必须问 用于:
createLinker(vm, { host, allowHostAccess: true }); // only for libraries you would run in-process
createLinker(vm); // user-supplied: each library gets an address space of its own
没有主机,图书馆无法互相解决任何符号,也无法到达主机堆.
来宾记忆被隔离;来宾CPU不是. 每个客人都是受限的 所以有个客人 无法读取口译或其他来宾。 这里没有什么能阻止客人旋转,所以工人CPU 极限是结束一个出走的循环。 在您需要的持久对象中不要运行未信任的来宾 保持响应.
单独处理的请求是共享的. 翻译记忆中留下的先前请求 由装入其中的下一位客人读取。 每名租户或每请求创建新译员 需要数据的地方.
burrow doctor 报告调查结果,从来就没有干净的保健帐单, 所以它是一个污点而不是一个
有门. 推进 用户.md 拥有完整的威胁模型.
子路径导出
| 导出 | 目录 |
|---|---|
. | 除了别的事 ./parallel |
./interpret | createInterpreter, (中文(简体) ), WasmInterpreter |
./dylink | createLinker, (中文(简体) ), readDylink, (中文(简体) ), Library |
./registry | Burrow租赁 |
./session | Session 编辑 eval 表面 |
./budget | Budget |
./runtime | defineRuntime, (中文(简体) ), RuntimeSpec |
./adapt | lines, (中文(简体) ), memoryFS, (中文(简体) ), mkdirp |
./doctor | inspectSource, (中文(简体) ), inspectWasm |
./publish | publishVersion |
./probe | probe |
./parallel | LanePool, (中文(简体) ), defineLane, (中文(简体) ), LaneTask |
./errors | 每个错误类型及其代码 |
解释 二进制是资产而非模块,通过路径导入:
import wasm3 from '@drupflare/burrow/vendor/wasm3.wasm';
测试
bun run typecheck
bun run test # gate: unit and node
bun run test:runtimes # real builds installed from npm
bun run format:check
每个错误都有稳定的点 code和那个吻合 永远不要在留言上.
许可证
麻省理工学院