第 5 章:会话管理与存活检测
本章定义 Session 的状态机、生命周期事件、与 Terminal_Resource 的绑定规则,以及 Liveness_Detection(存活检测)机制。本章对应蓝图 §2.3 的设计意图。
5.1 Session 状态机
每个 Session 在其生命周期内经历有限状态机的多个状态。
5.1.1 状态定义
SessionState = enum[
"creating",
"active",
"handover_pending",
"terminating",
"terminated"
]
| 状态 | 说明 |
|---|---|
creating | 授权校验通过,Session 正在初始化(如分配资源、设置 OS 访问控制) |
active | Session 处于活跃状态,Fay 可执行授权范围内的操作 |
handover_pending | Session 正在参与控制权交接(参见第 6 章),尚未确定结果 |
terminating | Session 正在被终止,资源回收中,新请求被拒绝 |
terminated | Session 已完全终止,session_id 进入历史记录 |
5.1.2 状态转移图
┌─────────────┐
│ (start) │
└──────┬──────┘
│ 授权校验通过
▼
┌─────────────┐
│ creating │
└──────┬──────┘
│ 资源初始化完成
▼
┌─────────────┐ 交接发起 ┌──────────────────┐
│ active │────────────→│ handover_pending │
└──────┬──────┘ └──────┬───────────┘
│ ↑ │
终止条件│ │交接超时回滚 │交接完成
▼ │ ▼
┌─────────────┐ ┌─────────────┐
│ terminating │←─────────────┤ (handed off)│
└──────┬──────┘ └─────────────┘
│ 资源回收完成
▼
┌─────────────┐
│ terminated │
└─────────────┘
5.1.3 状态转移规则
终端 MUST 仅按下表允许的转移更新 Session 状态:
| 当前状态 | 目标状态 | 触发条件 |
|---|---|---|
creating | active | 资源初始化完成 |
creating | terminating | 初始化失败(如资源被其他 Session 占用) |
active | handover_pending | 收到针对该 Session 的交接请求 |
active | terminating | 主动释放、心跳超时、撤销终止、资源不可用 |
handover_pending | terminating | 交接成功(原 Session 必须终止)或交接超时取消 |
handover_pending | active | 交接被新控制方拒绝(回退到原状态) |
terminating | terminated | 资源完全释放、状态持久化完成 |
实现 MUST NOT 进行未列出的状态转移。
5.1.4 状态转移的原子性
每次状态转移 MUST 满足以下原子性要求:
- 状态读取、判断、写入 MUST 在临界区内完成,外部观察者不会看到中间状态
- 状态转移与对应的资源操作(如 OS 访问控制下发)MUST 作为一个事务执行,要么全部成功,要么全部回滚
5.2 Session 创建
5.2.1 创建触发
Session 在以下场景被创建:
- iFay_Runtime 发起 AuthRequest 且授权校验通过(参见 §3.3、§4.3)
- 控制权交接成功后,为新控制方创建新 Session(参见第 6 章)
5.2.2 创建步骤
终端 MUST 按以下步骤创建 Session:
- 资源占用预检:检查目标
resource_id在access_mode下是否可被占用(参见 §5.3 与第 7 章读写锁规则) - 生成 Session_ID:分配新的 UUID v7
- 设置初始状态:
state = "creating" - 构造 Session 对象:填充 §2.5 定义的字段
- 下发 OS 访问控制:通过 §1.3.2 接口告知操作系统允许该 Fay 进程以指定模式访问资源
- 状态切换:
state: creating → active,记录created_at和last_heartbeat_at - 返回 AuthResult:将
session_id通过 AuthResult 回传给 iFay_Runtime
5.2.3 创建失败处理
若任一步骤失败:
- 已分配的资源(如 OS 访问控制条目)MUST 被回滚
- Session 状态切换到
terminating然后立刻terminated - 返回对应的错误码(如
E_RESOURCE_BUSY、E_OS_INTEGRATION_FAILED)
5.3 Session 与 Terminal_Resource 的绑定
5.3.1 一对一绑定
每个活跃 Session MUST 绑定到恰好一个 Resource_ID。终端通过 (resource_id, access_mode) 维护资源的占用关系。
5.3.2 排他性与共享性规则
详见第 7 章 §7.2 读写锁矩阵。本节给出会话层面的简化规则:
| 资源当前活跃 Session | 新 Session 请求 | 处理 |
|---|---|---|
| 无 | 任意模式 | 允许创建 |
| ≥1 个 read | read | 允许创建 |
| ≥1 个 read | write/execute/configure | 拒绝(E_RESOURCE_BUSY) |
| 1 个 write/execute/configure | 任意模式 | 拒绝(E_RESOURCE_BUSY) |
5.3.3 资源不可用的级联终止
当 Resource_ID 对应的资源变为不可用(如硬件断开、软件进程崩溃、操作系统报告资源消失)时:
- 终端 MUST 立即将所有绑定该资源的 Session 切换到
terminating - 终端 MUST 向所有受影响的 iFay_Runtime 推送
SessionStateChanged通知,reason为"resource_unavailable" - 资源恢复后,已终止的 Session MUST NOT 自动恢复,iFay_Runtime 需重新发起 AuthRequest 创建新 Session
5.4 Liveness_Detection(存活检测)
存活检测通过长连接维持和应用层心跳两个独立信号判定 Session 是否仍活跃。
5.4.1 长连接维持
iFay_Runtime 与终端之间 MUST 维持一条长连接通道(如 WebSocket、HTTP/2 stream、gRPC stream)。
终端 MUST 监测该长连接的状态:
- 连接建立:长连接信号有效
- 连接断开:长连接信号无效(包括 TCP RST、超时无响应等)
长连接断开 MAY 是临时网络抖动的结果,因此 MUST NOT 单独作为终止 Session 的依据(见 §5.4.3 双重判定)。
5.4.2 应用层心跳
iFay_Runtime MUST 在长连接上为每个活跃 Session 周期性发送 Heartbeat 消息:
Heartbeat (body of ProtocolMessage) {
required session_id : Session_ID
required sequence_number : uint64
}
HeartbeatAck (body of ProtocolMessage) {
required session_id : Session_ID
required sequence_number : uint64
}
| 参数 | 默认值 | 范围 |
|---|---|---|
| 心跳间隔 | 10 秒 | 1–60 秒 |
| 心跳超时阈值 | 30 秒 | 心跳间隔 × 2 至心跳间隔 × 6 |
sequence_number 在每个 Session 内单调递增,从 0 开始。
终端 MUST:
- 收到 Heartbeat 后立即返回 HeartbeatAck(
sequence_number与请求一致) - 更新该 Session 的
last_heartbeat_at - 拒绝
sequence_number小于已记录最大值的 Heartbeat(防止重放)
5.4.3 双重判定
终端 MUST 仅当同时满足以下两个条件时才判定 Session 失效:
- 长连接已断开超过心跳超时阈值
- 自
last_heartbeat_at起的时长超过心跳超时阈值
这种双重判定的设计意图是:
- 长连接短暂抖动期间应用层心跳可能仍正常(不应误判失效)
- 应用层心跳停止但长连接仍在(如 Fay 卡顿)需通过心跳超时检测
- 两者同时发生才是高置信度的失效信号
5.4.4 失效后的处理
判定失效后,终端 MUST:
- 切换 Session 状态:
active → terminating - 释放占用的 Terminal_Resource
- 通过 OS 接口撤销该 Fay 对资源的访问权限
- 等待长连接恢复或心跳恢复期间,所有针对该 Session 的请求返回
E_SESSION_TERMINATED - 终端 MAY 在长连接恢复后向 iFay_Runtime 推送一次
SessionStateChanged通知,但此时 Session 已不可恢复
5.4.5 心跳的可选模式
实现 MAY 支持以下心跳优化模式(须明确声明支持):
- 聚合心跳:iFay_Runtime 在一条 Heartbeat 消息中同时报告多个 Session(适用于一个 runtime 管理大量 Session 的场景)
- 降频心跳:当 Session 长期未发起资源访问时,心跳间隔可放大至最长 60 秒
聚合心跳的具体格式作为可选扩展,在 schema.json 中定义为可选字段。
5.5 Session 终止
5.5.1 终止触发条件
| 触发原因 | reason 字段值 | 触发方 |
|---|---|---|
| 主动释放 | "client_release" | iFay_Runtime |
| 心跳超时 | "liveness_timeout" | 终端 Liveness_Detection |
| 撤销终止 | "credential_revoked" | 终端撤销列表更新 |
| 资源不可用 | "resource_unavailable" | 终端 OS 集成层 |
| 凭证过期 | "credential_expired" | 终端定期检查 |
| 交接完成 | "handed_over" | 终端交接流程 |
| 强制终止 | "forced" | 终端管理接口(如管理员操作) |
5.5.2 终止步骤
终端 MUST 按以下步骤执行终止:
- 状态切换:
{active|handover_pending} → terminating - OS 资源回收:通过 §1.3.2 接口撤销 Fay 进程的资源访问权限
- 释放并发控制:将 (resource_id, access_mode) 从占用列表中移除(参见第 7 章读写锁更新)
- 通知 iFay_Runtime:发送
SessionStateChanged消息,状态为terminated,附带 reason - 状态切换:
terminating → terminated - 持久化:MAY 将 Session 历史记录写入审计日志
5.5.3 终止的幂等性
iFay_Runtime 发起的 SessionRelease 消息 MUST 是幂等的:
- 若 Session 已处于
terminating或terminated,再次释放 MUST 返回成功(不视为错误) - 若 Session 不存在(已被回收),返回
E_SESSION_NOT_FOUND
5.5.4 终止的可观测性
终端 MUST 至少向以下方通知 Session 终止:
- 该 Session 关联的 iFay_Runtime(通过
SessionStateChanged) - 终端本地的资源管理子系统(用于更新可用性状态)
终端 MAY 选择是否通知:
- 其他正在等待该资源的 iFay_Runtime(通过 §6 交接通知机制)
- 审计日志(取决于终端实现的审计策略)
5.6 状态变更通知
SessionStateChanged (body of ProtocolMessage) {
required session_id : Session_ID
required new_state : SessionState
optional reason : string
optional details : map<string, string>
}
终端 MUST 在以下状态转移发生时向 iFay_Runtime 发送 SessionStateChanged:
creating → active:Session 创建成功(也可通过 AuthResult 直接告知,二选一)active → handover_pending:Session 进入交接流程handover_pending → active:交接被取消或拒绝* → terminating与terminating → terminated:终止过程的开始与结束
5.7 Session 与凭证生命周期的关系
Session 的生命周期独立于凭证生命周期,但终端 MUST 监控凭证状态变化:
| 凭证事件 | Session 影响 |
|---|---|
凭证 not_after 到达 | 关联 Session 立即按 credential_expired 终止 |
| 凭证被撤销(撤销声明到达终端) | 关联 Session 立即按 credential_revoked 终止 |
| 凭证被同 ID 重新签发(理论不可能,因 descriptor_id 不可复用) | 不适用 |
| 凭证被新版本覆盖(更新流程) | Session 不受影响(仍使用原 credential_ref 校验) |
5.8 Session 数量限制
终端 SHOULD 实现 Session 数量限制以防资源耗尽:
| 维度 | 默认限制 | 备注 |
|---|---|---|
| 单终端总活跃 Session | 1024 | 可由终端策略调整 |
| 单 Fay 活跃 Session | 64 | 防止单一 Fay 占满系统资源 |
| 单 Resource_ID 活跃 read Session | 32 | 防止 read 共享被滥用 |
超出限制时,终端 MUST 返回 E_SESSION_LIMIT_EXCEEDED。
