XiHan Framework 处于预览阶段

查看获取方式
跳转到内容

XiHan.Framework.Scheduling.InMemory ​

调度的默认实现,同时提供 scheduling.jobs@1(进程内作业存储加抽象包的引擎)与 scheduling.leader@1(进程内租约)。适用于单实例部署、开发与测试;Profiles.Full 已经包含它。

项内容
包 IDXiHan.Framework.Scheduling.InMemory
环层Ring 3(实现)
能力提供 scheduling.jobs@1、scheduling.leader@1(role: default);依赖 kernel.hosting@1
特性入口InMemorySchedulingFeature(清单 ID xihan.scheduling.inmemory)
配置节XiHan:Scheduling(引擎选项)、XiHan:Scheduling:InMemory(MaxRuns)
依赖XiHan.Framework.Scheduling.Abstractions;无第三方依赖
AOT兼容
稳定性Preview

概述 ​

本包只有作业存储与领导选举两样东西:misfire、并发阻塞、暂停与恢复、动态登记、重试、取消、历史都由抽象包的 JobSchedulerEngine 完成,语义与数据库实现一致。

InMemoryJobStore 把作业、触发器、运行历史与节点放在进程内的表里,全部操作在一把锁内完成,读出来的是深拷贝,调用方改不到存储里的对象。运行历史有界,最多 MaxRuns 条,超出时丢弃最旧的已结束记录。存储不跨实例共享(IsShared 为假),因此集群唯一的作业(RunOnEveryInstance = false)只在持有领导租约的实例上按计划运行,RunOnEveryInstance 的作业每个实例各自运行。

InMemoryLeaderElection 是进程内的租约表:同一资源在本进程内只有一个持有者,每次获取生成新的持有者标识,过期的记录视为空闲。它不能在实例之间互斥。

特性按能力求解的结果注册契约:

被选中的能力注册
scheduling.leaderILeaderElection → InMemoryLeaderElection
scheduling.jobsIJobStore → InMemoryJobStore,并装配 JobSchedulerEngine 与 IJobScheduler

只有 scheduling.leader 被别的 Provider 顶替时(如装配了 Scheduling.Kubernetes),引擎用那个 Provider 的选举,作业存储仍在本进程内。具体类型与健康项总是注册。

何时使用 ​

  • 单实例部署、开发环境、测试:零外部基础设施。
  • Kubernetes 多副本、只要求集群唯一的作业只跑一份:保留本包,加 Scheduling.Kubernetes 顶替领导选举。
  • 需要运行时作业在实例间共享、历史持久化、节点失联恢复:换 Scheduling.Database。

安装与启用 ​

bash
dotnet add package XiHan.Framework.Scheduling.InMemory --prerelease

当前是预览版,安装要带 --prerelease;从源码或本地包源引用见快速上手。Profiles.Full 已经装配本包;不用组合包时单独装配:

csharp
using XiHan.Framework.Hosting.AspNetCore;
using XiHan.Framework.Scheduling.InMemory;

var builder = WebApplication.CreateBuilder(args);
builder.AddXiHan(xihan => xihan.UseFeature<InMemorySchedulingFeature>());

配置 ​

键类型缺省说明
XiHan:Scheduling:InMemory:MaxRuns正整数1000运行历史上限,超出丢弃最旧的已结束记录

引擎选项(轮询周期、并发上限、misfire 阈值、租约、历史保留)在 XiHan:Scheduling,见 Scheduling.Abstractions。值不合法时启动抛 ArgumentException。

json
{
  "XiHan": {
    "Scheduling": {
      "PollIntervalSeconds": 1,
      "MaxConcurrentRuns": 32,
      "HistoryRetentionDays": 7,
      "InMemory": { "MaxRuns": 1000 }
    }
  }
}

主要类型 ​

类型说明
InMemorySchedulingFeature特性:注册存储、选举与健康项,被选中提供作业能力时装配引擎;应用启动时启动引擎,停止时等进行中的运行结束并释放租约
InMemoryJobStore进程内 IJobStore,IsShared 为假
InMemoryLeaderElection进程内 ILeaderElection
InMemorySchedulingOptionsMaxRuns
InMemorySchedulingHealthContributor健康项 scheduling.inmemory.leader(InMemorySchedulingFeature.HealthName)

使用示例 ​

csharp
using XiHan.Framework.Hosting.AspNetCore;
using XiHan.Framework.Primitives;
using XiHan.Framework.Scheduling.Abstractions;
using XiHan.Framework.Scheduling.Abstractions.Jobs;
using XiHan.Framework.Scheduling.Abstractions.Schedules;
using XiHan.Framework.Scheduling.InMemory;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddJob<HeartbeatJob>("heartbeat", JobSchedule.Every(TimeSpan.FromSeconds(10)));
builder.AddXiHan(xihan => xihan.UseFeature<InMemorySchedulingFeature>());

var app = builder.Build();
app.UseXiHan();
app.Run();

public sealed class HeartbeatJob(ILogger<HeartbeatJob> logger) : IJob
{
    public ValueTask<Result> RunAsync(JobRun run, InvocationContext context, CancellationToken cancellationToken)
    {
        logger.LogInformation("Heartbeat run {RunId}.", run.Id);
        return ValueTask.FromResult(Result.Success());
    }
}

framework/samples/KubernetesApp 的 HeartbeatFeature 用同样的写法在特性的 Configure 里登记作业,本地运行时就由本包调度。

行为与限制 ​

  • 进程重启后,运行时登记的作业、暂停状态、运行历史都丢失;代码登记的作业在下次启动时重新写入。
  • 运行历史全部是运行中的记录、已经没有可丢弃的已结束记录时,开始新运行返回 SCHEDULING_UNAVAILABLE_004。
  • 存储不共享,没有节点心跳与失联恢复:RequestsRecovery 不起作用,集群唯一的作业的重试也只有本进程看得到。
  • 多个实例各用一份本包时,每个实例都持有自己的进程内租约,集群唯一的作业会在每个实例上各跑一份。
  • 健康项 scheduling.inmemory.leader 同步计算:引擎在跑为 Ready(进程内租约持有与否都不影响服务),引擎停止为 Stopped;作业能力被别的 Provider 顶替、没有引擎时也是 Ready。
  • 通过 Scheduling.Conformance 的调度器、存储与领导选举三个套件。

相关 ​

Released under The MIT License