直至正文
豫言包府
← 众包

豫言操作系统网页事件流适配 0.1.0

豫言 · 库

以云工的 TransformStream 与 Response 实现网页事件流接口:响应头立即提交,逐块写入受背压并可感知客户端断开。

网页事件流云工适配

流。豫 以豫言书于云工宿主库之上,不增宿主 JavaScript 一字。其行[网页事件流公约](../../../豫言操作系统接口/网页事件流/规范.文言.md) 0.1.0:即提响应头、逐块书文(受背压)、察断、正终与异终。

所以行之

  • 响应与背压:造 TransformStream,其可读端授 Response 为体,以 云工设置响应句柄 提之;宿主于 fetch、service-fetch、durable-fetch 之事用 Promise.race([响应已备, 运行毕]),故响应一设,fetch 即返,Wasm 续行。可写端之写器司书:writer.write(字节) 待读者来取而后成,此即背压。
  • 察断:造“断开候”之承诺——scheduler.wait(二十四时, {signal: AbortSignal.any([请求信号, 我方信号])}) 再以 Promise.allSettled 裹之(永不拒)。每书与每闭,皆使操作之承诺与之 Promise.race,断开候居前:请求信号一止(客断),无论书本身能成与否皆返一;操作被拒(响应体读端已取消)亦返一。入站事件流已断开 读请求信号之 aborted 与写器之 desiredSize(误则 null)。流终、止或断之后,经“我方信号”撤计时而释诸柄,不留悬挂之时。
  • 状与柄:每 Wasm 实例内有一登记簿(流柄、写器号、状态引用、请求信号号、断开候号、我方控制器号)。流柄为“实例标记:写器句柄号”,实例标记取 crypto.randomUUID() 之首十三字,故他事(句柄号纵同)得之亦辨为无效。状态零开、一客断、二已终或止、三断而后终或止。
  • 校验:状态、标头(令牌、值字节、禁名、重复、数)皆于提响应头之前由豫言校之,违则抛豫言之异;书之大小先于状态之辨;事类非 HTTP 事则抛异。止用 writer.abort(new Error(因)),终用 writer.close(),皆不阻于慢读者。
  • 内部诸辅助之名皆以 流内 起首,免与客或他适配同名。

部署之要

一、兼容标志 `enable_request_signal`:工作者配置之 compatibility_flags 必含之。无之则请求之 AbortSignal 不止(本地 workerd 已验),断无从察,客去后书或永阻于背压。云仓之 wrangler.jsonc 须为用此包之应用加此一项。 二、全局 `scheduler.wait` 与 `AbortSignal.any`:Workers 自具;Node 宿主无全局 scheduler,以 node:timers/promises 之 scheduler 垫片经 创建云工宿主({全局}) 授之,见 一致性验证/工具.mjs 之 造全局。 三、事之限:每事之豫言实例有墙钟之限,默认三十秒;需更久之流(长联)者,于应用目录置 执行配置.json,如 {"事件时限毫秒":{"durable-fetch":900000}}(至多十五分钟)。

本地 workerd 之实测(Wrangler 4.129.0,兼容日 2026-09-10,enable_request_signal,持久对象内 durable-fetch,真实 HTTP)

  • 响应头先于程序毕而至;帧序、UTF-8、六十四 KiB 之界、三千小块、八十个六十四 KiB 之块、十二并发流,皆正;线上见附加标头,Content-Type 不可覆。
  • 背压宽:读者止读八百毫秒,书者已出二百六十七至三百四十八个万字节之帧(套接字与管道之缓冲约三 MB 之量),而后乃阻。
  • 客中止 fetch 后应用续行:书约八十五至一百三十毫秒内返一,毕 D1 结算、终、终后书返二。空闲之联不即被见:断后首、二次之书仍返零,请求信号待书败而后止,第三次书返一(本地 HTTP/1.1;见组合范例三分片与心跳三百五十四毫秒之察);故久持之流当按期书心跳。
  • 止:HTTP/1.1 之客所读者为正终(分块之尾照发),宿主志记未捕之异;欲使客可靠知败者,当先于流中书一帧误事件。
  • 未终未止而程序返:客久候(二十秒不见终)。
  • 事逾墙钟之限:宿主于下一调即败(约三十秒,书止),响应流仍开而无人终之;订阅同不收。见下“宿主改动之请”。
  • 云端(Cloudflare 边缘)之行——空闲流之限时、断是否即告、异终于 HTTP/2 之所见——待云端验证。

宿主改动之请(致宿主壳之守者;此适配不改宿主 JS)

事毕,收尾流之写器与读取器。 今宿主于事毕(正、败、逾时)不理仍登于事句柄表之流:未终之响应流悬挂,未取之订阅泄漏(云工每实例仅六十四频道之额,泄漏可尽之,此后订新频道皆得 HTTP 500)。宜于 宿主.mjs 之 执行 中、运行毕 之前加下列收尾,并于 句柄.mjs 所返之物增 全部: () => Array.from(表.values()):

// 文言:事毕(成、败、逾时皆然),其未终之写器则终之,未退之读器则退之。
// 汉语:事件结束时收尾该事件句柄表里仍登记的流写器与读取器:正常结束则 close 写器;失败或超时则 abort 写器,使响应流以错误终止而不悬挂;读取器一律 cancel,使订阅得以回收。
const 收尾流 = 失败 => {
  for (const 值 of 句柄.全部()) {
    try {
      if (值 instanceof 全局.WritableStreamDefaultWriter) void (失败 === undefined ? 值.close() : 值.abort(失败)).catch(() => {});
      else if (值 instanceof 全局.ReadableStreamDefaultReader) void 值.cancel().catch(() => {});
    } catch { /* 已释放或已终的流不再收尾。 */ }
  }
};
// 在 `运行().then(() => {` 之首调 收尾流();
// 在 `.catch(错 => {` 之首调 收尾流(错);

已于私有 dist 副本验之(Node 与本地 workerd 二处):补丁既施,未终之流于程序返时正终,事逾时(压 durable-fetch 之限至三百毫秒)则以“豫言执行超过时限”终而不悬挂,遗订被收;本地 workerd(真持久对象)中:未终之流于程序返时以正终收场,长流于三十秒之限而止,不复悬挂,遗订之数归零;一致性验证三组测试于补丁宿主上尽通过(二则“已知限制(待宿主改进)”之测由待办转通过)。WritableStreamDefaultWriter 与 ReadableStreamDefaultReader 于 workerd 与 Node 皆为全局之类,instanceof 可用。

一致性验证

一致性验证/ 含试验应用 事件流一致性应用(实 Wasm)与 Node 测试 事件流一致性.test.mjs(响应头先至、帧序、六十四 KiB 之界与大量小块、背压、读端取消与请求信号中止二种断、断后收尾、止、终后之义、无效与他事之流柄、非 HTTP 事、并发流、durable-fetch、附加标头诸校验之支),并有于真实 workerd 复验之驱动 事件流云端复验.test.mjs。复行之法见该目录之说明。

所赖

观包之制

上传之记

今修订:1 ·

  1. 修订 1
    取 ZIP

包之层级

父:豫言操作系统适配

无子包。