fix(锁与查询组): #12 熔断器状态转换加锁;#10 问答人名匹配改 JSON_CONTAINS 精确匹配(防 LIKE 子串/特殊字符误匹配);#4 OracleDB 复合写加锁;#6 每消费者独立 VideoProcessor(消除 adapter.timeout 共享竞争);#15 done 视频文件被覆盖(mtime>processed_at)自动重置重分析

This commit is contained in:
ericwyuan
2026-08-21 14:24:12 +08:00
parent 034dca92b2
commit 4e85a98944
4 changed files with 68 additions and 34 deletions

View File

@@ -17,6 +17,7 @@ Oracle 本地库SQLite - 视频摘要 / 事件 / 人物 存储
import os
import json
import sqlite3
import threading
from datetime import datetime, timezone, timedelta
from typing import Dict, List, Optional
@@ -35,6 +36,7 @@ class OracleDB:
self._conn.row_factory = sqlite3.Row
self._conn.execute("PRAGMA journal_mode=WAL")
self._conn.execute("PRAGMA busy_timeout=10000")
self._write_lock = threading.Lock() # 复合写(如 DELETE+INSERT+commit串行化
self._init_schema()
# ------------------------------------------------------------------
@@ -182,25 +184,26 @@ class OracleDB:
def mark_video_processed(self, video_id: int, summary: str, events: List[dict],
people: List[str], compute_provider: str) -> List[int]:
"""落库视频结果;返回新插入事件的 id 列表(与 events 参数一一对应,供事件截图用)"""
now = _now_iso()
self._conn.execute(
"UPDATE videos SET status='done', summary_json=?, events_json=?, "
"people_json=?, compute_provider=?, updated_at=?, processed_at=? WHERE id=?",
(summary, json.dumps(events, ensure_ascii=False), json.dumps(people, ensure_ascii=False),
compute_provider, now, now, video_id))
# 事件落独立表,便于 NAS 拉取
self._conn.execute("DELETE FROM events WHERE video_id=?", (video_id,))
event_ids: List[int] = []
for ev in events:
cur = self._conn.execute(
"INSERT INTO events (video_id, ts, description, person_list_json, "
"is_attention_event) VALUES (?,?,?,?,?)",
(video_id, ev.get('timestamp', ''), ev.get('description', ''),
json.dumps(ev.get('people', []), ensure_ascii=False),
1 if ev.get('is_attention_event') else 0))
event_ids.append(cur.lastrowid)
self._conn.commit()
return event_ids
with self._write_lock:
now = _now_iso()
self._conn.execute(
"UPDATE videos SET status='done', summary_json=?, events_json=?, "
"people_json=?, compute_provider=?, updated_at=?, processed_at=? WHERE id=?",
(summary, json.dumps(events, ensure_ascii=False), json.dumps(people, ensure_ascii=False),
compute_provider, now, now, video_id))
# 事件落独立表,便于 NAS 拉取
self._conn.execute("DELETE FROM events WHERE video_id=?", (video_id,))
event_ids: List[int] = []
for ev in events:
cur = self._conn.execute(
"INSERT INTO events (video_id, ts, description, person_list_json, "
"is_attention_event) VALUES (?,?,?,?,?)",
(video_id, ev.get('timestamp', ''), ev.get('description', ''),
json.dumps(ev.get('people', []), ensure_ascii=False),
1 if ev.get('is_attention_event') else 0))
event_ids.append(cur.lastrowid)
self._conn.commit()
return event_ids
def mark_video_failed(self, video_id: int, error: str = ''):
now = _now_iso()