正在统计访客…
浏览全部文档
开始 · 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 分钟核心课程建立完整心智模型
工作流

让工作流持久化

保存检查点、在不占用进程的情况下等待、恢复租约,并按照显式策略继续运行。

实践指南·16 min

持久化模型

持久工作流会保存有语义的进度,再由任意兼容 Worker 继续执行。进程是否持续在线不再 影响正确性。

需要跨发布存活、等待人员或定时器、协调昂贵副作用,或在 Worker 消失后恢复的任务, 都适合使用持久化。

在本机运行一个持久 Task

单机持久 Worker 启用 SQLite;如果多个进程或主机需要并发 Claim,改用 PostgreSQL。

Cargo.toml
[dependencies]
runifold = { version = "=0.9.0", features = ["sqlite-bundled"] }
serde_json = "1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

假设 workflow 是在 Workflow 指南中构建的 Workflow,下面代码会 创建持久控制面、注册准确版本、入队一个 Task,并运行一次 Claim:

use std::{sync::Arc, time::Duration};
 
use runifold::{
    Budget, CapabilitySet, LeaseDuration, WorkerId, WorkflowDefinition,
    WorkflowRegistry, WorkflowStore, WorkflowTask, WorkflowWorker,
    sqlite::SqliteWorkflowStore,
};
use serde_json::json;
 
let store = Arc::new(SqliteWorkflowStore::open("runifold-workflows.db")?);
let mut registry = WorkflowRegistry::new();
registry.register(WorkflowDefinition::new(
    Arc::new(workflow),
    Budget::default(),
    CapabilitySet::new(),
))?;
 
store
    .enqueue(WorkflowTask::new(
        "order-intake",
        1,
        json!({ "order_id": "ord_42" }),
    )?)
    .await?;
 
let worker = WorkflowWorker::new(
    store,
    registry,
    WorkerId::parse("worker-local-1")?,
    LeaseDuration::new(Duration::from_secs(30))?,
    Duration::from_secs(10),
)?;
let outcome = worker.run_once().await?;
println!("{outcome:?}");

run_once() 会返回 IdleCompletedRetriedSuspendedFailedDefinitionUnavailableLeaseLost。生产服务通常使用有界 Supervisor;测试或接入 现有 Job Loop 时可以直接使用 run_once()

检查点与版本

Checkpoint 记录工作流定义、当前阶段、已完成步骤输出、预算状态和恢复元数据。 Revision 可防止两个 Worker 提交互不兼容的进度。

步骤输出应可序列化、紧凑且有版本。大型产物放在 Checkpoint 外,通过不可变 ID 引用。

定时器、信号与人工审核

Wait 会持久化等待意图,不占用线程或进程。Timer 在截止时间后唤醒;Signal 在审批等 外部事件发生时唤醒。

Signal 名称与 Payload 是应用契约。验证发送者身份、按 Signal ID 去重,并保留足够 历史来解释谁在何时、为何恢复了工作流。

Worker 与租约

Worker 通过有限 Lease 认领任务。健康 Worker 会续租;租约过期后,其他 Worker 可以 恢复任务。

SQLite Store 适合本地持久执行;分布式 Worker 和多进程协调使用 PostgreSQL 工作流 Feature。

恢复策略

恢复必须区分可以安全重复的步骤,以及结果未知的 Effect。按边界配置 Resume Policy, 在继续前先对账不确定副作用。

旧任务仍存在时,新版本必须保持工作流定义兼容。把 Step ID、序列化状态与 Signal 名称当作数据库 Schema 管理。

恢复演练

上线前应对真实 Store 完成以下演练:

  1. 使用已知 Checkpoint ID 入队一个 Task;
  2. 在确定性 Step 执行中终止 Worker;
  3. 等待超过 Lease 时长,再用新的 Worker Identity 启动;
  4. 验证已完成 Step 不会重复,Usage 不会减少;
  5. 在外部写入边界重复演练,确认结果依据 Effect 证据被重放或标记为 Ambiguous, 而不是根据超时猜测;
  6. 在版本 1 Task 等待期间部署版本 2,确认两个 Definition 都仍被注册。

常见失败

Outcome 或错误含义修复
DefinitionUnavailableWorker 缺少 Task 指定的名称/版本部署或重新注册该准确版本
LeaseLost另一个 Owner 可能已经接管立即停止写入,让当前 Owner 恢复
持续 Retried失败策略或租户预算推迟任务检查类型化失败和 Retry Delay
Checkpoint Conflict过期 Revision 尝试提交丢弃旧状态并重新加载
Ambiguous In-flight外部是否完成未知先对账,禁止静默成功或重跑
Task 一直 WaitingTimer 未到期或 Signal 未接受检查 Wake Time、Tenant、Signal 名与去重 ID

对应控制面细节继续阅读 WorkerWait 与 SignalCheckpoint 恢复Workflow 版本