docs(resident): document timer and TCP drivers

Describe ResidentSupervisor ownership, TCP policy and configuration, bounded stream backpressure, timer scheduling, restart behavior, and deterministic Host-resource shutdown order.
This commit is contained in:
Maofeng
2026-07-31 10:04:46 +08:00
parent 7939285e9f
commit b5aa008729
2 changed files with 71 additions and 0 deletions
+65
View File
@@ -30,6 +30,71 @@ Host KV 使用 `(service_id, key)` 复合主键存储在该数据库中:同一
编译后的本地机器码默认缓存在 `var/wasmeld/component-cache`,相同 Component 在
Console 或 Runtime 重启后可由 Wasmtime 直接复用;缓存不包含 Actor 内存。
## 常驻 Host Driver
导出 `wasmeld:resident/actor@0.1.0` 的 Component 启动时,Console 会为它创建独立的
`ResidentSupervisor`。Supervisor 在专用阻塞线程上独占 `ResidentSession`,避免同步
Actor mailbox 阻塞 Tokio executor。Timer、TCP Listener 和每条 TCP Stream 由 Tokio
task 等待外部事件,再通过容量受限的 channel 汇聚到同一个 Supervisor。
Host 资源属于平台配置,不由 Component 创建,也不写入 `.wasmpkg`。当前可通过
`ConsoleConfig::resident_services` 为稳定服务 ID 配置 TCP Listener 和 Timer
```rust
use std::collections::BTreeMap;
use wasmeld_console::{
ConsoleConfig, NetworkScope, ResidentPolicy, ResidentServiceConfig,
ResidentTcpListenerConfig, ResidentTimerConfig,
};
let mut resident_services = BTreeMap::new();
resident_services.insert(
"scheduler".to_owned(),
ResidentServiceConfig {
policy: ResidentPolicy {
tcp_listen: NetworkScope::Loopback,
..ResidentPolicy::default()
},
tcp_listeners: vec![ResidentTcpListenerConfig {
name: "internal-api".to_owned(),
bind: "127.0.0.1:9000".parse().unwrap(),
}],
timers: vec![ResidentTimerConfig {
name: "heartbeat".to_owned(),
initial_delay_ms: 1_000,
interval_ms: Some(30_000),
}],
..ResidentServiceConfig::default()
},
);
let config = ConsoleConfig {
resident_services,
..ConsoleConfig::default()
};
```
`ResidentPolicy` 默认拒绝全部网络地址;配置 Listener 时还必须显式选择 `Loopback`
`Any`。Listener 在 Actor 启动过程中完成策略校验和 bind,任何失败都会回滚刚启动的
Actor,避免出现“Actor 正在运行但端口未监听”的半启动状态。Listener、Timer 和其它
顶层资源名称在同一服务内必须唯一,每个 Revision 都会获得独立的 Host handle 和不复用
资源 ID。
TCP Driver 每次最多读取 `limits.resident.max_stream_chunk_bytes`,不会把 socket handle
交给 Wasm。TCP 字节在 Supervisor 队列满时等待并把背压传递到内核接收缓冲区,不能像
Timer occurrence 一样丢弃。Component 可通过 WIT 返回 `write-stream``close-stream`
`pause-stream``resume-stream`;每条连接的写入/控制队列也是有界的,慢客户端填满
队列时只关闭该连接,不阻塞同一 Actor 的其它连接。
Timer task 只负责等待,队列满时丢弃该次 occurrence,而不是创建无界积压。Component
返回 `arm-timer` 会替换 Host 初始日程,`cancel-timer` 会取消它;generation 使取消前
已经排队的迟到事件失效。
停止顺序固定为:停止接收新 Driver 事件、停止 accept、投递 `shutdown`、关闭 Stream
和 Timer task、先释放子 Stream 再释放 Listener、最后停止 Actor。服务重启和 Runtime
Deployment 恢复都会重新 bind 并创建新 Session,不会复用旧 Revision 的 socket、Timer
或 Component 内存。UDP 和 Unix Driver 尚未接入,后续继续复用相同的 Supervisor
序列化边界。
## 启动
`wasmeld-console` 需要 Rust 1.95 或更高版本;Wasm 组件继续使用项目约定的 Rust 1.90