正在统计访客…
浏览全部文档
开始 · 9找到适合你的 Runifold 学习路径45 分钟掌握 Runifold理解完整的 Runifold 平台第一次可信运行选择正确的执行 API选择 Crate 与 Cargo Feature构建常见 Runifold 应用Runifold 常见问题排查 Runifold 应用故障
执行内核 · 7理解 RunContext安全协调外部副作用使用预算与取消限制工作安全地处理错误与重试事件、Journal 与执行证据设计 Capability 安全执行从 Checkpoint 安全恢复
模型与服务商 · 7在避免重复输出的前提下路由模型选择并配置模型服务商使用服务商中立的模型协议基于 Provider Runtime 契约构建使用 OpenAI 控制面与 Realtime API测试与 Benchmark Provider Adapter配置 OpenAI、Anthropic、Gemini 与 Ollama
Agent · 7构建并配置 Agent为 Agent 添加类型化工具加入会话与语义记忆安全地委派给子 Agent返回结构化 Rust 值在不丢失语义的前提下流式输出使用检索为 Agent 提供事实依据
持久工作流 · 7组合确定性工作流让工作流持久化运行持久工作流 Worker协调 Timer、Signal 与持久等待运行多租户工作流基础设施运行并行 Branch 与安全 Race对持久 Workflow 进行版本管理
集成 · 7通过 MCP 连接外部能力选择存储与持久化边界通过 MCP Tasks 暴露持久工作构建并评估检索流水线使用 MCP Resources、Prompts 与 Sampling在不跨越权限的前提下缓存 MCP 响应在 Rust Web Service 中部署 Runifold
质量与运维 · 10在没有网络的情况下测试评估质量并阻止回归观测完整运行树在浏览器与边缘环境安全运行准确理解可靠性声明在 CI 中运行可复现评测使用 SLO 运维 Runifold治理 Task 保留与删除把审计证据归档到 S3-Compatible WORM 存储管理兼容性与可信发布
文档/持久工作流
第一次使用?通过 45 分钟核心课程建立完整心智模型
持久工作流

协调 Timer、Signal 与持久等待

让工作流在不占用进程的情况下暂停,幂等投递 Signal,治理长期等待并安全恢复。

实践指南·12 min

等待为何是持久状态

长期业务流程的大部分时间都在等待:送达日期、审批、Webhook、人工回答或外部 Batch。 让 Worker 或 Async Task 一直存活会浪费容量,并在重启时丢失状态。

持久 Wait 提交暂停原因和允许唤醒它的事件,然后 Worker 释放所有权,之后可由另一进程 恢复。

Timer

Timer 保存由 Store 决定的权威唤醒时间。在此之前 Claim Query 不会返回它;到期后无需 进程 Sleep 或内存 Scheduler,就会重新就绪。

Timer 适合重试计划、提醒、轮询间隔和业务期限。它与操作 Timeout 不同:Timer 决定何时 恢复,Timeout 限制一次尝试。

Signal

Signal 是发送给等待 Workflow 的外部输入。每次投递都要有稳定 Identity,使网络重试不会 产生重复跳转。Signal 应持久化,并按 Tenant 与 Checkpoint 隔离。

明确 Early、Duplicate、Unknown 与 Late Signal 的行为。不能把不透明 Task ID 或 Signal ID 本身当作授权。

Interrupt

Interrupt 把 Workflow 转成显式 input_required 状态,标识所需决策与接受的响应格式。 Approve、Edit、Reject 或 Cancel 命令必须幂等。

人工审核不是一种特殊 Prompt,而是具有 Identity、授权、保留与可审计结果的持久协议 边界。

保留与治理

限制 Wait 时长、Pending Signal 数、轮询频率与保留历史。Supervisor 应找出陈旧 Wait 并 暴露问题,而不是虚构完成。

协议 TTL、执行 Deadline、业务 Due Date 与物理删除 Retention 是不同概念。分别建模; 混用可能取消仍在运行的工作,或无限期保存敏感状态。

构建 Timer、Signal 与人工审核 Wait

use std::time::Duration;
 
let workflow = Workflow::builder("approval")
    .version(1)
    .step("prepare", PrepareProposal, CapabilitySet::new())
    .wait_for_signal_or_timeout(
        "wait_for_documents",
        "documents_ready",
        Duration::from_secs(24 * 60 * 60),
    )
    .interrupt("manager_review", "Approve, edit, or reject this proposal")
    .timer("cooldown", Duration::from_secs(30))
    .step("commit", CommitDecision, write_capabilities)
    .build()?;

Worker 在释放 Lease 前持久化 Wait。通过 WorkflowStore 发布 Signal,使用稳定的 WorkflowSignalId、已认证 Tenant、Checkpoint ID、Name 与 Payload;重复投递应视为 同一事件。Interrupt 要展示带 Key 的 Input Request,并提交一次幂等 Approve / Edit / Reject 决策,绝不能把缺少 Response 推断为批准。