Skip to content

异步任务与定时调度

Molore的大量能力是「到点自己跑」的:图谱自进化、自动打标、每日复盘、每周回顾、回填迁移、各类清扫。这些任务全部登记在启动钩子注册表(app/core/startup.pySTARTUP_HOOKS)里,调度器用 APScheduler / threading.Timer 实现。整条域的设计纪律只有三条:事件驱动必配定时兜底、撞锁记 pending 补跑、时限按执行体配速分级

调度任务总览

任务触发口径执行体代码位置
图谱自进化停笔 300s 防抖 + 距上次成功 ≥1800sgraphifyy CLI 子进程app/services/graphify_service.py
自动打标兜底扫描启动 120s 首扫 + 每小时本地 0.8b,零成本app/services/autotag_service.py
wiki 规则 lint启动 120s 首扫 + 每小时零模型纯 SQLapp/services/wiki_service/lint.py
KU title 回填启动 180s 首扫 + 每小时零成本解析优先,本地模型兜底app/services/knowledge_title.py
每日复盘每天 08:00(Asia/Shanghai)本地 0.8b,零成本app/services/daily_review_service.py
每周回顾每周一 08:00(Asia/Shanghai)本地 0.8b,零成本app/services/weekly_review_service.py
每日日报每天 08:30(CST)本地生成落库 + data/reports/*.mdapp/services/daily_report.py
表格文档回填启动 120s 一次性重抽取 + 重索引,marker 幂等app/services/document_service.py
标签日扫每日清幽灵关联 + 回收闲置 30 天空标签app/services/tag_maintenance.py
同步 oplog GC每日清理过期/被覆盖的 sync_operationsapp/services/sync_maintenance.py
计费调度周期订阅到期与自动续费app/core/billing_scheduler.py
RSS 自动抓取用户设置驱动rss_auto 开关app/services/rss_scheduler.py
插件自动同步周期manifest 声明app/services/plugin_scheduler.py

图谱自进化:防抖 + 重入锁

写入内容不再立即重建图谱——全量重建等于全语料逐篇 LLM 抽取,代价太高。自进化(graphify_service.py)采用防抖口径:

  • 停笔静默期 _EVOLVE_QUIET_SECONDS = 300:内容变更触发后置 dirty 并重排防抖计时器(threading.Timer),连续书写期间不打扰;
  • 最小间隔 _EVOLVE_MIN_INTERVAL = 1800:距上次成功构建不足 30 分钟不重复起建;
  • 撞锁不丢触发:计时器到期复核状态,构建已在跑或条件不满足时记 evolve_pending_bump_evolve_pending),构建完成后若期间有新内容(dirty)且成功,自动补排一轮——重入锁撞锁不能直接丢触发;
  • 重启恢复evolve_dirty=True 的行在启动钩子里重排防抖计时器,把重启丢掉的排定重建补回来;中断的构建同钩子里恢复;
  • 事件监听按会话派发:内容提交走 before_commit 捕获、after_commit 投递(after_commitsession.new 已清空,必须先暂存 _pending);lifespan 重入有防重复挂载守卫,一次提交不会触发 N 次自进化。

自进化配置存 user.settings["graphify"]["auto_evolve"](enabled + model),不动表结构;模型必须是构建允许的档位,推理档模型禁入图谱构建。

事件驱动必配定时兜底

凡 event-driven 的自动链路,一律加「启动首扫 + 每小时补扫」保险。这条纪律来自实捕事故:云端自动打标曾因事件链某一环(进程重启窗口/线程异常/监听脱落)静默失效近三周,零日志无人发现。现在的标配形态(以自动打标为例,autotag_service.py):

  • 内容变更事件监听触发即时处理;
  • 启动后 120s 首扫一遍存量(延迟 120s 是让启动主链路先就绪的约定口径);
  • 每小时兜底补扫,函数自带重入锁,扫到即处理、扫空即退;
  • 兜底扫描幂等,与事件链互不冲突——事件链是低延迟路径,兜底是存活证据。

同形态的还有 wiki lint(120s + 每小时,零模型纯 SQL)与 KU title 回填(180s + 每小时)。

每日复盘与每周回顾

  • 每天 08:00Asia/Shanghaidaily_review_service.py)为活跃用户生成昨日复盘;每周一 08:00weekly_review_service.py)生成上周回顾。
  • 全程本地 qwen3.5:0.8b,零成本;失败不落假复盘——模型不可用就跳过当天,绝不生成兜底内容充数(自动生成链路只走本地模型、绝不自动扣费的红线)。
  • 补课链 = 启动首查 + 每小时复查:错过 08:00 窗口(机器没开)的复盘在下次启动后补上,不依赖用户在场。
  • 素材口径:index_only 仓库模式内容不进复盘素材(tenant_scope.semantic_visible 过滤)。

一次性回填任务

管线升级后的存量追平走「启动 120s 后台跑一次 + marker 落 system_configs」形态,代表是 backfill_md_table_documentsdocument_service.py,marker extract_md_tables_v1):重抽取有差异才更新、FTS 重同步、向量重嵌,全部成才落 marker,中途失败下次启动重跑,天然幂等。详见内容入库的存量回填节。

时限按执行体配速分级

定时任务的超时不许拍脑袋,必须按执行体真实配速分级(血泪纪律:撞上强制思考的推理档,大图必超时卡死):

  • 推理档模型(如 GLM 5.3 Flash,强制思考)长任务按分钟计,JSON 类调用整体超时 180s 起配;
  • 图谱构建 CLI 子进程超时就文档数配速计算:max(1800, min(上限, 文档数 × 单篇配速)),小规模 30 分钟起步,大规模按量放宽;
  • 本地 0.8b 零成本链按秒~十秒级配;
  • 排队类(Ollama 本地推理门)超 120s 视为过载,生成路 yield [Error:]、嵌入路返回 [],沿用降级语义不悬挂。

下一步

基于 AGPL-3.0 协议发布。