docs: explain Tessera modules and execution flows in Chinese

This commit is contained in:
2026-11-11 23:36:03 +08:00
parent 4c3fc8b5dd
commit 1fedd21d3c
77 changed files with 1418 additions and 0 deletions
+40
View File
@@ -1,3 +1,7 @@
//! owner/key 管理的异步任务与协作式源函数调度。弱索引用于查找,回调、等待对象和协程帧是托管图中的真实边。
//! 任务可能处于等待 I/O、定时器、可执行协程或等待另一任务的状态;取消 owner/key 不能让晚到结果再次执行。
//! 调度使用有界量子和公平推进;await 挂起后保留操作数与帧,不重放此前副作用。失败和依赖环有明确处理路径。
//!
//! Owner-managed asynchronous work. Only weak identities enter the scheduler;
//! callbacks and scopes are ordinary traced edges in the Aster object graph.
use std::{
@@ -24,6 +28,7 @@ const MAX_READY: usize = 64;
type Index = Arc<Mutex<Vec<WeakObjectRef>>>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
/// 任务对源代码可见的生命周期状态,完成/取消/失败各有不同 await 语义。
enum State {
Pending,
Running,
@@ -32,6 +37,7 @@ enum State {
Failed,
}
impl State {
/// 返回内部枚举或对象对应的稳定源名称。
fn name(self) -> &'static str {
match self {
Self::Pending => "pending",
@@ -44,6 +50,7 @@ impl State {
}
#[derive(Debug, Clone)]
/// 托管异步对象,保存 owner/key、结果与真正拥有的回调/协程/等待引用。
struct Task {
owner: WeakObjectRef,
key: String,
@@ -60,15 +67,19 @@ struct Task {
result: Option<Value>,
}
impl ObjectPayload for Task {
/// 提供受检查的 Any 下转型入口,让宿主按具体 payload 类型读取数据。
fn as_any(&self) -> &dyn std::any::Any {
self
}
/// 返回运行时诊断/类型检查使用的稳定 payload 名称。
fn kind_name(&self) -> &'static str {
"tessera-task"
}
/// 声明此 payload 的赋值遵循引用身份语义,避免把内部宿主状态当作可复制值。
fn reference_assignment_only(&self) -> bool {
true
}
/// 把 Task 状态投影成 await 的就绪、等待、取消或失败结果,不在等待期间主动轮询执行。
fn poll_await(&self) -> Result<endor_core::AwaitPoll, VmError> {
match self.state {
State::Pending | State::Running => Ok(endor_core::AwaitPoll::Pending),
@@ -86,6 +97,7 @@ impl ObjectPayload for Task {
)),
}
}
/// 枚举本对象真正拥有的托管强引用,供 Aster 引用追踪和循环回收使用。
fn trace(&self, visit: &mut dyn FnMut(ObjectRef)) {
if let Some(callback) = self.callback {
visit(callback);
@@ -101,15 +113,18 @@ impl ObjectPayload for Task {
}
}
}
/// 统一构造本模块的参数错误,让调用方停止处理无效输入。
fn invalid(message: &'static str) -> VmError {
VmError::InvalidArgument(message)
}
/// 从源值中提取并检查托管对象身份,错误类型沿 VM 错误返回。
fn object(value: &Value) -> Result<ObjectRef, VmError> {
match value {
Value::Object(object) => Ok(*object),
_ => Err(invalid("task owner and callback must be managed objects")),
}
}
/// 取得 owner 关联的托管任务作用域,供 key 替换和取消使用。
fn scope(store: &ObjectStore, owner: ObjectRef) -> Result<Option<ObjectRef>, VmError> {
let payload = store.object(owner)?.payload();
if let Some(value) = payload.as_any().downcast_ref::<Block>() {
@@ -132,6 +147,7 @@ fn scope(store: &ObjectStore, owner: ObjectRef) -> Result<Option<ObjectRef>, VmE
Err(error) => Err(error),
}
}
/// 为可拥有任务的对象安装作用域,真实引用仍由托管图追踪。
fn install_scope(
cx: &mut NativeContext<'_>,
owner: ObjectRef,
@@ -155,6 +171,7 @@ fn install_scope(
}
cx.set_attr(owner, SCOPE, Value::Object(scope))
}
/// 检查任务的 owner 仍有效且任务具备交付条件,避免晚到结果复活已关闭页面。
fn eligible(store: &ObjectStore, owner: ObjectRef, desktop: ObjectRef) -> Result<bool, VmError> {
let payload = store.object(owner)?.payload();
if let Some(mount) = payload.as_any().downcast_ref::<Mount>() {
@@ -194,6 +211,7 @@ fn eligible(store: &ObjectStore, owner: ObjectRef, desktop: ObjectRef) -> Result
}
Ok(true)
}
/// 检查弱索引对应的任务是否仍是 owner/key 当前登记的那一项。
fn current(
store: &ObjectStore,
owner: ObjectRef,
@@ -210,6 +228,7 @@ fn current(
/// Called at the actual close/detach boundary, including close-then-reopen in
/// one language input. A later appearance never revives these identities.
/// 取消某个 owner 的全部任务,防止页面/窗口生命周期结束后继续执行回调。
pub fn cancel_owner(cx: &mut NativeContext<'_>, owner: ObjectRef) -> Result<(), VmError> {
let Some(scope) = scope(cx.store(), owner)? else {
return Ok(());
@@ -233,6 +252,7 @@ pub fn cancel_owner(cx: &mut NativeContext<'_>, owner: ObjectRef) -> Result<(),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
/// 当前宿主 API 的操作分类,分派代码负责参数校验与状态更新。
enum Operation {
Timer,
Sleep,
@@ -241,6 +261,7 @@ enum Operation {
Spawn,
}
#[derive(Debug)]
/// 创建定时/I/O/协作任务时的原生调用适配器。
struct After {
operation: Operation,
provider: crate::io_tasks::Provider,
@@ -251,13 +272,16 @@ struct After {
desktop: ObjectRef,
}
impl NativeCallable for After {
/// 给出参数与返回值的托管类型契约;实际操作在 invoke 中执行。
fn signature(&self) -> Option<endor_core::CallSignature> {
Some(self.signature.clone())
}
/// 声明宿主可调用对象接受的参数个数,供 VM 在执行前检查。
fn arity(&self) -> Option<endor_core::CallArity> {
Some(self.signature.arity)
}
/// VM 调入本宿主能力的入口;按所属操作解码参数并返回托管值或后续调用。
fn invoke(&self, cx: &mut NativeContext<'_>, args: &[Value]) -> Result<NativeResult, VmError> {
if self.quiescing.load(Ordering::Acquire) {
return Err(invalid("runtime is exiting; new tasks are forbidden"));
@@ -459,6 +483,7 @@ impl NativeCallable for After {
}
#[derive(Debug, Clone, Copy)]
/// 该原生能力的查询/操作分类,方法包装用它选择具体实现。
enum Query {
Cancel,
Status,
@@ -467,19 +492,23 @@ enum Query {
Error,
}
#[derive(Debug)]
/// 保存 owner、签名或操作枚举的原生方法适配器,统一由 VM 调用。
struct Method {
signature: endor_core::CallSignature,
query: Query,
desktop: ObjectRef,
}
impl NativeCallable for Method {
/// 给出参数与返回值的托管类型契约;实际操作在 invoke 中执行。
fn signature(&self) -> Option<endor_core::CallSignature> {
Some(self.signature.clone())
}
/// 声明宿主可调用对象接受的参数个数,供 VM 在执行前检查。
fn arity(&self) -> Option<endor_core::CallArity> {
Some(endor_core::CallArity::exact(1))
}
/// VM 调入本宿主能力的入口;按所属操作解码参数并返回托管值或后续调用。
fn invoke(&self, cx: &mut NativeContext<'_>, args: &[Value]) -> Result<NativeResult, VmError> {
let [value] = args else {
return Err(invalid("Task methods accept no arguments"));
@@ -561,6 +590,7 @@ impl NativeCallable for Method {
}
}
/// 弱任务索引、公平调度位置和 provider,索引不会单独把任务保活。
pub struct Scheduler {
index: Index,
runnable: Arc<AtomicBool>,
@@ -569,15 +599,18 @@ pub struct Scheduler {
provider: crate::io_tasks::Provider,
}
impl Scheduler {
/// 停止接收该域的新任务工作,为关闭/替换运行时做准备。
pub fn quiesce(&self, vm: &mut Vm) -> Result<usize> {
self.quiescing.store(true, Ordering::Release);
self.cancel_all(vm)
}
/// 检查是否有可推进的协程,而不是仅仅存在正在等待外部结果的任务。
pub fn has_cooperative_work(&self) -> bool {
self.runnable.load(Ordering::Acquire)
}
/// Mutation boundaries collect unreachable owner/callback cycles before
/// this weak lookup. Idle timer polling does not rescan the entire heap.
/// 在当前 VM 中有界交付就绪任务、执行回调或推进协程;开始布局后由外层刷新流程继续。
pub fn poll(&self, vm: &mut Vm, limit: usize) -> Result<usize> {
anyhow::ensure!((1..=MAX_READY).contains(&limit), "invalid task poll limit");
// Provider threads only fill the mailbox. Only this VM worker updates
@@ -731,6 +764,7 @@ impl Scheduler {
self.prune(vm)?;
Ok(work)
}
/// 取消当前域全部任务,切断回调、协程和等待交付资格。
pub fn cancel_all(&self, vm: &mut Vm) -> Result<usize> {
let snapshot = self
.index
@@ -753,6 +787,7 @@ impl Scheduler {
self.runnable.store(false, Ordering::Release);
Ok(count)
}
/// 移除已释放的弱任务索引,索引本身不让任务或其 owner 存活。
fn prune(&self, vm: &mut Vm) -> Result<()> {
let mut index = self
.index
@@ -789,6 +824,7 @@ impl Scheduler {
Ok(())
}
}
/// 沿等待链检查任务依赖环,防止 await 永远无法被满足。
fn cyclic_wait(vm: &Vm, source: ObjectRef, mut target: ObjectRef) -> Result<bool> {
let mut seen = std::collections::HashSet::new();
loop {
@@ -805,6 +841,7 @@ fn cyclic_wait(vm: &Vm, source: ObjectRef, mut target: ObjectRef) -> Result<bool
}
}
/// 恢复已保存的源函数帧,处理完成、软量子挂起或 await 等待,保留已发生的副作用。
fn advance_coroutine(vm: &mut Vm, reference: ObjectRef) -> Result<()> {
let mut task = vm.payload::<Task>(reference, "Task")?.clone();
let coroutine = if let Some(coroutine) = task.coroutine {
@@ -897,6 +934,7 @@ fn advance_coroutine(vm: &mut Vm, reference: ObjectRef) -> Result<()> {
}
}
/// 记录回调执行失败并沿运行时故障规则停止后续不安全的交付。
fn fail_callback(vm: &mut Vm, reference: ObjectRef, message: &str) -> Result<()> {
let mut task = vm.payload::<Task>(reference, "Task")?.clone();
task.error = Some(message.chars().take(1024).collect::<String>().into());
@@ -904,6 +942,7 @@ fn fail_callback(vm: &mut Vm, reference: ObjectRef, message: &str) -> Result<()>
finish(vm, reference, State::Failed)
}
/// 将任务转入终态并释放回调、provider 租约、协程和等待引用;取消还会清除保存的结果。
fn finish(vm: &mut Vm, reference: ObjectRef, state: State) -> Result<()> {
let mut task = vm.payload::<Task>(reference, "Task")?.clone();
if !matches!(task.state, State::Pending | State::Running) {
@@ -934,6 +973,7 @@ fn finish(vm: &mut Vm, reference: ObjectRef, state: State) -> Result<()> {
Ok(())
}
/// 把本模块的类型、方法或能力注册到所属运行时上下文。
pub fn install(
vm: &mut Vm,
roots: &mut Vec<ObjectRef>,