Sparkdo.Runtime.Contracts 0.0.1-preview.3

This is a prerelease version of Sparkdo.Runtime.Contracts.
dotnet add package Sparkdo.Runtime.Contracts --version 0.0.1-preview.3
                    
NuGet\Install-Package Sparkdo.Runtime.Contracts -Version 0.0.1-preview.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Sparkdo.Runtime.Contracts" Version="0.0.1-preview.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Sparkdo.Runtime.Contracts" Version="0.0.1-preview.3" />
                    
Directory.Packages.props
<PackageReference Include="Sparkdo.Runtime.Contracts" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Sparkdo.Runtime.Contracts --version 0.0.1-preview.3
                    
#r "nuget: Sparkdo.Runtime.Contracts, 0.0.1-preview.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Sparkdo.Runtime.Contracts@0.0.1-preview.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Sparkdo.Runtime.Contracts&version=0.0.1-preview.3&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Sparkdo.Runtime.Contracts&version=0.0.1-preview.3&prerelease
                    
Install as a Cake Tool

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.RuntimeRuntimeFactory 完成。
  • 不提供测试夹具;测试用静态注册表位于 Sparkdo.Runtime.Testing

安装与依赖

项目目标框架为 net10.0。项目文件未声明第三方 NuGet 依赖;它只提供运行时协议类型,并依赖目标框架提供的基础类库。

dotnet add package Sparkdo.Runtime.Contracts

仅引用本包时,可以定义和交换契约,但不能启动运行时。需要执行 Catalog 时,还应引用内核包:

dotnet add package Sparkdo.Runtime

生产组合根通常还需直接引用生成器包。Sparkdo.RuntimebuildTransitive 规则会在 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 运行时的最小控制面:重协调、打开快照作用域、停止。 每个调用都返回结构化结果;结果中的 ReasonObservation 是运维关联信息。
SnapshotScopeLease<T> 固定一次读取所见的快照,并管理导出获取与释放。 二者都实现 IAsyncDisposable,必须按嵌套顺序释放。

能力执行契约

能力计划段实现 IPlanSection。注册时,CapabilityRegistration<TPlan> 使用以下接口把能力行为交给内核调度:

接口 调用时机 实现责任
ICapabilityCompiler<TPlan> 构建候选计划时 CapabilityCompilationContext 生成确定性的计划段。
ICapabilityActivator<TPlan> 候选能力进入准备流程前 从计划段创建 ICapabilityCandidate
ICapabilityPreparationAdapter<TPlan> 候选能力准备阶段 返回 CapabilityPreparationResult,其中包含可用性和 ICapabilityVersion
ICapabilityReconciler<TPlan> 比较活动计划与候选计划时 返回 ReconciliationDecision;若执行重载,则实现 PrepareReloadAsync
ICapabilityCandidate 丢弃、退役和释放候选资源时 实现 DiscardAsyncRetireAsyncDisposeAsync
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。当前内核实现支持异步释放,因此上述直接组合示例通过运行时检查取得该能力;使用 RuntimeHostConsoleRuntimeHost 或 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。这样可避免把构建期组合、配置读取和执行期生命周期混在一个类型中。

生命周期与失败语义

创建与重协调

  1. 调用 IRuntimeRegistrationTable.CreateCatalog(CatalogInputs) 并检查 CatalogCreationResult.Succeeded
  2. 调用 RuntimeFactory.Create 并检查 RuntimeCreationResult.SucceededRuntimeValidation。创建阶段会冻结注册表并验证其绑定;不能假定失败时仍有可用的 IRuntime
  3. 使用 ReconciliationRequest 提交 Catalog。若调用方掌握当前版本,应设置 ExpectedCurrentRevision;若需要更新宿主对象,应同时提供新的 HostBindingSnapshot
  4. ReconciliationResult.Outcome 决策,而不是仅以“没有抛出异常”为成功条件。
ReconciliationOutcome 调用方动作
Published 新快照已成为活动视图;可以打开新 SnapshotScope
Rejected 请求、Catalog、环境或生命周期条件不满足;记录 ReasonObservation 和校验信息。
Superseded 并发提交被新的候选请求替代;由上层决定是否重试最新状态。
RestartRequested 当前切换策略要求宿主执行受控重启;不要把它当作已发布。
Quarantined 内核无法证明状态安全;停止常规流量,并交由宿主按 ReasonObservation 处置。

快照、作用域与租约

  • OpenScope() 成功时返回绑定到一个完整快照的 SnapshotScope;失败时 ScopenullSucceededfalse,并携带可用性、原因和观测标识。
  • 重协调发布后,旧作用域仍保留其创建时的快照视图;新作用域使用新活动快照。这要求调用方不得跨请求、跨作业或跨租约缓存 SnapshotScope
  • SnapshotScope.AcquireAsync<T> 只允许获取该快照声明的 Export<T>。未声明的导出会抛出 ExportNotFoundException;声明但不可用的导出会抛出 CapabilityUnavailableException
  • 先释放 Lease<T>,再释放 SnapshotScope。遗漏任何一个释放都会延长旧快照或能力版本的排空时间。

停止与隔离

IRuntime.StopAsync 首先关闭新作用域接纳,取消排队或执行中的重协调,然后等待活动快照排空。始终检查 RuntimeStopResult.Status

RuntimeStopStatus 含义 运维处理
Stopped 活动快照已退役,运行时不可用。 可以完成宿主关闭。
DrainTimedOut 新接纳已关闭,但现有作用域或租约未在期限内排空。 保持实例不可用,保留诊断并交由进程或编排器处置。
Quarantined 取消确认、清理或生命周期状态无法安全确认。 停止普通请求,保留 ReasonObservation,执行人工或自动恢复流程。

生产接入注意事项

  • 为每个能力稳定地定义 CapabilityId、Owner、契约范围、计划段、导出、依赖、Host 绑定和来源信息;它们参与 Catalog、计划和指纹校验。
  • CatalogInputs 传递配置数据,用 HostBindingSnapshot 传递 Host 拥有的对象。不要把 IServiceProviderIConfiguration 或可变全局对象直接藏进能力实现。
  • 传给 CapabilityRegistrationBinding.Create 的集合不能是 default,且不能包含空项;使用 ImmutableArray<T>.Empty 表示空集合。
  • RuntimeEnvironment.IsAotIsTrimmingEnabled 视为实际部署约束,准确声明能力的 CapabilityRuntime Profile 和兼容性。
  • RuntimeOptions.ObservationsIObservationSink 设置与吞吐量匹配的容量、溢出策略与排空时间;观测管道不能替代关键业务的同步提交路径。
  • 生产控制面必须记录所有非 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • 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