Waymark: Python 的持久化工作流引擎
概述
Waymark 是一个旨在通过将代码编译为中间表示(而非重放)来编排持久化后台工作流的库。通过利用基于 Rust 的运行时和 Postgres 作为主要后端存储,它允许开发者编写标准的异步 Python 代码,这些代码可以在服务器重启、崩溃和长时间运行的操作中存活,而无需复杂的独立基础设施栈。
“一次编译”架构
与 Temporal 或 Vercel Workflow 等依赖“重放”机制的传统持久化执行引擎不同,Waymark 采用了一次编译的方法。在基于重放的系统中,工作流代码在每一步都会从头开始重新执行,这要求用户编写严格确定性的代码——在工作流逻辑中必须避免使用 random() 或 datetime.now() 等非确定性函数。
Waymark 通过将 Python run() 方法的抽象语法树 (AST) 解析为中间表示 (IR) 来改变这一点。该 IR 随后被降级为自定义持久化虚拟机的字节码。由于运行时在 Postgres 中跟踪该虚拟机的状态,工作流在恢复期间无需从头开始重新执行。这使得开发者可以使用标准的 Python 控制流,包括循环、条件判断和并行分支,且对确定性的限制更少。
核心概念
Waymark 区分了两种用于管理分布式工作的主要原语:
- Actions (动作): 这些代表分布式工作单元,例如网络调用、数据库查询或任何可能失败并需要独立重试的任务。动作由节点执行,并可配置特定的重试策略和超时时间。
- Workflows (工作流): 这些作为持久化控制流层。它们编排动作,但自身不执行繁重的任务。它们支持标准的 Python 模式,例如用于并行分发的
asyncio.gather和在进程重启后依然有效的持久化暂停asyncio.sleep。
部署与使用
Waymark 的设计目标是“轻基础设施”,仅需要一个 Postgres 数据库。该系统包含一个内置的 Web 应用程序,可通过 waymark-executor 访问,提供对工作流实例、调用时间线和节点负载的可视化。
虽然该项目目前处于早期开发阶段,不建议用于生产环境,但它旨在通过简化后台作业栈来支持专注于实现产品市场契合度 (product-market fit) 的团队。它并不适用于需要亚 100ms 延迟或大规模并发(例如显著超过 1 万个并发动作)的高规模环境。
社区观点
Waymark 的推出引发了关于其设计权衡的讨论。一些用户指出了工作流引擎与应用程序代码之间可能存在的紧密耦合,并对随着 Python 版本或第三方依赖项演进而产生的长期可维护性表示担忧。
另一些人则强调了这种架构转变,将其与 Bazel 或 Nix 等构建系统进行了比较。正如一位评论者所言:
"令我惊讶的是,我直到现在才看到这种被 Nix 和 Bazel 使用的‘连接沙盒化命令式组件的纯协调语言’架构模式,被应用到了分布式工作流中。" — @handle
此外,一些开发者指出了该库对 asyncio 的严重依赖,并指出这对于主要使用同步代码库的团队来说可能不太友好。