docs: clarify API request phases and native input ordering

This commit is contained in:
2026-11-12 20:05:19 +08:00
parent a1c1781b00
commit f1e413c8c5
3 changed files with 26 additions and 0 deletions
+12
View File
@@ -5,6 +5,11 @@
//! api::start_server_observed 的唯一执行线程创建 Worker,每次循环调用 begin_request/resume_request 或 refresh_viewport。
//! HTTP/原生请求仍由外层持有,PendingRequest 只记录继续哪一步;本文件不重新读取请求流或回放已执行输入。
//! NamespaceState 是对外权威值,repl 是实际 VM 所有者;submission 是接受顺序,runtime_session 才表示画面仍属哪个 VM。
//!
//! 请求阶段不能互换:BeforeInput 尚未执行业务,可重新进入 begin_request;Input 已执行,只能恢复视觉工作;
//! Candidate 持有独立候选,成功前不替换 self.repl。外层 api 循环保留原 job,因此这里不会创建第二份回应端。
//! 接受 PUT 先改变 submission,候选成功提交后才切换 runtime_session;preserve_live_owner 在两者之间保留仍权威的旧域。
//! 源业务与视觉方法在 Namespace 锁外执行,文档/命令发布回到写锁内复核身份;错误响应和故障画面发布是两项不同结果。
use super::*;
// 响应已编码成内存字节,外层 RequestReply 可发 HTTP 或转换成原生回执,不需要读取 VM 返回值。
@@ -376,6 +381,7 @@ impl Worker {
current.document.frame.session = 0;
current.document.frame.focus = None;
for document in current.document.windows.values_mut() {
// 重置的是共享堆,所有副窗旧身份都失效;保留的是静态绘制文档,不是仍可接收事件的窗口业务对象。
document.frame.session = 0;
document.frame.focus = None;
}
@@ -388,6 +394,7 @@ impl Worker {
serde_json::json!({"ok":true,"execution":"repl-reset","persistent":true,"session_reset":true,"message":"Console memory cleared; displayed page preserved"}),
));
}
// 旧布局/绘制仍挂起时只保存等待阶段,不能在它的只读 VM 调用中执行新的 REPL 或事件副作用。
if self
.repl
.as_ref()
@@ -414,6 +421,7 @@ impl Worker {
}
}
};
// 先按输入种类筛选再查资源能力:合法 JSON 不代表有权触发任意名字的宿主操作。
if !input.kind.starts_with("developer-open:")
&& !matches!(
input.kind.as_str(),
@@ -638,6 +646,7 @@ impl Worker {
// Console 不是事件,不制造一个空 Input;下面按 source 执行同一持久会话的交互语句。
None
};
// 只有当前 epoch 没有实际会话才惰性创建空 Console;正常输入沿用已有 VM,不为每次 POST 复制 globals。
if self
.repl
.as_ref()
@@ -935,6 +944,7 @@ impl Worker {
/// 新提交/候选过期或失败时调用,若旧 VM 仍拥有发布画面则只跟进 epoch;DELETE 已撤权威则丢弃它。
pub(super) fn preserve_live_owner(&mut self, current: &NamespaceState) {
// 调用方已持发布状态锁,本函数只对照身份修改 worker 本地拥有关系,不执行回调或生成新文档。
if let Some((epoch, runtime)) = &mut self.repl {
if current.runtime_session == runtime.id {
// 旧程序还是真正交互域,接受次序更新但其实际对象和 session 身份都不改变。
@@ -1071,10 +1081,12 @@ impl Worker {
let Ok(mut current) = namespace.write() else {
return error_response(StatusCode(500), "namespace lock poisoned");
};
// 候选计算结束不代表仍被接受;先处理过期并保留权威旧域,再考虑把候选结果交给 commit。
if current.submission != job.submission {
self.preserve_live_owner(&current);
return superseded(job.submission);
}
// 失败分支遵循同一原则:候选未被完整接受就不把其 VM 装进 self.repl,不用半成品替换旧程序。
match result {
Ok(Ok((runtime, document, commands))) => match current.commit(job.submission, document)
{