Sparkdo.Runtime.Contracts
0.0.1-preview.3
dotnet add package Sparkdo.Runtime.Contracts --version 0.0.1-preview.3
NuGet\Install-Package Sparkdo.Runtime.Contracts -Version 0.0.1-preview.3
<PackageReference Include="Sparkdo.Runtime.Contracts" Version="0.0.1-preview.3" />
<PackageVersion Include="Sparkdo.Runtime.Contracts" Version="0.0.1-preview.3" />
<PackageReference Include="Sparkdo.Runtime.Contracts" />
paket add Sparkdo.Runtime.Contracts --version 0.0.1-preview.3
#r "nuget: Sparkdo.Runtime.Contracts, 0.0.1-preview.3"
#:package Sparkdo.Runtime.Contracts@0.0.1-preview.3
#addin nuget:?package=Sparkdo.Runtime.Contracts&version=0.0.1-preview.3&prerelease
#tool nuget:?package=Sparkdo.Runtime.Contracts&version=0.0.1-preview.3&prerelease
Sparkdo.Runtime.Contracts
Sparkdo.Runtime.Contracts 是 Sparkdo 运行时的公共类型系统。它定义能力注册、Catalog、重协调、Host 绑定、快照作用域、导出租约、观测和停止结果等稳定边界,但不创建或执行运行时实例。
把它视为应用能力、源生成组合根、宿主适配器和运行时内核之间共同使用的协议包。所有公共类型位于 Sparkdo.Runtime 命名空间。
何时使用
在下列场景直接引用本包:
- 编写能力的声明、计划段、编译器、激活器、准备器或重协调器。
- 编写显式
IRuntimeRegistrationTable,或消费Sparkdo.Runtime.Generators生成的注册表。 - 编写 Host、配置、观测或运维适配器,并且只需要稳定的请求、结果和数据模型。
- 为能力导出定义强类型
Export<T>,并在调用方通过SnapshotScope获取Lease<T>。
本包不负责以下工作:
- 不扫描程序集,不按反射约定发现能力。
- 不调用
Microsoft.Extensions.Hosting、依赖注入容器或配置提供程序。 - 不创建
IRuntime;创建与执行由Sparkdo.Runtime的RuntimeFactory完成。 - 不提供测试夹具;测试用静态注册表位于
Sparkdo.Runtime.Testing。
安装与依赖
项目目标框架为 net10.0。项目文件未声明第三方 NuGet 依赖;它只提供运行时协议类型,并依赖目标框架提供的基础类库。
dotnet add package Sparkdo.Runtime.Contracts
仅引用本包时,可以定义和交换契约,但不能启动运行时。需要执行 Catalog 时,还应引用内核包:
dotnet add package Sparkdo.Runtime
生产组合根通常还需直接引用生成器包。Sparkdo.Runtime 的 buildTransitive 规则会在 SparkdoRuntimeCompositionRequired=true 时检查这一点,并在缺少生成器资产时停止构建。
dotnet add package Sparkdo.Runtime.Generators
核心模型
运行时以显式注册和不可变输入驱动,不依赖隐式发现。典型数据流如下:
flowchart LR
A[组合根生成或提供 IRuntimeRegistrationTable] --> B[CreateCatalog: CatalogInputs]
B --> C[CatalogCreationResult]
C --> D[ReconciliationRequest]
D --> E[IRuntime.SubmitReconciliationAsync]
E --> F[ReconciliationResult]
F --> G[OpenScope]
G --> H[SnapshotScope]
H --> I[AcquireAsync: Lease T]
I --> J[DisposeAsync]
| 类型 | 责任 | 调用方应关注的结果 |
|---|---|---|
IRuntimeRegistrationTable |
声明运行环境、注册条目、贡献绑定,并根据 CatalogInputs 创建 Catalog。 |
CreateCatalog 返回 CatalogCreationResult;先检查 Succeeded,再使用 Catalog。 |
RuntimeRegistrationEntry |
描述一个能力的 Owner、契约、计划段、Host 绑定、扩展槽、原因、观测、工厂和编解码器。 | 由生成器或显式组合代码提供;同一运行时实例将其冻结为注册快照。 |
CapabilityRegistration<TPlan> |
将 ICapabilityCompiler<TPlan>、ICapabilityReconciler<TPlan>、ICapabilityActivator<TPlan> 和 ICapabilityPreparationAdapter<TPlan> 绑定到一个计划段。 |
四个行为对象及所有 ImmutableArray 集合都必须完整提供。 |
Catalog |
能力定义和来源的不可变描述,以及语义、实现和来源指纹。 | 作为每次重协调的输入,不能以可变全局状态替代。 |
CatalogInputs |
配置边界传入的能力输入值。 | 由配置适配器生成;无输入时使用 CatalogInputs.Empty。 |
HostBindingSnapshot |
一次重协调可见的宿主对象快照,包含 Revision、Source 和绑定值。 | 通过 ReconciliationRequest.HostBindings 传入,不应让能力自行访问 Host 容器。 |
IRuntime |
运行时的最小控制面:重协调、打开快照作用域、停止。 | 每个调用都返回结构化结果;结果中的 Reason 和 Observation 是运维关联信息。 |
SnapshotScope 与 Lease<T> |
固定一次读取所见的快照,并管理导出获取与释放。 | 二者都实现 IAsyncDisposable,必须按嵌套顺序释放。 |
能力执行契约
能力计划段实现 IPlanSection。注册时,CapabilityRegistration<TPlan> 使用以下接口把能力行为交给内核调度:
| 接口 | 调用时机 | 实现责任 |
|---|---|---|
ICapabilityCompiler<TPlan> |
构建候选计划时 | 从 CapabilityCompilationContext 生成确定性的计划段。 |
ICapabilityActivator<TPlan> |
候选能力进入准备流程前 | 从计划段创建 ICapabilityCandidate。 |
ICapabilityPreparationAdapter<TPlan> |
候选能力准备阶段 | 返回 CapabilityPreparationResult,其中包含可用性和 ICapabilityVersion。 |
ICapabilityReconciler<TPlan> |
比较活动计划与候选计划时 | 返回 ReconciliationDecision;若执行重载,则实现 PrepareReloadAsync。 |
ICapabilityCandidate |
丢弃、退役和释放候选资源时 | 实现 DiscardAsync、RetireAsync 与 DisposeAsync。 |
ICapabilityVersion |
版本进入活动快照后 | 暴露 ICapabilityExportProvider,并在退役时实现 ReleaseAsync。 |
能力提供导出时,ICapabilityExportProvider.TryAcquireAsync<T> 产生 ExportAcquireResult<T>。内核据此创建 Lease<T>;释放租约会调用对应的 IExportAcquisitionRelease.ReleaseAsync。因此导出提供方必须把获取和释放视为同一笔资源所有权,而不是把对象直接泄露给调用方。
最小可运行验证
下面的程序使用 Sparkdo.Runtime.Testing.StaticRuntimeRegistrationTable 验证契约调用顺序。该注册表是一个只用于测试、示例和包消费者冒烟验证的固定实现,不能作为生产能力注册方式。
dotnet add package Sparkdo.Runtime.Contracts
dotnet add package Sparkdo.Runtime
dotnet add package Sparkdo.Runtime.Testing
using System;
using Sparkdo.Runtime;
using Sparkdo.Runtime.Testing;
var registrations = StaticRuntimeRegistrationTable.Create();
var catalogResult = registrations.CreateCatalog(CatalogInputs.Empty);
if (!catalogResult.Succeeded || catalogResult.Catalog is null)
{
throw new InvalidOperationException("Catalog 创建失败。");
}
var creation = RuntimeFactory.Create(registrations);
if (!creation.Succeeded || creation.Runtime is null)
{
throw new InvalidOperationException("Runtime 创建失败。");
}
var runtime = creation.Runtime;
if (runtime is not IAsyncDisposable ownedRuntime)
{
throw new InvalidOperationException("直接创建的 Runtime 未提供异步释放能力。");
}
await using (ownedRuntime)
{
var published = await runtime.SubmitReconciliationAsync(
new ReconciliationRequest(catalogResult.Catalog));
if (published.Outcome != ReconciliationOutcome.Published)
{
throw new InvalidOperationException("Catalog 未发布。");
}
var opened = runtime.OpenScope();
if (!opened.Succeeded || opened.Scope is null)
{
throw new InvalidOperationException("活动快照不可用。");
}
await using (opened.Scope)
{
await using var lease = await opened.Scope.AcquireAsync(registrations.CreateExport());
Console.WriteLine(lease.Value);
}
var stopped = await runtime.StopAsync();
if (stopped.Status != RuntimeStopStatus.Stopped)
{
throw new InvalidOperationException("Runtime 未正常停止。");
}
}
RuntimeFactory.Create 返回的是 IRuntime,其公开契约本身不继承 IAsyncDisposable。当前内核实现支持异步释放,因此上述直接组合示例通过运行时检查取得该能力;使用 RuntimeHost、ConsoleRuntimeHost 或 Generic Host 适配器时,应由相应宿主拥有停止和释放责任。
生产组合入口与生成边界
生产应用不应手写 RuntimeCompositionTable。当组合根直接引用 Sparkdo.Runtime.Generators 并声明组合要求时,生成器在应用程序集的 Sparkdo.Runtime 命名空间生成该类型及其 Instance。
<PropertyGroup>
<SparkdoRuntimeCompositionRequired>true</SparkdoRuntimeCompositionRequired>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Sparkdo.Runtime" />
<PackageReference Include="Sparkdo.Runtime.Generators" />
</ItemGroup>
using Sparkdo.Runtime;
[assembly: RuntimeComposition("orders.api")]
// ----- 生成器边界开始 -----
// RuntimeCompositionTable 由 Sparkdo.Runtime.Generators 生成,禁止手写。
IRuntimeRegistrationTable registrations = RuntimeCompositionTable.Instance;
// ----- Contracts API 使用点开始 -----
var catalogResult = registrations.CreateCatalog(CatalogInputs.Empty);
if (!catalogResult.Succeeded || catalogResult.Catalog is null)
{
throw new InvalidOperationException("Catalog 创建失败。");
}
var request = new ReconciliationRequest(catalogResult.Catalog);
该片段刻意止于 ReconciliationRequest:Catalog 工件、输入路由和项目引用收集属于 Sparkdo.Runtime.Generators 的构建协议;运行时执行属于 Sparkdo.Runtime。这样可避免把构建期组合、配置读取和执行期生命周期混在一个类型中。
生命周期与失败语义
创建与重协调
- 调用
IRuntimeRegistrationTable.CreateCatalog(CatalogInputs)并检查CatalogCreationResult.Succeeded。 - 调用
RuntimeFactory.Create并检查RuntimeCreationResult.Succeeded、Runtime与Validation。创建阶段会冻结注册表并验证其绑定;不能假定失败时仍有可用的IRuntime。 - 使用
ReconciliationRequest提交 Catalog。若调用方掌握当前版本,应设置ExpectedCurrentRevision;若需要更新宿主对象,应同时提供新的HostBindingSnapshot。 - 按
ReconciliationResult.Outcome决策,而不是仅以“没有抛出异常”为成功条件。
ReconciliationOutcome |
调用方动作 |
|---|---|
Published |
新快照已成为活动视图;可以打开新 SnapshotScope。 |
Rejected |
请求、Catalog、环境或生命周期条件不满足;记录 Reason、Observation 和校验信息。 |
Superseded |
并发提交被新的候选请求替代;由上层决定是否重试最新状态。 |
RestartRequested |
当前切换策略要求宿主执行受控重启;不要把它当作已发布。 |
Quarantined |
内核无法证明状态安全;停止常规流量,并交由宿主按 Reason 与 Observation 处置。 |
快照、作用域与租约
OpenScope()成功时返回绑定到一个完整快照的SnapshotScope;失败时Scope为null,Succeeded为false,并携带可用性、原因和观测标识。- 重协调发布后,旧作用域仍保留其创建时的快照视图;新作用域使用新活动快照。这要求调用方不得跨请求、跨作业或跨租约缓存
SnapshotScope。 SnapshotScope.AcquireAsync<T>只允许获取该快照声明的Export<T>。未声明的导出会抛出ExportNotFoundException;声明但不可用的导出会抛出CapabilityUnavailableException。- 先释放
Lease<T>,再释放SnapshotScope。遗漏任何一个释放都会延长旧快照或能力版本的排空时间。
停止与隔离
IRuntime.StopAsync 首先关闭新作用域接纳,取消排队或执行中的重协调,然后等待活动快照排空。始终检查 RuntimeStopResult.Status:
RuntimeStopStatus |
含义 | 运维处理 |
|---|---|---|
Stopped |
活动快照已退役,运行时不可用。 | 可以完成宿主关闭。 |
DrainTimedOut |
新接纳已关闭,但现有作用域或租约未在期限内排空。 | 保持实例不可用,保留诊断并交由进程或编排器处置。 |
Quarantined |
取消确认、清理或生命周期状态无法安全确认。 | 停止普通请求,保留 Reason 与 Observation,执行人工或自动恢复流程。 |
生产接入注意事项
- 为每个能力稳定地定义
CapabilityId、Owner、契约范围、计划段、导出、依赖、Host 绑定和来源信息;它们参与 Catalog、计划和指纹校验。 - 用
CatalogInputs传递配置数据,用HostBindingSnapshot传递 Host 拥有的对象。不要把IServiceProvider、IConfiguration或可变全局对象直接藏进能力实现。 - 传给
CapabilityRegistrationBinding.Create的集合不能是default,且不能包含空项;使用ImmutableArray<T>.Empty表示空集合。 - 把
RuntimeEnvironment.IsAot与IsTrimmingEnabled视为实际部署约束,准确声明能力的CapabilityRuntimeProfile 和兼容性。 - 为
RuntimeOptions.Observations和IObservationSink设置与吞吐量匹配的容量、溢出策略与排空时间;观测管道不能替代关键业务的同步提交路径。 - 生产控制面必须记录所有非
Published、非Stopped结果中的Reason.Code、参数和ObservationId,并把这些结果接入告警和恢复策略。
与邻近项目的边界
| 项目 | 与本包的关系 |
|---|---|
Sparkdo.Runtime |
执行本包契约:验证注册、创建运行时、构建计划、重协调、维护快照和租约。 |
Sparkdo.Runtime.Generators |
在构建期收集工件并生成 RuntimeCompositionTable,不承担执行期生命周期。 |
Sparkdo.Runtime.Hosting |
将创建、初始发布、更新和停止编排为独立于框架的宿主生命周期。 |
Sparkdo.Runtime.Console |
将控制台信号和进程退出码适配到 RuntimeHost,不进入核心契约。 |
Sparkdo.Runtime.Configuration |
将显式配置路由转换为 CatalogInputs,不读取或执行能力。 |
Sparkdo.Runtime.Testing |
提供 StaticRuntimeRegistrationTable 等测试夹具,不是生产组合扩展点。 |
Sparkdo.Runtime.Inspection |
提供只读运行时投影,不暴露 Provider、导出实例或 Host 绑定对象。 |
验证命令
在仓库根目录执行:
dotnet restore src/runtime/Sparkdo.Runtime.slnx
dotnet build src/runtime/src/Sparkdo.Runtime.Contracts/Sparkdo.Runtime.Contracts.csproj --configuration Release --no-restore
dotnet build src/runtime/src/Sparkdo.Runtime/Sparkdo.Runtime.csproj --configuration Release --no-restore
dotnet test src/runtime/test/Sparkdo.Runtime.Specification.Tests/Sparkdo.Runtime.Specification.Tests.csproj --configuration Release --no-restore
对真实应用还应执行其组合根的 dotnet build,并在目标运行时标识符上运行一次发布后冒烟测试,确认生成的 RuntimeCompositionTable、Catalog 创建、首次发布、作用域获取和停止路径均可用。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages (6)
Showing the top 5 NuGet packages that depend on Sparkdo.Runtime.Contracts:
| Package | Downloads |
|---|---|
|
Sparkdo.Configuration
Sparkdo 统一运行时的框架无关配置输入绑定。 |
|
|
Sparkdo.Console
Sparkdo 统一运行时的控制台宿主适配。 |
|
|
Sparkdo.Configuration.MicrosoftExtensions
Sparkdo 统一运行时的 Microsoft.Extensions 配置适配。 |
|
|
Sparkdo.Hosting.MicrosoftExtensions
Sparkdo 统一运行时的 Generic Host 与 Microsoft DI 适配。 |
|
|
Sparkdo.Runtime.Inspection
Sparkdo 统一运行时的只读检查投影。 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.1-preview.3 | 75 | 8/26/2026 |
| 0.0.1-preview.2 | 78 | 8/25/2026 |
| 0.0.1-preview.1 | 95 | 8/25/2026 |