2 个版本

0.1.1 2022 年 11 月 20 日
0.1.0 2022 年 11 月 20 日

#2 in #response-object

MIT 许可证

27KB
398

do-proxy

Crates.io Docs.rs MIT licensed

一个用于在 Rust 中编写类型安全持久对象(DOs)的库。

使用 do-proxy 你可以

  • 轻松编写持久对象的类型安全 API。
  • 抽象化 fetchalarm 和请求-响应粘合代码。

概述

do-proxy 提供了一个核心特质 DoProxy,该特质抽象化了序列化/反序列化请求响应代码、对象初始化和加载以及错误处理粘合代码。

在结构体实现了 DoProxy 之后,宏 do_proxy! 创建了 workers-rs#[DurableObject] 结构体,最终生成最终对象。

对象生命周期

此库提供了两种不同的 Request 类型。一种普通 Request 类型,持久对象将发送 99% 的此类请求,以及一个可选的 Init 类型,该类型可选用于初始化对象。

例如,假设我们有一个 Person 对象。结构体可能看起来像

struct Person {
    birthday: DateTime<Utc>,
    name: String
}

impl DoProxy for Person {
    // ...
}

do_proxy!(Person, PersonObject);

birthdayname 字段是非可选的且必需的。然而,在 Rust 中使用 new 构造持久对象或在 TypeScript 中使用 constructor 时,你只能获得 StateStorage 的信息。因此,当你第一次加载 Person 对象时,你将不得不使用虚假值来设置 namebirthday,因为它们尚未设置。

创建对象的请求可能是某种“创建”命令,将 birthdayname 设置为实际值。但这不是保证的。

如果人在创建之前收到一个 CalculateNextBirthday 命令怎么办?现在你需要显式检查这些值是否是虚假的,或者将所有内容包裹在一个 Option 中。这两种选择都容易出现错误(虚假值)或不方便(Option)。

为了解决这个问题,do-proxy 有两个用于构建对象的函数。

  • init:创建并保存在 load_from_storage 中构建对象所需的所有信息。当库的用户向 Person 对象发送请求时,他们可以可选地添加 DoProxy::Init 数据。如果这些数据存在,init 将在 load_from_storage 之前被调用。
  • load_from_storage:从存储中加载一个对象。如果对象缺少字段或未初始化,此函数应报错。

在以下示例中,我们发送了初始化信息和命令。对象首先被初始化,然后处理命令

let proxy = env.obj::<Person>("[email protected]");
let resp = proxy
    .init(Person::new("Bob", bobs_birthday))
    .and_send(Command::CalculateNextBirthday).await?;

如果您知道对象必须初始化或无法创建初始化信息,您只需发送命令即可

let proxy = env.obj::<Person>("[email protected]");
let resp = proxy.send(Command::CalculateNextBirthday).await?;

这种方法让您避免了选项、无效值,并且 init 函数是 async 的。

示例

位于 ./examples 下的所有 crate 都是库的示例,未来它们将成为分布式系统的完整粘贴块。

每个 crate 都有一个 hurl 脚本,展示如何查询包装工作者的方法。

  • inserter:InserterObject 响应一个简单的类似 KV 的 API,用于在它的存储中获取、插入和删除 KV 对。示例
POST http://localhost:8787/test_do
{
    "insert": {
        "key": "hello",
        "value": "world!"
    }
}

POST http://localhost:8787/test_do
{
    "get": {
        "key": "hello"
    }
}

# returns { "value": "world!" }

依赖项

~11–15MB
~301K SLoC