Skip to content

调度器集成

这一篇是扩展专题——如果你需要定时任务能力,怎么把它接进这个项目。

当前状态

这个项目目前没有集成 soulsoft_scheduler。代码里没有 addScheduler()IJob 实现或 HostedService 注册。

不过,项目的架构(DI 容器、DbContext、分层结构)已经为接入调度器准备好了条件。

接入前的准备

先确保你理解这些基础概念(建议先看 Scheduler 专题文档):

  • Scheduler 如何注册进 Spire 宿主
  • IJob 接口的定义和生命周期
  • HostedService 如何驱动定时任务

专题入口:Scheduler 总览

适合接入的场景

这个博客项目有四类场景天然适合定时任务:

1. 定时发布

职责:查询"发布时间已到但还设为私密"的文章,批量公开。

cangjie
// 伪代码:定时发布 Job
public class PublishScheduledPostsJob <: IJob {
    let blogRepo: IBlogRepository

    public func execute(context: JobExecutionContext): Unit {
        let now = DateTime.now()
        let posts = blogRepo.findScheduledBefore(now)  // 仓储层封装查询
        for (post in posts) {
            post.isPublic = 1
            blogRepo.update(post)
        }
        blogRepo.saveChanges()
    }
}

2. 热门榜单重算

职责:定时刷新热门文章排名,避免每次请求实时计算。

3. 数据清理

职责:清理过期草稿、无效评论、临时文件。

4. 缓存预热

职责:首页加载慢时,定时把热门数据加载到缓存。

推荐接入方式

直接在现有 web-api 宿主里加,不要另开一个进程:

cangjie
// 在 main.cj 里加
builder.services.addScheduler() {
    options =>
        options.scheduleJob<PublishScheduledPostsJob>("0 */5 * * *")  // 每5分钟
        options.scheduleJob<RecalculatePopularJob>("0 0 2 * *")       // 每天凌晨2点
}
builder.services.addSchedulerHostedService()

原因:

  • 现有 DI 容器、DbContext、Repository、配置体系全部可以直接复用
  • 不需要为定时任务单独维护一套数据库连接
  • 部署仍然是单进程

分层建议

定时任务也遵循分层原则:

text
IJob(调度入口)   → 只做参数编排,不写业务
Application Service → 真正的业务逻辑
Repository          → 数据访问
cangjie
// ✅ IJob 只做编排
public class PublishScheduledPostsJob <: IJob {
    let service: BlogService     // 不直接注 DbContext

    public func execute(context: JobExecutionContext): Unit {
        service.publishScheduledPosts()
    }
}

// ✅ BlogService 做业务
public func publishScheduledPosts(): Unit {
    let posts = blogRepo.findScheduledBefore(DateTime.now())
    for (post in posts) {
        post.isPublic = 1
        blogRepo.update(post)
    }
    blogRepo.saveChanges()
}

不推荐在 IJob 里直接操作 DbContext——Job 是调度框架的入口,业务逻辑应该留在应用层。

注意事项

  • 默认禁止同一任务并发执行,避免多个实例同时操作同一批数据
  • 定时任务的事务管理独立于请求事务,需要在 Job 内部自行控制事务边界
  • 调度器依赖于宿主进程一直在运行,部署时确保进程监控和自动重启

相关专题