refactor(schedule): 异步化月度计划生成以避免阻塞
将月度计划的生成过程从同步阻塞模式重构为异步非阻塞模式。 在 `ScheduleManager` 中,当月度计划耗尽时,现在会通过调用新的 `trigger_generate_monthly_plans` 方法来启动一个后台生成任务,而不是 `await` 其完成。这可以防止在生成新计划时(可能耗时较长)阻塞日常任务的调度流程。 同时,修复了 `MonthlyPlanManager` 中一个排序逻辑错误,确保在计划数量超出上限时,正确删除最旧的计划而不是最新的。
This commit is contained in:
@@ -77,7 +77,7 @@ class MonthlyPlanManager:
|
|||||||
if len(plans) > max_plans:
|
if len(plans) > max_plans:
|
||||||
logger.warning(f"当前月度计划数量 ({len(plans)}) 超出上限 ({max_plans}),将自动删除多余的计划。")
|
logger.warning(f"当前月度计划数量 ({len(plans)}) 超出上限 ({max_plans}),将自动删除多余的计划。")
|
||||||
# 按创建时间升序排序(旧的在前),然后删除超出上限的部分(新的)
|
# 按创建时间升序排序(旧的在前),然后删除超出上限的部分(新的)
|
||||||
plans_to_delete = sorted(plans, key=lambda p: p.created_at)[max_plans:]
|
plans_to_delete = sorted(plans, key=lambda p: p.created_at, reverse=True)[:len(plans)-max_plans]
|
||||||
delete_ids = [p.id for p in plans_to_delete]
|
delete_ids = [p.id for p in plans_to_delete]
|
||||||
delete_plans_by_ids(delete_ids)
|
delete_plans_by_ids(delete_ids)
|
||||||
# 重新获取计划列表
|
# 重新获取计划列表
|
||||||
@@ -138,6 +138,14 @@ class MonthlyPlanManager:
|
|||||||
finally:
|
finally:
|
||||||
self.generation_running = False
|
self.generation_running = False
|
||||||
|
|
||||||
|
def trigger_generate_monthly_plans(self, target_month: Optional[str] = None):
|
||||||
|
"""
|
||||||
|
以非阻塞的方式启动月度计划生成任务。
|
||||||
|
这允许其他模块(如ScheduleManager)触发计划生成,而无需等待其完成。
|
||||||
|
"""
|
||||||
|
logger.info(f"已触发 {target_month or '当前月份'} 的非阻塞月度计划生成任务。")
|
||||||
|
asyncio.create_task(self.generate_monthly_plans(target_month))
|
||||||
|
|
||||||
def _get_previous_month(self, current_month: str) -> str:
|
def _get_previous_month(self, current_month: str) -> str:
|
||||||
"""获取上个月的月份字符串"""
|
"""获取上个月的月份字符串"""
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -231,17 +231,15 @@ class ScheduleManager:
|
|||||||
|
|
||||||
# 如果计划耗尽,则触发补充生成
|
# 如果计划耗尽,则触发补充生成
|
||||||
if not sampled_plans:
|
if not sampled_plans:
|
||||||
logger.info("可用的月度计划已耗尽或不足,尝试进行补充生成...")
|
logger.info("可用的月度计划已耗尽或不足,触发后台补充生成...")
|
||||||
from mmc.src.schedule.monthly_plan_manager import monthly_plan_manager
|
from mmc.src.schedule.monthly_plan_manager import monthly_plan_manager
|
||||||
|
|
||||||
success = await monthly_plan_manager.generate_monthly_plans(current_month_str)
|
# 以非阻塞方式触发月度计划生成
|
||||||
if success:
|
monthly_plan_manager.trigger_generate_monthly_plans(current_month_str)
|
||||||
logger.info("补充生成完成,重新抽取月度计划...")
|
|
||||||
sampled_plans = get_smart_plans_for_daily_schedule(
|
# 注意:这里不再等待生成结果,因此后续代码不会立即获得新计划。
|
||||||
current_month_str, max_count=3, avoid_days=avoid_days
|
# 日程将基于当前可用的信息生成,新计划将在下一次日程生成时可用。
|
||||||
)
|
logger.info("月度计划的后台生成任务已启动,本次日程将不包含新计划。")
|
||||||
else:
|
|
||||||
logger.warning("月度计划补充生成失败。")
|
|
||||||
|
|
||||||
if sampled_plans:
|
if sampled_plans:
|
||||||
plan_texts = "\n".join([f"- {plan.plan_text}" for plan in sampled_plans])
|
plan_texts = "\n".join([f"- {plan.plan_text}" for plan in sampled_plans])
|
||||||
|
|||||||
Reference in New Issue
Block a user