Fix standup race condition: lock + daily guard + remove standup from TaskBeat whitelist

- _standup_lock: threading.Lock prevents concurrent standup runs
- DB check: if a standup task already exists for today, abort
- TaskBeat whitelist: remove 'standup' type so TaskBeat never re-runs standup tasks
  (standup is always driven by trigger_daily_standup(), not TaskBeat)
This commit is contained in:
eric 2026-02-21 20:28:22 +00:00
parent 8780c2b176
commit 0868a2c71f

35
app.py
View file

@ -2108,7 +2108,7 @@ def process_beat_tasks():
# Konvertiere zu Dict-Format für Legacy-Kompatibilität
pending_tasks = []
for db_task in db_tasks:
if db_task.get('type') in ('agent_created', 'manual', 'orchestrated', 'agent_delegated', 'telegram', 'agent_subtask', 'standup', 'broadcast'):
if db_task.get('type') in ('agent_created', 'manual', 'orchestrated', 'agent_delegated', 'telegram', 'agent_subtask', 'broadcast'):
pending_tasks.append(db_task)
for task in pending_tasks:
@ -2405,12 +2405,43 @@ def start_orchestrator_beat():
# ── DAILY STANDUP ─────────────────────────────────────────────────────────────
_standup_lock = threading.Lock()
def trigger_daily_standup():
"""
Tägliches Standup: Orchestrator fragt alle Team-Members nach Updates
und delegiert anschließend Wissensupdates an alle Agenten.
Gegen Doppel-Trigger gesichert: nur ein Standup pro Tag möglich.
"""
logger.info("[DailyStandup] Starte tägliches Standup...")
# Nur einen gleichzeitigen Standup erlauben
if not _standup_lock.acquire(blocking=False):
logger.warning("[DailyStandup] Bereits aktiv — zweiter Trigger ignoriert.")
return
try:
# Prüfe ob heute schon ein Standup läuft oder abgeschlossen ist
today_str = datetime.now().strftime('%Y-%m-%d')
try:
con = sqlite3.connect(EMAIL_JOURNAL_DB)
existing = con.execute(
"SELECT id FROM tasks WHERE type='standup' AND created_at LIKE ? AND status != 'error'",
(f"{today_str}%",)
).fetchone()
con.close()
except Exception:
existing = None
if existing:
logger.warning("[DailyStandup] Standup für heute (Task #%s) bereits vorhanden — abgebrochen.", existing['id'] if existing else '?')
return
logger.info("[DailyStandup] Starte tägliches Standup...")
_trigger_daily_standup_inner()
finally:
_standup_lock.release()
def _trigger_daily_standup_inner():
# Team-Members aus DB holen
try: