
Rivet Actors 睡眠 API 深度解析POST /actors/{actor_id}/sleep 端点原理与 Rust SDK 调用指南【免费下载链接】actorsRivet Actors are the primitive for stateful workloads. Built for AI agents, collaborative apps, and durable execution.项目地址: https://gitcode.com/GitHub_Trending/riv/actorsRivet Actors 为有状态工作负载AI Agent、协作应用、持久化执行提供了完整的生命周期管理能力其中睡眠Sleep是控制 Actor 资源释放与状态持久化的关键原语。本文以engine/sdks/rust/api-full/rust/docs/ActorsSleepApi.md为骨架完整解析POST /actors/{actor_id}/sleep端点的请求参数、认证方式、响应语义并沿着 API 网关到引擎核心的调用链讲解其底层实现原理。读完本文你将掌握如何通过 Rust SDK 与原生 HTTP 调用主动休眠 Actor、理解 sleep 与 destroy 的差异以及keepAwake/waitUntil等配套原语的使用场景。一、API 概览ActorsSleepApi是 Rivet API 中负责主动触发 Actor 睡眠的端点。当 Actor 处于空闲状态时平台会依据空闲超时自动将其休眠以释放资源而该端点则提供了一条显式、按需的休眠通道让调用方可以在业务逻辑确认 Actor 不再需要驻留时立即触发睡眠流程。MethodHTTP requestDescriptionactors_sleepPOST/actors/{actor_id}/sleep主动请求指定 Actor 进入睡眠状态该文档由 OpenAPI Generator 基于engine/artifacts/openapi.json生成版本 2.3.14所有 URI 均相对于http://localhost开发环境地址生产环境应以实际部署的 API 网关地址为基准。除了 Rust SDKapi-full外仓库还提供了同构的 TypeScript SDKengine/sdks/typescript/api-full/src/Client.ts与 Go SDKengine/sdks/go/api-full/client/client.go三者共享同一份 OpenAPI 契约。二、请求参数详解actors_sleep方法签名如下pub async fn actors_sleep( configuration: configuration::Configuration, actor_id: str, namespace: str, body: serde_json::Value, ) - Resultserde_json::Value, ErrorActorsSleepError参数表NameTypeDescriptionRequiredNotesactor_idString目标 Actor 的 ID[required]路径参数位于/actors/{actor_id}/sleep的 URL 路径中namespaceStringActor 所属的命名空间名称[required]查询参数以?namespace...形式附加在 URL 上bodyserde_json::Value请求体[required]JSON 请求体Content-Type: application/json参数在请求中的实际位置查看 SDK 源码 actors_sleep_api.rs 可以确认三个参数的组装方式let uri_str format!({}/actors/{actor_id}/sleep, configuration.base_path, actor_id crate::apis::urlencode(p_actor_id)); let mut req_builder configuration.client.request(reqwest::Method::POST, uri_str); req_builder req_builder.query([(namespace, p_namespace.to_string())]); // ... req_builder req_builder.json(p_body);actor_id经过urlencode后拼入 URL 路径因此需要 URL 编码namespace通过 reqwest 的query()以查询字符串追加body通过json()序列化为请求体。请求体的真实结构尽管文档中body的类型标注为通用的serde_json::Value但从服务端契约 api-types/src/actors/sleep.rs 可以看到请求体实际是空对象#[derive(Serialize, Deserialize, ToSchema)] #[serde(deny_unknown_fields)] #[schema(as ActorsSleepRequestBody)] pub struct SleepRequest {}该结构体启用了deny_unknown_fields意味着请求体中不能携带任何额外字段。实际调用时传入serde_json::json!({})即可let result actors_sleep(config, actor_id, default, serde_json::json!({})).await?;若传入未知字段服务端会因反序列化失败而拒绝请求。三、认证与响应认证方式该端点使用Bearer Token认证bearer_auth参见 api-public 路由定义 中的security((bearer_auth []))声明。Rust SDK 侧认证令牌在Configuration中通过bearer_access_token字段注入请求发出时自动附加Authorization: Bearer token头if let Some(ref token) configuration.bearer_access_token { req_builder req_builder.bearer_auth(token.to_owned()); };完整的认证说明可参考 engine/sdks/rust/api-full/rust/README.md。返回类型与响应头项目值成功响应200 OK返回serde_json::Value实际为ActorsSleepResponse空对象{}Content-Type请求application/jsonAccept响应application/jsonSDK 在收到响应后会根据响应头的content-type决定解析策略actors_sleep_api.rsapplication/json会尝试反序列化为serde_json::Valuetext/plain及未知类型会构造错误返回。4xx/5xx 响应则统一包装为Error::ResponseError其中携带状态码、原始响应体与反序列化后的ActorsSleepError。四、调用链从 HTTP 端点到引擎核心actors_sleep表面是一个简单 POST 端点但背后贯穿了 API 网关、控制面与运行时三层。理解这条链路有助于排查问题与预估延迟。第一步API 网关路由与鉴权服务端入口位于 engine/packages/api-public/src/actors/sleep.rs。sleep_inner首先执行ctx.auth().await?完成鉴权然后判断目标 Actor 所在的数据中心若 Actor 属于当前数据中心path.actor_id.label() ctx.config().dc_label()直接调用本地的rivet_api_peer::actors::sleep::sleep否则通过request_remote_datacenter_raw将请求原样转发包括查询参数与请求体到 Actor 所在数据中心的/actors/{actor_id}/sleep端点。这种按数据中心就近路由的设计意味着调用方无需感知 Actor 部署在哪个区域。第二步控制面校验与信号下发请求进入 engine/packages/api-peer/src/actors/sleep.rs 后依次完成三道校验通过pegboard::ops::actor::get查询 Actor不存在则返回Actor::NotFound通过namespace::ops::resolve_for_name_global解析namespace参数命名空间不存在则返回Namespace::NotFound校验 Actor 的namespace_id与解析出的命名空间一致不一致时同样返回Actor::NotFound——避免跨命名空间越权操作。校验通过后控制面发送pegboard::workflows::actor2::Sleep {}信号定义于 engine/packages/pegboard/src/workflows/actor2/mod.rs并指定tag(actor_id, ...)定向投递给对应 Actor 的 workflow 实例。若 Actor workflow 已不存在例如刚刚停止graceful_not_found()会静默返回仅记录一条 warning 日志不会报错。第三步运行时生命周期状态机信号最终作用于 RivetKit 运行时核心的睡眠状态机。ActorContext::sleep()rivetkit-rust/packages/rivetkit-core/src/actor/context.rs内部执行了严格的生命周期守卫若生命周期尚未启动lifecycle_started false区分尚未启动完成返回actor/starting错误与已在关闭中返回actor/stopping错误两种诊断通过sleep_requested.swap(true, Ordering::SeqCst)原子交换保证每个生命周期代次generation内只能成功请求一次成功后调用cancel_sleep_timer()取消空闲定时器避免与自动睡眠竞争。从源码结构看睡眠与销毁destroy共用同一套优雅关闭grace通道睡眠进入SleepGrace阶段销毁进入DestroyGrace阶段二者都会触发abortSignal通知用户代码收尾详见 docs-internal/engine/sleep-sequence.md。五、Rust SDK 完整调用示例结合 Configuration 与 Error 类型一个完整的最小可运行调用如下use rivet_api_full::apis::{actors_sleep_api, configuration::Configuration}; #[tokio::main] async fn main() - Result(), Boxdyn std::error::Error { // 1. 构造配置base_path 指向 API 网关token 来自鉴权流程 let mut config Configuration::new(); config.base_path https://api.example.com.to_string(); config.bearer_access_token Some(your-token.to_string()); // 2. 主动触发 Actor 睡眠 let actor_id actor-uuid-here; let namespace default; let result actors_sleep_api::actors_sleep( config, actor_id, namespace, serde_json::json!({}), // 请求体必须是空对象 ) .await?; println!(sleep 请求已受理: {result:?}); Ok(()) }actors_sleep是异步非阻塞的它只负责提交睡眠意图并返回SleepResponse {}真正的状态持久化与进程回收在后台异步完成。业务侧如需确认 Actor 已进入睡眠应轮询 Actor 的状态或等待下一次唤醒后观察其重启计数。六、睡眠语义触发场景、状态持久化与保持唤醒何时会触发睡眠从测试套件 actor-sleep.test.ts 可以归纳出以下触发与抑制行为空闲超时自动睡眠Actor 在SLEEP_TIMEOUT内无任何活动无 RPC、无连接即自动睡眠显式 API 触发即本文的actors_sleep端点以及 Actor 内部调用c.sleep()TypeScript 侧实现在 registry/native.ts保持唤醒的活动进行中的 RPC 调用、活跃的 Raw WebSocket 连接、未完成的 Raw HTTP 请求、已设置的 alarm 定时器都会阻止睡眠noSleep配置Actor 可通过配置完全禁用自动睡眠。睡眠即状态持久化睡眠并不是简单地杀掉进程。睡眠流程会先序列化 Actor 的 KV 状态与 SQLite 数据再释放计算资源下次有请求到达时平台会以持久化的状态唤醒并重建 Actor 实例。测试actor sleep persists state验证了这一点触发睡眠后sleepCount从 0 变为 1、startCount从 1 变为 2表明旧实例已回收、新实例基于持久化状态重启。这一机制是 Rivet Actors 支撑有状态工作负载的成本优势来源——空闲即休眠按需唤醒。keepAwake 与 waitUntil控制优雅关闭窗口睡眠信号到达后Actor 不会立即停止而是进入宽限期grace period等待进行中的收尾工作完成。开发者通过两个 Promise 原语控制这一窗口详细不变量见 sleep-sequence.mdMethod阻止空闲睡眠阻止宽限期完成说明c.keepAwake(promise)是是返回同一个 Promise用于必须保持 Actor 运行的工作如 alarm、队列接收c.waitUntil(promise)否是返回 void用于尽力的 flush/清理工作允许在宽限期内完成二者均以 Promise 为粒度计数Promise settle无论 resolve 还是 reject后计数器自动递减不会像旧的setPreventSleep标志位那样因忘记复位而将 Actor 永久卡醒。setPreventSleep/preventSleep目前是保留兼容性的 no-op调用时会打印 deprecation 警告计划在 2.2.0 移除。七、测试与验证仓库为睡眠生命周期提供了多层次的测试保障TypeScript 驱动测试rivetkit-typescript/packages/rivetkit/tests/driver/actor-sleep.test.ts约 1072 行覆盖状态持久化、RPC/WebSocket/HTTP 保持唤醒、alarm 唤醒、onSleep回调中发送消息、宽限期与 abortSignal 竞态等 20 余个场景配套 fixture 位于 rivetkit-typescript/packages/rivetkit/fixtures/driver-test-suite/包含sleep.ts、sleepWithRawWebSocket.ts、sleepNestedWaitUntil.ts等大量可复用的测试 ActorRust 集成测试位于rivetkit-core/tests/modules/sleep.rs锁定睡眠谓词、宽限期选择与save_final_state兜底上限SERIALIZE_STATE_SHUTDOWN_SANITY_CAP 15s等核心不变量端到端脚本scripts/tests/actor_sleep.ts 与 examples/kitchen-sink/scripts/sleep-close-fuzz.ts 提供面向真实部署的验证与模糊测试路径。这些测试共同确认了actors_sleep端点在真实系统中的行为边界RPC 会重置空闲定时器、长 RPC 期间不会睡眠、活跃连接关闭后按超时睡眠等。八、总结POST /actors/{actor_id}/sleep是 Rivet Actors 主动控制生命周期的一等公民 API调用方通过actor_id路径、namespace查询参数与空对象请求体即可安全地提交睡眠意图服务端以 Bearer Token 鉴权并在跨数据中心场景下自动就近转发。其底层实现api-public → api-peer → pegboard workflow 信号 → RivetKit 生命周期状态机保证了校验的严谨与状态持久化的可靠。配合keepAwake/waitUntil原语开发者可以精确编排何时保持活跃、何时优雅让位在成本与可用性之间取得平衡。// 快速参考提交睡眠请求所需的最少步骤 actors_sleep_api::actors_sleep(config, actor_id, namespace, serde_json::json!({})).await?;【免费下载链接】actorsRivet Actors are the primitive for stateful workloads. Built for AI agents, collaborative apps, and durable execution.项目地址: https://gitcode.com/GitHub_Trending/riv/actors创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考