- 后端
- 工作流自动化
- 流程编排
- 低代码
【免费下载链接】elsa-core
The Workflow Engine for .NET
本文基于 Elsa Core 仓库中 specs/011-persistence-vnext/tasks.md 的完整任务清单(T001–T054),结合同目录的 spec.md、roadmap.md 与
src/modules/Elsa.Persistence.VNext*系列源码,系统梳理 Elsa Persistence vNext 这一"Provider 无关、模块零迁移、文档存储为默认、物理化按策略可选"的新一代持久化架构的分阶段落地计划、当前实现状态、验收标准与源码佐证。读完本文,你可以掌握该架构从"存储清单(Manifest)→ 规划器(Planner)→ 渲染器(Renderer)→ 物化(Materialization)→ 文档存储 → 运行时实体 → 物理化策略"的完整开发闭环,并据此判断各阶段任务的依赖关系与剩余工作。
一、任务清单的定位:一份可执行、可追踪的八阶段开发计划
specs/011-persistence-vnext/tasks.md 是 Persistence vNext 特性的执行任务清单,它把 spec.md 中的用户故事与功能需求(FR-001 到 FR-018)翻译为 8 个阶段(S1–S8)、共 54 个可勾选的任务项(T001–T054),并明确标注每项的完成状态([x]已完成 /[ ]待办)。
从任务结构可以清晰看到整条架构主线:
- S1 是"地基":先建立 Provider 中立的存储描述符与规划器,让"一次声明、多 Provider 复用"成为可能;
- S2–S4 是"存储能力":依次打通 SQLite(可移植文档存储 MVP)、SQL Server / PostgreSQL(关系型文档 Provider)、MongoDB(原生文档 Provider);
- S5 是"接入 Elsa":把 vNext 持久化接入 Elsa 特性系统,并完成第一个真实模块(Secrets)的迁移;
- S6–S7 是"能力扩展":运行时自定义实体(Runtime-Defined Entities)与按策略的物理化优化(Physicalization);
- S8 是"收尾评估":对工作流运行时热路径做基准测试与 go/no-go 决策,形成生产化硬化结论。
每个任务项都对应 roadmap.md 中一个或多个 GitHub issue(#7670–#7677),是典型的"规范 → 计划 → 执行 → 验证 → 合并"闭环管理方式。
二、S1 — Core Manifest And Planner Foundations:Provider 无关存储声明的根基
S1 的目标(roadmap.md 原文):模块只需声明一次 Provider 无关的存储意图,关系型规划器与文档规划器即可消费同一份 Manifest。任务项包括 T001–T011,其中 T008(打开/更新 S1 PR)与 T010、T011(合并 PR、关闭 issue)仍待办,核心编码工作已全部完成。
2.1 核心描述符模型(T001)
T001 "Add provider-neutral storage descriptors" 已完成的产物集中在 src/modules/Elsa.Persistence.VNext/Models 目录,五个核心类型构成存储声明的"词汇表":
PersistenceSchema:整份存储模式的根,包含Name、Version、Tables与StorageUnits(见 PersistenceSchema.cs);PersistenceStorageUnit:Provider 中立的持久化单元,声明Name、Namespace、Fields、Key(主键)与Indexes(见 PersistenceStorageUnit.cs);PersistenceField/PersistenceIndex/PersistencePrimaryKey:分别描述字段、查询索引与主键约束;PersistenceColumn/PersistenceColumnType:关系型列与列类型的抽象描述。
这正是 spec.md 中"Key Entities"所定义的 Persistence Manifest、Storage Unit、Field、Index 等概念在代码中的直接落地。
2.2 规划器与渲染器契约(T002–T004)
任务 T002(关系型规划器 + SQLite 渲染器)、T003(SQL Server 渲染器)、T004(文档规划器)围绕四份契约接口展开(见 src/modules/Elsa.Persistence.VNext/Contracts):
IPersistenceSchemaPlanner:把 Manifest 规划为 Provider 家族的执行计划;IPersistenceSchemaRenderer:把计划渲染为具体 DDL;IPersistenceSchemaProvider:提供/注册 Schema 来源;IPersistenceSchemaMigrator:执行迁移(见下文 Schema History)。
具体实现上:
- 关系型一侧有 RelationalSchemaPlanner.cs,产出
RelationalSchemaPlan(含RelationalTable、RelationalColumn、RelationalIndex、RelationalPrimaryKey); - 文档一侧有 DocumentDatabasePlanner.cs,产出
DocumentDatabasePlan(含DocumentCollection、DocumentField、DocumentIndex); - SQLite 与 SQL Server 分别提供
SqliteSchemaSqlRenderer、SqlServerSchemaSqlRenderer作为 DDL 渲染器。
"同一份 Manifest 同时产出关系型与文档型计划"的验收标准,正是 spec.md 中 User Story 1 的两个 Acceptance Scenario。
2.3 Schema History:版本化执行的基石(T005)
T005 "Add SQLite schema history/version runner" 对应 SqliteSchemaVersionRunner.cs。它的职责是记录每个 Manifest 版本是否已被应用,从而支撑 spec.md 的 FR-006(记录已应用版本)与 FR-007(幂等启动物化):
- 某版本未应用时,执行生成的 DDL 并写入版本记录;
- 已应用时直接跳过,不重复执行任何 Schema 操作。
这正是 spec.md 中 User Story 2 的验收场景 1 与 2 的运行时保障。
2.4 示例 Manifest 与聚焦测试(T006、T007、T009)
T006 要求提供 Secrets 示例 Manifest,作为 S1 的"冒烟样例"来证明"一次声明、两路规划";T007 为关系型、文档型与版本运行器行为补充聚焦测试;T009 的 S1 自审循环已完成。S1 的验证命令在 roadmap.md 中明确给出:
dotnet test test/unit/Elsa.Persistence.VNext.UnitTests/Elsa.Persistence.VNext.UnitTests.csproj对应的测试工程位于 test/unit/Elsa.Persistence.VNext.UnitTests。
三、S2 — Portable SQLite Document Store MVP:可移植文档存储的最小可用版本
S2 的目标:在 SQLite 上实现一个 Provider 无关的文档存储,支持保存、加载、删除、索引维护与按声明索引查询(T012–T021)。除 T021(PR 合并与 issue 关闭)外全部完成。
3.1 文档包络与存储契约(T012)
T012 定义了StoredDocument(文档包络:存储的元数据与负载)与IDocumentStore契约,见 Document/IDocumentStore.cs,接口包含五个核心方法:
MaterializeAsync:物化 Schema/索引;SaveAsync(SaveDocumentRequest, ...):保存并返回StoredDocument;LoadAsync(storageUnit, id, ...):按存储单元与 ID 加载;DeleteAsync(storageUnit, id, expectedVersion, ...):删除,支持期望版本参数;QueryAsync(DocumentQuery, ...):按声明索引查询。
3.2 表物化与索引维护(T013–T016)
- T013 在 SQLite 侧实现文档表物化(SqliteDocumentStore.cs);
- T014 实现 save/load/delete 三件套;
- T015 实现通用字段索引存储(Generic field index table);
- T016 关键要求是索引维护与文档写入处于同一事务,对应 spec.md Edge Case 中"文档保存成功但索引维护失败"的场景——同一事务保证了二者要么同时成功、要么同时回滚。
3.3 索引查询、并发控制与未索引校验(T017–T019)
- T017 实现按声明索引查询:
DocumentQuery只接受StorageUnit+ 过滤器字典(见 Document/DocumentQuery.cs),这从类型层面就限制了查询只能走声明过的索引字段; - T018 增加乐观并发(Optimistic Concurrency),配合
DeleteAsync的expectedVersion参数,冲突时抛出 DocumentStoreConcurrencyException.cs; - T019 增加未索引查询校验:查询引用未声明索引的字段时,抛出 DocumentQueryNotIndexedException.cs,对应 spec.md 的 FR-009/FR-010(可移植查询只能走声明索引,未支持/未索引查询返回清晰错误)与 User Story 3 的验收场景 3。
3.4 测试(T020)
T020 为 SQLite 文档存储补充了单元/集成测试,覆盖 save/load/delete、事务性索引维护、索引查询与乐观并发。
四、S3 — SQL Server And PostgreSQL Relational Document Providers:关系型文档 Provider 家族
S3 的目标:让同一套文档/索引契约在 SQL Server 与 PostgreSQL 上通过(T022–T026)。T022(SQL Server Provider)、T023(PostgreSQL Provider)、T024(启动锁定/物化策略)已完成;T025(关系型 Provider 契约测试)与 T026(PR 合并)仍待办。
4.1 两个 Provider 的实现
- SQL Server 侧:
SqlServerDocumentStore、SqlServerDocumentStoreDialect、SqlServerSchemaSqlRenderer、SqlServerTypeMapper(见 src/modules/Elsa.Persistence.VNext.SqlServer); - PostgreSQL 侧:
PostgreSqlDocumentStore、PostgreSqlDocumentStoreDialect(见 src/modules/Elsa.Persistence.VNext.PostgreSql); - 两者共享关系型文档存储基座 src/modules/Elsa.Persistence.VNext.Relational(
RelationalDocumentStore与RelationalDocumentStoreDialect),实现"Provider 差异隔离在各自包内"的验收要求。
4.2 启动锁定与物化策略(T024)
T024 要求启动物化具备并发安全策略。spec.md 的 Edge Case 第一条就是"多个应用实例并发启动并尝试物化",因此 S3 需要在多实例场景下通过启动锁定保证只有一台实例执行 Schema 物化,其余实例等待完成后继续,避免 DDL 竞争。
4.3 验证前提
roadmap.md 的本地进度注明:Provider 包与 SQL 方言测试已在本地实现,但真实的 SQL Server/PostgreSQL 契约测试需要运行中的 Docker/Testcontainers 环境或 CI worker。即 T025 属于"代码就绪、环境受限"的待办,这一点在阅读任务清单时应结合 roadmap 的说明理解。
五、S4 — MongoDB Document Provider:原生文档数据库支持
S4 的目标:同一存储/索引模型在 MongoDB 上以原生集合与原生索引运行(T027–T032)。T027–T030 完成,T031(契约测试)与 T032(PR 合并)待办。
5.1 原生物化与查询翻译
- T027 实现 MongoDB 文档 Provider(MongoDbDocumentStore.cs);
- T028 物化原生集合与索引:
MongoDbDatabasePlanner把 Manifest 规划为MongoDbDatabasePlan(含MongoDbCollectionPlan、MongoDbIndexPlan),见 src/modules/Elsa.Persistence.VNext.MongoDb; - T029 实现声明索引的查询翻译,让可移植查询走 MongoDB 原生查询/索引模型,对应 spec.md User Story 4 的验收场景 2;
- T030 增加乐观并发——roadmap.md 特别指出 MongoDB 侧通过期望版本写入/删除过滤器(expected-version write/delete filters)实现,即保存/删除时携带期望版本号,由 MongoDB 端原子地校验。
5.2 事务与拓扑的边界
spec.md 的 Edge Case 提醒:MongoDB 事务支持在部分部署拓扑中不可用。因此乐观并发的实现不应依赖多文档事务,而是依赖单文档原子操作与版本字段——这也是 T030 采用 expected-version 过滤器的原因。T031 的本地实现同样已完成,但真实契约测试需要运行中的 MongoDB 服务或 CI worker(roadmap.md 本地进度注明)。
六、S5 — Elsa Integration And First Module Migration:接入 Elsa 并迁移第一个模块
S5 的目标:Elsa 消费 vNext 持久化,至少一个真实模块不再需要 EF Core 迁移(T033–T038)。T033–T036 完成;T037(如需则提供 EF Core 存量导入/迁移路径)与 T038(PR 合并)待办。
6.1 集成包与特性注册(T033–T034)
- T033 增加 Elsa vNext 持久化集成包,即 src/modules/Elsa.Persistence.VNext.Extensions;
- T034 增加 Shell 特性/选项/启动物化:
- PersistenceVNextFeature.cs 以 Elsa 特性系统(
FeatureBase)注册 vNext,ConfigureOptions回调可配置PersistenceVNextOptions; - PersistenceVNextStartupTask.cs 在应用启动时执行物化;
- DefaultPersistenceSchemaCatalog.cs 实现
IPersistenceSchemaCatalog,聚合各模块贡献的 Manifest。
- PersistenceVNextFeature.cs 以 Elsa 特性系统(
6.2 诊断输出(T035)
T035 增加"已应用 Manifest 与 Provider 状态"诊断,对应 FR-017(暴露 Manifest 版本、Provider 状态与物化失败诊断)。实现载体为 DefaultPersistenceVNextStatus.cs 与 PersistenceVNextStatusSnapshot.cs,通过IPersistenceVNextStatus契约对外暴露状态快照。
6.3 Secrets 模块迁移(T036)
T036 实现 Secrets vNext 存储,是 spec.md 中"Secrets 是首选迁移的真实模块"这一假设的直接落地。roadmap.md 本地进度注明:Secrets 现有 EF Core 持久化保持不变,存量数据导入/迁移路径(T037)刻意留待存储模型进一步验证后再决定——对应 spec.md 的 FR-015(现有模块逐步迁移)与 Edge Case"存量 EF Core 数据必须导入 vNext 存储"。
6.4 迁移的验收标准
S5 的验收标准(roadmap.md):
- Secrets 可在 vNext 持久化上运行;
- Secrets vNext不再需要 Provider 专属的 EF Core 迁移包(对应 FR-016:EF Core 迁移退出 vNext 的 Schema 权威路径);
- 现有行为保持不变。
七、S6 — Runtime-Defined Entities:管理员运行时定义实体
S6 的目标:管理员可在运行时定义实体,发布后持久化,并按声明索引查询,默认不按实体建物理表(T039–T044)。T039–T043 完成,T044(PR 合并)待办。
7.1 运行时实体模型与生命周期(T039–T040)
- T039 定义运行时实体定义模型,集中在 src/modules/Elsa.Persistence.VNext.Runtime/Models:
RuntimeEntityDefinition:包含Id、Name、Version、Status、Fields、Indexes与审计时间戳(见 RuntimeEntityDefinition.cs);RuntimeEntityFieldDefinition/RuntimeEntityFieldType/RuntimeEntityIndexDefinition:字段与索引声明;RuntimeEntityInstance:运行时实体的实例(以文档形式存储)。
- T040 实现 draft/published/retired 生命周期,状态枚举见 RuntimeEntityDefinitionStatus.cs,对应 FR-013。
7.2 校验与能力检查(T041)
T041 由 RuntimeEntityDefinitionValidator.cs 承担:草稿实体发布前必须通过校验(字段类型、索引声明、Provider 能力等),对应 spec.md 的 FR-004(物化前 Provider 能力校验)。
7.3 CRUD/API 与审计(T042–T043)
- T042 由 IRuntimeEntityManager.cs 与 RuntimeEntityManager.cs 提供服务级 CRUD/查询 API。roadmap.md 本地进度明确:POC 刻意不添加 Studio UI 与 HTTP 端点,只提供服务层 API;
- T043 增加审计轨迹,载体为 RuntimeEntityAuditRecord.cs。
7.4 不按实体建表的设计要点
S6 的验收标准强调"默认不要求为每个运行时实体创建物理表"。这正是文档存储模型的价值所在:实体实例以文档 + 声明索引的方式落在通用存储中,避免"每实体一表"的爆炸式物理结构;而按需的物理化优化留到 S7 的策略机制处理。
八、S7 — Physicalization And Performance:按策略的物理化与性能优化
S7 的目标:热点实体与索引可选入 Provider 优化的物理存储形态,且不修改模块 Manifest 代码(T045–T049)。T045–T047 完成;T048(基准测试)与 T049(PR 合并)待办。
8.1 存储策略模型(T045)
T045 在 src/modules/Elsa.Persistence.VNext/Physicalization 目录落地:
StoragePhysicalizationPolicy:每个存储单元/索引选择的优化模式;PhysicalizedIndexPolicy:索引级优化策略;PhysicalizationTarget/PhysicalizationPlan:物理化目标与执行计划;IPhysicalizationPlanner:物理化规划器契约;PhysicalizationPolicyValidator:策略校验,负责"Provider 不支持某物理化形态时,在应用前报告"(spec.md User Story 6 验收场景 2,也是 FR-004 的延续)。
8.2 两个 Provider 的物理化示例(T046–T047)
- T046 为关系型 Provider 实现优化的索引:SQLite 侧由 SqlitePhysicalizationPlanner.cs 规划专用表/索引 DDL;
- T047 为文档 Provider 实现原生优化:MongoDB 侧由 MongoDbPhysicalizationPlanner.cs 规划专用集合/原生索引操作。
二者共同遵守 roadmap.md 的验收要求:"可移植默认保持不变"——策略是 opt-in 的逃生舱,不是默认行为。T048 的真实工作负载基准测试仍待办,这与 S8 的基准门控直接相关。
九、S8 — Workflow Runtime Evaluation And Hardening:工作流运行时评估与加固
S8 的目标:对工作流运行时热路径做基准评估、并发/锁定验证与生产化加固,输出明确的 go/no-go 决策(T050–T054)。T052、T053 完成;T050、T051、T054 待办。
9.1 运行时候选评估(T053)
T053 的产物集中在 src/modules/Elsa.Persistence.VNext.Runtime/Evaluation:
WorkflowRuntimePersistenceEvaluator:运行时评估器;WorkflowRuntimePersistenceCandidate:候选存储的刻画(名称、负载特征);WorkflowRuntimePersistenceDecision:决策记录,包含DecisionKind、Reasons与RequiredEvidence(见 WorkflowRuntimePersistenceDecision.cs)。
决策类型WorkflowRuntimePersistenceDecisionKind定义了四种出路:
AdoptVNext:直接采用 vNext;AdoptWithPhysicalization:采用 vNext 但需配合物理化策略;DeferUntilBenchmarked:推迟到基准测试后决定;KeepSpecializedProvider:保留专用 Provider。
9.2 当前的评估结论(roadmap.md 本地进度)
roadmap.md 明确记录了当前分类:
- 元数据/模块类存储(Metadata/Module stores):被分类为 vNext 的优质候选(good vNext candidates);
- 热点查找类存储(Hot lookup stores):基准测试门控(benchmark-gated),即必须等 T050 基准数据才能进入 go 状态;
- 队列/日志类工作负载(Queue/log workloads):保持专用 Provider 候选(specialized-provider candidates)。
这正好印证了 spec.md 假设中的"工作流运行时热路径后续评估,不是首个迁移目标"。真实 Provider 基准测试(T050)与并发/锁定契约测试(T051)仍然开放。
9.3 诊断与恢复指导(T052)
T052 增加 Provider 诊断与恢复指导,与 S5 的诊断输出(T035)一脉相承,共同服务于"Provider 状态报告与物化失败诊断"这一运维闭环。
十、任务状态总览与剩余工作
下表汇总 8 个阶段的任务完成度(依据 tasks.md 原始勾选状态):
| 阶段 | 主题 | 已完成 | 待办(未合并/未完成) |
|---|---|---|---|
| S1 | 核心 Manifest 与规划器基础 | T001–T007, T009 | T008(开/更新 PR)、T010(合并)、T011(关闭 issue) |
| S2 | SQLite 可移植文档存储 MVP | T012–T020 | T021(PR 合并与 issue 关闭) |
| S3 | SQL Server / PostgreSQL 关系型 Provider | T022–T024 | T025(契约测试,依赖 Docker/Testcontainers 或 CI)、T026 |
| S4 | MongoDB 文档 Provider | T027–T030 | T031(契约测试,依赖 MongoDB 服务或 CI)、T032 |
| S5 | Elsa 集成与首个模块迁移 | T033–T036 | T037(存量 EF Core 导入路径,视需要)、T038 |
| S6 | 运行时定义实体 | T039–T043 | T044 |
| S7 | 物理化与性能 | T045–T047 | T048(基准测试)、T049 |
| S8 | 运行时评估与加固 | T052, T053 | T050(运行时基准)、T051(并发/锁定验证)、T054 |
整体来看,架构主体(S1–S7 的编码部分)均已实现,剩余工作集中在三类:
- PR 合并与 issue 收尾(T008/T010/T011、T021、T026、T032、T038、T044、T049、T054):属于流程性待办;
- 依赖环境的契约/集成测试(T025、T031、T051):需要 Docker/Testcontainers、CI worker 或真实数据库服务;
- 基准与决策证据(T048、T050):基准测试开放,直接决定运行时热路径的 go/no-go。
十一、验证与运行方式
任务的本地验证入口(来自 roadmap.md)为:
dotnet test test/unit/Elsa.Persistence.VNext.UnitTests/Elsa.Persistence.VNext.UnitTests.csproj该测试工程覆盖 S1 的关系型、文档型与版本运行器行为。其余阶段的验证分布在各 Provider 包的聚焦测试中,真实数据库契约测试(SQL Server / PostgreSQL / MongoDB)需要运行中的数据库服务或 CI worker。
若要在应用内启用 vNext,可通过 PersistenceVNextFeature 以 Elsa 特性系统方式注册,并用ConfigureOptions配置 PersistenceVNextOptions.cs;启动时由PersistenceVNextStartupTask完成 Schema/索引物化。
十二、相关文档与源码索引
继续深入阅读的仓库入口:
- 任务清单:specs/011-persistence-vnext/tasks.md
- 功能规范(用户故事、需求 FR-001–FR-018、成功标准):specs/011-persistence-vnext/spec.md
- 可执行路线图(范围、验收、issue 映射、本地进度):specs/011-persistence-vnext/roadmap.md
- 规范质量检查清单:specs/011-persistence-vnext/checklists/requirements.md
- 核心模型与规划器:src/modules/Elsa.Persistence.VNext(
Models、Relational、Document、Contracts、Physicalization) - SQLite 实现:src/modules/Elsa.Persistence.VNext.Sqlite
- SQL Server 实现:src/modules/Elsa.Persistence.VNext.SqlServer
- PostgreSQL 实现:src/modules/Elsa.Persistence.VNext.PostgreSql
- MongoDB 实现:src/modules/Elsa.Persistence.VNext.MongoDb
- Elsa 集成包:src/modules/Elsa.Persistence.VNext.Extensions
- 运行时实体与运行时评估:src/modules/Elsa.Persistence.VNext.Runtime
- 单元测试工程:test/unit/Elsa.Persistence.VNext.UnitTests
结语
specs/011-persistence-vnext/tasks.md 是 Elsa Persistence vNext 从规范走向实现的最直接证据:54 个任务把"Provider 无关存储清单 + 规划器/渲染器 + 可移植文档存储 + 多 Provider 物化 + 运行时实体 + 物理化策略 + 运行时评估"这条完整架构链拆解为可独立验证的增量步骤。结合 spec.md 的需求与 roadmap.md 的进度说明,可以确认:核心编码已基本完成,当前主战场在 PR 收尾、真实数据库契约测试与基准决策。对于希望参与或评估该架构的开发者,S1 的"同一 Manifest 双路规划"、S2 的"事务性索引维护 + 乐观并发"、S8 的"四类 go/no-go 决策"是最值得优先研读的三个切入点。
- 后端
- 工作流自动化
- 流程编排
- 低代码
【免费下载链接】elsa-core
The Workflow Engine for .NET
相关推荐
Elsa Persistence vNext 执行路线图解析:从模块存储清单到可移植文档存储的八阶段演进
Elsa Persistence vNext 执行路线图解析:从模块存储清单到可移植文档存储的八阶段演进 本文以 specs/011 persistence v
后端工作流自动化流程编排低代码Elsa Persistence vNext 工作流运行时持久化评估:哪些存储该迁移,哪些必须保留专用 Provider
Elsa Persistence vNext 工作流运行时持久化评估:哪些存储该迁移,哪些必须保留专用 Provider Persistence vNext 是
后端工作流自动化流程编排低代码Elsa Persistence vNext 路线图深度解析:让模块声明一次存储意图、由数据库提供方物化物理模型
Elsa Persistence vNext 路线图深度解析:让模块声明一次存储意图、由数据库提供方物化物理模型 导读 本文基于 design/persiste
后端工作流自动化流程编排低代码
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考