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:
parent
8780c2b176
commit
0868a2c71f
1 changed files with 33 additions and 2 deletions
35
app.py
35
app.py
|
|
@ -2108,7 +2108,7 @@ def process_beat_tasks():
|
||||||
# Konvertiere zu Dict-Format für Legacy-Kompatibilität
|
# Konvertiere zu Dict-Format für Legacy-Kompatibilität
|
||||||
pending_tasks = []
|
pending_tasks = []
|
||||||
for db_task in db_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)
|
pending_tasks.append(db_task)
|
||||||
|
|
||||||
for task in pending_tasks:
|
for task in pending_tasks:
|
||||||
|
|
@ -2405,12 +2405,43 @@ def start_orchestrator_beat():
|
||||||
|
|
||||||
# ── DAILY STANDUP ─────────────────────────────────────────────────────────────
|
# ── DAILY STANDUP ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
_standup_lock = threading.Lock()
|
||||||
|
|
||||||
def trigger_daily_standup():
|
def trigger_daily_standup():
|
||||||
"""
|
"""
|
||||||
Tägliches Standup: Orchestrator fragt alle Team-Members nach Updates
|
Tägliches Standup: Orchestrator fragt alle Team-Members nach Updates
|
||||||
und delegiert anschließend Wissensupdates an alle Agenten.
|
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
|
# Team-Members aus DB holen
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue