JobSpec.timeout_seconds 此前无法表达“显式不限时”:所有未声明预算的协程任务 一律补齐 SCHEDULER_JOB_TIMEOUT,订阅搜索队列因此被 3600 秒总时长判死,而它的 托管协程消费者无法靠取消收尾,只会把正常长轮次记成失败。现在收敛为三态语义 (正数为上限、0 为显式不限时、缺省继承默认),并修正 asyncio 超时异常 str() 为空导致的日志、系统通知与 SystemError 事件文本缺失。
4.7 KiB
智能助手执行优先策略
交互轮次从宿主 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 提供,修改后重启生效。