MineContext icon indicating copy to clipboard operation
MineContext copied to clipboard

[Advice]: 定时任务代码优化

Open benhack20 opened this issue 2 months ago • 2 comments

📌 Documentation Location

ComsumptionManager中,启动任务的timer代码(以_start_report_timer为例),check_and_generate_daily_report里开启了定时线程,而定时线程的任务又是check_and_generate_daily_report(它会再次创建子线程),这导致:

  • 每次执行都会创建新线程,可能导致线程数量不断增长
  • 如果函数执行时间超过30分钟,会创建多个重叠的定时器
  • 内存泄漏风险 功能没问题,但是不建议这么实现。

🚑 Issue with Current Content

No response

👍 Suggested Improvement

No response

benhack20 avatar Oct 15 '25 05:10 benhack20

建议用threading.Event配合while循环实现定时器:

def _start_report_timer(self):
    def report_worker():
        while self._scheduled_tasks_enabled:
            try:
                if self._activity_generator:
                    now = datetime.now()
                    today = now.date()
                    
                    hour, minute = map(int, self._daily_report_time.split(':'))
                    target_time = now.replace(hour=hour, minute=minute, second=0, microsecond=0)
                    
                    if now >= target_time and self._last_report_date != today:
                        try:
                            end_time = int(now.timestamp())
                            start_time = int((now - timedelta(days=1)).timestamp())
                            
                            # 使用现有的 asyncio.run() 模式
                            report_content = asyncio.run(
                                self._activity_generator.generate_report(start_time, end_time)
                            )
                            self._last_report_date = today
                        except Exception as e:
                            logger.exception(f"Failed to generate daily report: {e}")
            except Exception as e:
                logger.error(f"Failed to check daily report generation time: {e}")
            
            # 等待30分钟,可被中断
            if self._stop_event.wait(60*30):
                break  # 收到停止信号
    
    self._stop_event = threading.Event()
    self._report_thread = threading.Thread(target=report_worker, daemon=True)
    self._report_thread.start()

benhack20 avatar Oct 15 '25 06:10 benhack20

下一个 timer 才会创建新线程,当前线程结束后会销毁。不过确实可以优化下

qin-ctx avatar Oct 15 '25 07:10 qin-ctx