mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-10-29 19:37:54 +08:00
JobSpec.timeout_seconds 此前无法表达“显式不限时”:所有未声明预算的协程任务 一律补齐 SCHEDULER_JOB_TIMEOUT,订阅搜索队列因此被 3600 秒总时长判死,而它的 托管协程消费者无法靠取消收尾,只会把正常长轮次记成失败。现在收敛为三态语义 (正数为上限、0 为显式不限时、缺省继承默认),并修正 asyncio 超时异常 str() 为空导致的日志、系统通知与 SystemError 事件文本缺失。
64 lines
4.7 KiB
Markdown
64 lines
4.7 KiB
Markdown
# 智能助手执行优先策略
|
||
|
||
交互轮次从宿主 `MoviePilotAgent.process` 进入,到本轮推理及工具调用收口后结束。
|
||
网页、消息渠道、CLI 和兼容 API 的前台请求使用交互容量;自主定时任务与心跳保持后台归属,
|
||
即使配置了结果回传渠道也不会升级为交互轮次。
|
||
|
||
默认启用 `AGENT_INTERACTIVE_PRIORITY=true`。这是协作式资源隔离:正在运行的同步线程、
|
||
数据库事务和后台协程不会被抢占。主事件循环仍采用 asyncio 的协作调度,
|
||
因此同步代码阻塞事件循环、CPU 饱和、数据库锁竞争和模型网络延迟仍可能影响响应。
|
||
|
||
| 执行边界 | 交互容量 | 普通后台容量 |
|
||
| --- | --- | --- |
|
||
| `ThreadHelper.submit` | 独立 4 线程 | 保留现有 `CONF.threadpool` |
|
||
| 宿主 `run_in_threadpool` | 当前事件循环共享 4 个 anyio 令牌 | 独立后台 limiter,容量跟随 anyio 默认配置(通常 40) |
|
||
| `DatabaseWorker.run` | 独立 1 线程、运行及排队总计 8 项 | 保留 4 线程、总计 32 项默认值 |
|
||
| Agent 同步工具 | 各能力域独立的交互桶 | 保留原能力域限额,供自主任务使用 |
|
||
| APScheduler | 自主 Agent 使用 `agent` 执行组,2 线程 | 其他任务使用原 `default` 组 |
|
||
|
||
以上容量按需启动工作线程,关闭时沿用各自生命周期 owner 的封口和收敛合同。
|
||
取消不会提前归还仍在执行的同步工具、线程调用或数据库事务的容量。
|
||
聊天持久化的全局写入准入也区分交互和后台;同一会话的写锁及单会话上限继续共享,
|
||
以免并发覆盖历史。`DatabaseWorker.snapshot()` 返回普通组,`interactive_snapshot()` 返回保留组;
|
||
数据库队列和执行指标包含两组的增减量。
|
||
|
||
执行归属通过上下文复制传入线程。`moviepilot_api` 的本机 HTTP 调用携带本进程随机登记的
|
||
临时执行凭据,由 ASGI 中间件恢复;普通自填请求头或已经结束的轮次无法取得优先级。
|
||
用户令牌与权限检查照常执行。子进程、外部 MCP 服务和插件自建线程池不受本策略控制。
|
||
框架同步鉴权与同步端点保留 anyio 默认 limiter,宿主后台线程调用不再消耗该组令牌;
|
||
框架自身的 HTTP 请求之间仍共用默认配额,不能保证在任意 HTTP 洪峰下立即响应。
|
||
|
||
## 后台避让
|
||
|
||
交互活跃时,新进入调度执行入口的非关键自动任务最多等待
|
||
`AGENT_BACKGROUND_DEFER_SECONDS` 秒,默认 30 秒,设为 `0` 禁用等待。
|
||
轮次结束后等待任务继续执行;持续对话超过预算时也会继续,避免后台任务饥饿。
|
||
期间保留原任务 generation、重入保护和协程句柄,不重复注册或补投任务。
|
||
调度器明确使用合并过期触发、单实例和无限 misfire 宽限,避免有限避让产生的排队
|
||
被默认一秒宽限误判为过期丢弃;任务自己的重入保护继续生效。
|
||
调度服务列表以“等待交互结束”显示正在避让的任务,API 的 `execution_group` 返回实际执行组。
|
||
|
||
Outbox 补偿、安全检查、数据库维护、运行时维护和手动专用任务不避让。
|
||
交互主动触发的同步调用不会等待自己结束;业务调度函数执行时会撤销继承的交互归属。
|
||
已有主循环同步入口沿用原调用合同,不在事件循环中同步等待。
|
||
避让只作用于新进入执行入口的任务,不会暂停或重放已开始的业务操作。
|
||
|
||
APScheduler 3 的标准线程池没有任意数值 `priority` 的调度能力。
|
||
这里通过独立执行组和实际准入等待实现隔离,不向 `add_job` 传入无效的优先级参数。
|
||
独立调度执行组仅隔离触发线程,协程仍回投到同一主循环。
|
||
|
||
## 超时
|
||
|
||
- `AGENT_LLM_TIMEOUT`:单次根 Agent 模型请求总预算,默认 180 秒,覆盖流式与非流式生成
|
||
以及该请求的供应商重试;`0` 表示不限时。工具执行时间由原 `LLM_TOOL_TIMEOUT` 管理。
|
||
- `SCHEDULER_JOB_TIMEOUT`:协程调度任务的默认执行预算,默认 3600 秒,等待避让不计入执行时间;
|
||
`0` 表示不限时。显式 `JobSpec.timeout_seconds` 优先于此默认值:正数是总时长上限,`0`
|
||
表示该任务显式不限时,缺省才继承此默认值。
|
||
|
||
超时通过协程取消收口,不能杀死同步线程或撤销已经发生的外部副作用。
|
||
数据库和线程调用仍等待实际操作收尾后释放容量,因而收尾时间可能超过超时预算。
|
||
超时后应先查询操作状态,再决定是否重试写入。
|
||
|
||
关闭 `AGENT_INTERACTIVE_PRIORITY` 可让 Agent 使用普通执行容量并停用避让;两项超时配置独立生效。
|
||
这些配置由部署环境或 `app.env` 提供,修改后重启生效。
|