Sparkdo.Runtime.Contracts 0.0.1-preview.7

This is a prerelease version of Sparkdo.Runtime.Contracts.
dotnet add package Sparkdo.Runtime.Contracts --version 0.0.1-preview.7
                    
NuGet\Install-Package Sparkdo.Runtime.Contracts -Version 0.0.1-preview.7
                    
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.7" />
                    
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.7" />
                    
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.7
                    
#r "nuget: Sparkdo.Runtime.Contracts, 0.0.1-preview.7"
                    
#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.7
                    
#: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.7&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Sparkdo.Runtime.Contracts&version=0.0.1-preview.7&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.Runtime.Testing

Sparkdo 统一运行时的框架无关合规测试工具。

Sparkdo.Runtime.Inspection

Sparkdo 统一运行时的只读检查投影。

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.1-preview.7 95 9/7/2026
0.0.1-preview.3 109 8/26/2026
0.0.1-preview.2 103 8/25/2026
0.0.1-preview.1 119 8/25/2026