Skip to content

fix(worker): PR3 调度/抓取链路 High 修复 6 项(session隔离+cs_feed关联+auto_link池+download_pdf异步+调度配置+graceful) - #50

Merged
Color2333 merged 1 commit into
mainfrom
worker/pr3-scheduling
Jul 18, 2026
Merged

fix(worker): PR3 调度/抓取链路 High 修复 6 项(session隔离+cs_feed关联+auto_link池+download_pdf异步+调度配置+graceful)#50
Color2333 merged 1 commit into
mainfrom
worker/pr3-scheduling

Conversation

@Color2333

Copy link
Copy Markdown
Owner

背景

Worker 抓取逻辑审计的 6 个 High 调度/抓取链路问题。基于 PR1(#46)+ PR2(#49,均已合入 main)之上。本 PR 重建(原 #48 因 PR2 合并删 base 分支自动关闭)。完成本 PR 即 3 PR 全部就绪。

修复清单

3a cs_feed 每 sub 独立 session(High)

packages/ai/cs_feed_orchestrator.py run() 此前单 session 跨所有 sub,一个 sub 抓取异常后的脏数据污染下个 sub。改:先读订阅列表后关闭读 session,每 sub 开独立 SessionLocalupsert_paper + update_run_status 在 sub session 内 commit。冷却设置也走独立 session。

3b cs_feed 抓取论文触发 embed + skim(High)

此前 cs_feed 只 upsert_paper 无 embed/skim,论文处于 unread 无 embedding 只能靠 idle_processor 事后补。新增 _process_cs_papers,抓取即复用 PaperPipelines 触发 embed + skim(限流 + 并发控制),失败不抛不阻断抓取主流程。

3c _bg_auto_link 线程池化(High)

packages/ai/pipelines/paper_pipelines.py 此前 threading.Thread(...).start() 无界 daemon 线程,5 个 topic 各起线程可能失控。改用模块级 ThreadPoolExecutor(max_workers=2) 复用,submit 替代 start。两处 collect(arxiv/IEEE)都改用池。

3d download_pdf 异步化 + 失败可见(High)

packages/ai/tools/handlers/ingest.py 逐篇同步 download_pdf 90s 超时阻塞 + 失败静默。改后台线程池下载(不阻塞 ingest 主流程),失败记录到论文 metadata(pdf_download_failed),deep_dive 时可见。新增 _download_pdf_async + _pdf_download_pool(max_workers=2,独立 session 隔离)。

3e worker 调度配置(High)

apps/worker/main.py 整点双 cron + 默认单线程池 + misfire_grace_time=1。给 4 个 job 显式配 max_instances=1, misfire_grace_time=300, coalesce=True。topic_dispatch 与 cs_feed_dispatch 错开分钟(topic minute=0,cs_feed minute=5)。executor 配 apscheduler ThreadPoolExecutor(max_workers=3)

3f graceful shutdown 等待任务(Med)

shutdown(wait=False)shutdown(wait=True),让 _process_paper 跑完,避免已下载 PDF 未 set_pdf_path 的中间态丢失。

验证

  • ruff / format 全通过
  • pytest:55 passed, 2 skipped(无回归)
  • alembic upgrade head 迁移链完整(PR3 无新迁移,链到 PR2 的 head f6a7b8c9d0e1
  • scheduler 配置实例化验证:max_instances=1, misfire_grace_time=300, coalesce=True 生效;topic minute=0 / cs_feed minute=5 错开
  • 运行时:cs_feed _process_cs_papers 空列表安全返回;线程池 max_workers 正确;worker main 导入正常

部署影响

  • 无新迁移、无新增配置项
  • 调度时间微调:cs_feed 从整点改为 :05(错开 topic_dispatch)
  • graceful shutdown 改 wait=True,关闭时间略增

3a cs_feed 每 sub 独立 session:此前单 session 跨所有 sub,一个 sub
异常后的脏数据污染下个 sub。改读订阅列表后关闭读 session,每 sub 开
独立 SessionLocal,upsert_paper + update_run_status 在 sub session 内
commit。冷却设置也走独立 session。

3b cs_feed 抓取论文触发 embed + skim:此前 cs_feed 只 upsert_paper 无
topic 关联无 embed/skim,论文处于 unread 无 embedding 只能靠 idle_processor
事后补。新增 _process_cs_papers,抓取即复用 PaperPipelines 触发 embed + skim,
失败不抛不阻断抓取主流程。

3c _bg_auto_link 线程池化:此前 threading.Thread(...).start() 无界 daemon
线程,5 个 topic 各起线程可能失控。改用模块级 ThreadPoolExecutor(max_workers=2)
复用,submit 替代 start,限制并发 auto_link。

3d download_pdf 异步化 + 失败可见:ingest.py 逐篇同步 download_pdf 90s
超时阻塞 + 失败静默。改后台线程池下载(不阻塞 ingest 主流程),失败记录到
论文 metadata(pdf_download_failed),deep_dive 时可见。

3e worker 调度配置:整点双 cron + 默认单线程池 + misfire_grace_time=1。
给 4 个 job 显式配 max_instances=1, misfire_grace_time=300, coalesce=True。
topic_dispatch 与 cs_feed_dispatch 错开分钟(topic minute=0,cs_feed minute=5)
避免同分钟抢线程。executor 配 apscheduler ThreadPoolExecutor(max_workers=3)。

3f graceful shutdown 等待任务:shutdown(wait=False) 不等待进行中任务,
改 shutdown(wait=True),让 _process_paper 跑完,避免已下载 PDF 未
set_pdf_path 的中间态丢失。

验证:AST + ruff + 55 passed;alembic 链完整跑到 head f6a7b8c9d0e1;
scheduler 配置实例化验证(max_instances/misfire/coalesce 生效);
cs_feed _process_cs_papers 空列表安全返回;线程池 max_workers 正确。
@github-actions

Copy link
Copy Markdown

🔍 OpenCode PR Review Required

这是一个受保护的分支,merge 前需要进行 code review。

请运行以下命令进行 OpenCode review:

/oc review https://github.com/Color2333/PaperMind/pull/$PR_NUM

或者在 PR 页面评论 /oc 来触发 OpenCode review。


This is an automated reminder from PR Review Gate.

@Color2333
Color2333 merged commit 416f9b4 into main Jul 18, 2026
3 checks passed
@Color2333
Color2333 deleted the worker/pr3-scheduling branch July 18, 2026 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant