Skip to content

修复 PLUGIN_TIMEOUT 超时后仍等待慢任务的问题 - #153

Closed
henrycjchen wants to merge 1 commit into
fish2018:mainfrom
henrycjchen:fix/batch-timeout-no-wait
Closed

henrycjchen wants to merge 1 commit into
fish2018:mainfrom
henrycjchen:fix/batch-timeout-no-wait

Conversation

@henrycjchen

Copy link
Copy Markdown

问题

PLUGIN_TIMEOUT 设了之后只丢结果,不缩短耗时。

pool.ExecuteBatchWithTimeout(TG 频道和插件搜索共用)到超时后,GetResults 会按时返回,但 defer pool.Close() 里的 p.wg.Wait() 会一直阻塞,直到所有还在跑的任务结束。task() 本身不能被中断,所以整批耗时还是等于最慢的那个插件或频道。

复现:某个插件要 17s 左右(例如 hdmoli,它内部自带 30s 超时加重试),设 PLUGIN_TIMEOUT=5,src=plugin 仍然要 17s,而且超时后完成的那部分结果被丢掉了。

修改

  • ExecuteBatchWithTimeout:收集结果后,如果没收齐(超时),就在后台 go pool.Close(),调用方按超时时间拿到已完成的结果。正常全部完成的情况还是同步关闭,行为不变。
  • worker 发结果时同时监听 ctx.Done()。超时后没人再读 results,这样可以避免后台 worker 阻塞在通道上泄漏,也保证后台 Close() 能结束。
  • 新增 util/pool/worker_pool_test.go,覆盖超时和全部完成两种情况。

验证

  • go test -race -count=3 ./util/pool/ 通过(修复前超时用例耗时 2s,失败)。
  • 用仓库的 Dockerfile 分别构建 main 和本分支,PLUGIN_TIMEOUT=5、CACHE_ENABLED=false,/api/search?src=plugin&refresh=true:
关键词 main 本分支
漫长的季节 17.76s / 190 条 5.03s / 205 条
繁花 16.59s / 413 条 5.02s / 421 条

🤖 Generated with Claude Code

ExecuteBatchWithTimeout 超时后 GetResults 会按时返回,但 defer pool.Close()
中的 wg.Wait() 会阻塞到所有仍在执行的任务结束,导致整批耗时仍等于最慢的
插件/频道,超时只丢结果不提速。

- 超时时在后台关闭工作池,调用方按超时时间拿到已完成的结果
- worker 发送结果时同时监听 ctx,超时后不再阻塞在 results 通道上

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@henrycjchen

Copy link
Copy Markdown
Author

上游已在 d84c20e 中以更完整的方式修复(Shutdown(wait=false) + Task 接收 ctx),关闭此 PR。

@henrycjchen
henrycjchen deleted the fix/batch-timeout-no-wait branch September 27, 2026 01:41
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