暂停情报采集任务
This commit is contained in:
@@ -16,8 +16,12 @@ def run_scheduled_job(settings: Settings) -> None:
|
||||
|
||||
|
||||
def build_scheduler(settings: Settings) -> BackgroundScheduler:
|
||||
# APScheduler负责按固定间隔自动运行,避免服务重启时连续触发外部采集限流。
|
||||
# 调度器始终可供手动任务复用,自动采集关闭时不注册任何周期任务。
|
||||
scheduler = BackgroundScheduler(timezone=settings.agent_timezone)
|
||||
if not settings.agent_enabled:
|
||||
return scheduler
|
||||
|
||||
# APScheduler负责按固定间隔自动运行,避免服务重启时连续触发外部采集限流。
|
||||
scheduler.add_job(
|
||||
run_scheduled_job,
|
||||
trigger="interval",
|
||||
|
||||
+4
-1
@@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Literal, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -50,6 +50,9 @@ def trigger_daily_run(
|
||||
settings: Settings = Depends(get_settings),
|
||||
db: Session = Depends(get_db),
|
||||
) -> RunTriggerRead:
|
||||
# 暂停期间拒绝所有入口的采集请求,保证不会产生外部模型调用。
|
||||
if not settings.agent_enabled:
|
||||
raise HTTPException(status_code=503, detail="情报采集当前已暂停")
|
||||
# 手动搜索投递到调度器线程,避免HTTP请求承载长时间Grok搜索任务。
|
||||
running = db.scalar(
|
||||
select(AgentRun).where(AgentRun.status == "running").order_by(AgentRun.id.desc()).limit(1)
|
||||
|
||||
+3
-1
@@ -14,7 +14,7 @@ class Settings(BaseSettings):
|
||||
)
|
||||
llm_base_url: str = "https://api.zayuapi.com/v1"
|
||||
llm_api_key: str = ""
|
||||
llm_model: str = "grok-4.3"
|
||||
llm_model: str = "grok-4.5"
|
||||
llm_timeout_seconds: int = 180
|
||||
llm_max_tokens: int = 8000
|
||||
news_recent_days: int = 3
|
||||
@@ -24,6 +24,8 @@ class Settings(BaseSettings):
|
||||
github_min_stars: int = 20
|
||||
github_max_projects: int = 40
|
||||
agent_timezone: str = "Asia/Shanghai"
|
||||
# 采集开关统一控制定时任务和手动触发,暂停期默认不调用外部模型。
|
||||
agent_enabled: bool = False
|
||||
agent_interval_minutes: int = 30
|
||||
report_dir: Path = Path("reports")
|
||||
log_file: Path = Path("logs/app.log")
|
||||
|
||||
@@ -162,30 +162,6 @@ HOME_PAGE_HTML = """
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
border: 1px solid oklch(25% 0.02 210);
|
||||
border-radius: 8px;
|
||||
padding: 9px 13px;
|
||||
background: var(--ink);
|
||||
color: white;
|
||||
font: inherit;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
min-width: 96px;
|
||||
}
|
||||
|
||||
.action-button:disabled {
|
||||
cursor: wait;
|
||||
opacity: 0.66;
|
||||
}
|
||||
|
||||
.layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.2fr) minmax(340px, 0.8fr);
|
||||
@@ -434,9 +410,6 @@ HOME_PAGE_HTML = """
|
||||
<div class="pulse">
|
||||
<strong id="todayCountText">读取中</strong>
|
||||
<span id="todayCountDetail">正在整理新闻与项目。</span>
|
||||
<div class="actions">
|
||||
<button class="action-button" id="manualRunButton" type="button">手动搜索</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -511,7 +484,6 @@ HOME_PAGE_HTML = """
|
||||
const runCountFull = document.querySelector("#runCountFull");
|
||||
const todayCountText = document.querySelector("#todayCountText");
|
||||
const todayCountDetail = document.querySelector("#todayCountDetail");
|
||||
const manualRunButton = document.querySelector("#manualRunButton");
|
||||
|
||||
const stateText = {
|
||||
completed: "完成",
|
||||
@@ -695,34 +667,9 @@ HOME_PAGE_HTML = """
|
||||
renderRuns(data.runs || []);
|
||||
}
|
||||
|
||||
async function triggerManualRun() {
|
||||
manualRunButton.disabled = true;
|
||||
manualRunButton.textContent = "搜索中";
|
||||
try {
|
||||
const response = await fetch("/agent/runs/daily", {
|
||||
method: "POST",
|
||||
headers: { Accept: "application/json" }
|
||||
});
|
||||
if (!response.ok) throw new Error("手动搜索失败");
|
||||
await loadDashboard();
|
||||
} finally {
|
||||
window.setTimeout(() => {
|
||||
manualRunButton.disabled = false;
|
||||
manualRunButton.textContent = "手动搜索";
|
||||
loadDashboard().catch(() => {});
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
navButtons.forEach((button) => {
|
||||
button.addEventListener("click", () => activateView(button.dataset.viewTarget));
|
||||
});
|
||||
manualRunButton.addEventListener("click", () => {
|
||||
triggerManualRun().catch(() => {
|
||||
manualRunButton.disabled = false;
|
||||
manualRunButton.textContent = "手动搜索";
|
||||
});
|
||||
});
|
||||
|
||||
const initialView = window.location.hash.replace("#", "");
|
||||
if (["signals", "report", "runs"].includes(initialView)) {
|
||||
|
||||
Reference in New Issue
Block a user