Fix task status stuck at 'running': use new DB session in thread, add frontend auto-polling

This commit is contained in:
Yuzhiran Dev
2026-05-18 22:37:59 +08:00
parent 33766a396d
commit f427aea1b3
2 changed files with 37 additions and 17 deletions
+25 -16
View File
@@ -227,25 +227,34 @@ def run_creator_task(
from ..core.generator import run_creator from ..core.generator import run_creator
def _run(): def _run():
from ..database import SessionLocal
from datetime import datetime, timezone
new_db = SessionLocal()
try: try:
result = run_creator(topic_id) result = run_creator(topic_id)
finished = datetime.now(timezone.utc) new_task = new_db.query(ContentTask).filter(ContentTask.task_id == task_id).first()
task.status = "completed" if new_task:
task.finished_at = finished finished = datetime.now(timezone.utc)
task.progress = 100 new_task.status = "completed"
task.message = "创作完成" new_task.finished_at = finished
task.result_data = result or {} new_task.progress = 100
if task.started_at: new_task.message = "创作完成"
task.duration = int((finished - task.started_at).total_seconds()) new_task.result_data = result or {}
db.commit() if new_task.started_at:
new_task.duration = int((finished - new_task.started_at).total_seconds())
new_db.commit()
except Exception as e: except Exception as e:
finished = datetime.now(timezone.utc) new_task = new_db.query(ContentTask).filter(ContentTask.task_id == task_id).first()
task.status = "failed" if new_task:
task.finished_at = finished finished = datetime.now(timezone.utc)
task.error_msg = str(e) new_task.status = "failed"
if task.started_at: new_task.finished_at = finished
task.duration = int((finished - task.started_at).total_seconds()) new_task.error_msg = str(e)
db.commit() if new_task.started_at:
new_task.duration = int((finished - new_task.started_at).total_seconds())
new_db.commit()
finally:
new_db.close()
thread = threading.Thread(target=_run) thread = threading.Thread(target=_run)
thread.start() thread.start()
+12 -1
View File
@@ -187,6 +187,7 @@ const TasksApp = {
showDetailDialog: false, detailTask: null, showDetailDialog: false, detailTask: null,
schedulerJobs: [], schedulerLoading: false, schedulerJobs: [], schedulerLoading: false,
totalTasks: 0, currentPage: 1, pageSize: 20, totalTasks: 0, currentPage: 1, pageSize: 20,
pollTimer: null,
SCHEDULER_JOBS, SCHEDULER_JOBS,
} }
}, },
@@ -236,6 +237,13 @@ const TasksApp = {
if (!dateStr) return '-'; if (!dateStr) return '-';
try { return new Date(dateStr).toLocaleString('zh-CN'); } catch (e) { return dateStr; } try { return new Date(dateStr).toLocaleString('zh-CN'); } catch (e) { return dateStr; }
}, },
startPolling() {
this.stopPolling();
this.pollTimer = setInterval(() => this.loadTasks(), 5000);
},
stopPolling() {
if (this.pollTimer) { clearInterval(this.pollTimer); this.pollTimer = null; }
},
async loadTasks() { async loadTasks() {
this.loading = true; this.loading = true;
try { try {
@@ -244,6 +252,8 @@ const TasksApp = {
const data = await this.api(url) || []; const data = await this.api(url) || [];
this.tasks = data; this.tasks = data;
this.totalTasks = data.length < this.pageSize ? (this.currentPage - 1) * this.pageSize + data.length : this.currentPage * this.pageSize + 1; this.totalTasks = data.length < this.pageSize ? (this.currentPage - 1) * this.pageSize + data.length : this.currentPage * this.pageSize + 1;
const hasRunning = data.some(t => t.status === 'running');
if (hasRunning) { this.startPolling(); } else { this.stopPolling(); }
} catch (e) { console.error(e); this.$message.error('加载任务列表失败: ' + e.message); } } catch (e) { console.error(e); this.$message.error('加载任务列表失败: ' + e.message); }
finally { this.loading = false; } finally { this.loading = false; }
}, },
@@ -265,7 +275,8 @@ const TasksApp = {
} catch (e) { this.$message.error('重试失败: ' + e.message); } } catch (e) { this.$message.error('重试失败: ' + e.message); }
} }
}, },
mounted() { this.checkAuth(); } mounted() { this.checkAuth(); },
beforeUnmount() { this.stopPolling(); }
}; };
const app = Vue.createApp(TasksApp); const app = Vue.createApp(TasksApp);
app.use(ElementPlus); app.use(ElementPlus);