fix(orchestrator): Auto-Refresh nicht direkt nach Cancel/Error neu einreihen
Der Auto-Refresh-Scheduler hat seinen letzten relevanten refresh_log-Eintrag bisher mit Filter status IN (completed, running) gesucht. Cancelled- und Error-Laeufe wurden ignoriert, der davor liegende Completed wurde genommen. Ergebnis: Direkt nach Cancel oder Error wurde der Slot als faellig gesehen und nach 60 Sekunden wieder eingereiht (Endlos-Loop bei Iran-Konflikt heute, 4x error in Folge ohne Pause). - main.py: Filter erweitert auf status IN (completed, running, cancelled, error) - orchestrator.py: Queue-Cancels schreiben jetzt auch einen cancelled-Eintrag ins refresh_log via _log_queued_cancellation (vorher: stiller Discard, kein Fingerabdruck im Log -> Auto-Refresh erkannte den Cancel nie) Wirkung: Nach Cancel oder Error startet die Lage erst beim naechsten regulaeren Slot wieder. refresh_mode bleibt unveraendert.
Dieser Commit ist enthalten in:
@@ -489,6 +489,9 @@ class AgentOrchestrator:
|
|||||||
|
|
||||||
logger.info(f"Lage {incident_id} aus Warteschlange entfernt (removed={removed})")
|
logger.info(f"Lage {incident_id} aus Warteschlange entfernt (removed={removed})")
|
||||||
|
|
||||||
|
# refresh_log-Eintrag schreiben, damit Auto-Refresh nicht im naechsten Tick erneut einreiht
|
||||||
|
await self._log_queued_cancellation(incident_id)
|
||||||
|
|
||||||
# Send cancelled event
|
# Send cancelled event
|
||||||
if self._ws_manager:
|
if self._ws_manager:
|
||||||
try:
|
try:
|
||||||
@@ -639,6 +642,28 @@ class AgentOrchestrator:
|
|||||||
finally:
|
finally:
|
||||||
await db.close()
|
await db.close()
|
||||||
|
|
||||||
|
async def _log_queued_cancellation(self, incident_id: int):
|
||||||
|
"""Schreibt einen cancelled-Eintrag fuer einen Queue-Abbruch (Lage war noch nicht laufend).
|
||||||
|
Verhindert, dass der Auto-Refresh-Scheduler im naechsten Tick sofort wieder einreiht."""
|
||||||
|
from database import get_db
|
||||||
|
db = await get_db()
|
||||||
|
try:
|
||||||
|
cur = await db.execute("SELECT tenant_id FROM incidents WHERE id = ?", (incident_id,))
|
||||||
|
row = await cur.fetchone()
|
||||||
|
tid = row["tenant_id"] if row else None
|
||||||
|
now_str = datetime.now(TIMEZONE).strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
await db.execute(
|
||||||
|
"""INSERT INTO refresh_log (incident_id, started_at, completed_at, status,
|
||||||
|
trigger_type, error_message, tenant_id)
|
||||||
|
VALUES (?, ?, ?, 'cancelled', 'manual', 'Aus Warteschlange entfernt', ?)""",
|
||||||
|
(incident_id, now_str, now_str, tid),
|
||||||
|
)
|
||||||
|
await db.commit()
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Konnte Queue-Cancel nicht in refresh_log loggen: {e}")
|
||||||
|
finally:
|
||||||
|
await db.close()
|
||||||
|
|
||||||
async def _mark_refresh_failed(self, incident_id: int, error: str):
|
async def _mark_refresh_failed(self, incident_id: int, error: str):
|
||||||
"""Markiert den laufenden Refresh-Log-Eintrag als error."""
|
"""Markiert den laufenden Refresh-Log-Eintrag als error."""
|
||||||
from database import get_db
|
from database import get_db
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ async def check_auto_refresh():
|
|||||||
|
|
||||||
# Letzten abgeschlossenen oder laufenden Refresh pruefen
|
# Letzten abgeschlossenen oder laufenden Refresh pruefen
|
||||||
cursor = await db.execute(
|
cursor = await db.execute(
|
||||||
"SELECT started_at, status FROM refresh_log WHERE incident_id = ? AND status IN ('completed', 'running') ORDER BY id DESC LIMIT 1",
|
"SELECT started_at, status FROM refresh_log WHERE incident_id = ? AND status IN ('completed', 'running', 'cancelled', 'error') ORDER BY id DESC LIMIT 1",
|
||||||
(incident_id,),
|
(incident_id,),
|
||||||
)
|
)
|
||||||
last_refresh = await cursor.fetchone()
|
last_refresh = await cursor.fetchone()
|
||||||
|
|||||||
In neuem Issue referenzieren
Einen Benutzer sperren