diff --git a/routes/api.py b/routes/api.py index 11ce1a3..ee6fdb8 100644 --- a/routes/api.py +++ b/routes/api.py @@ -133,7 +133,18 @@ def _fetch_pending_builds_all_towns(c, player_id): This allows all towns to build in parallel within a single poll cycle. Within each town the oldest-updated command is picked first, so requeued commands (updated_at = now) naturally sort behind fresh ones. + + Towns that already have a command in 'executing' state are skipped — + this prevents a second build from being dispatched before the first one + has reported its result (which was causing commands to pile up in EXECUTING). """ + # Towns that currently have a build already in-flight — don't touch those. + executing_rows = c.execute(''' + SELECT DISTINCT town_id FROM commands + WHERE status = 'executing' AND type = 'build' AND player_id = ? + ''', (player_id,)).fetchall() + busy_towns = {r['town_id'] for r in executing_rows} + # Get every town that has at least one pending build, ordered by # which town has been waiting longest (MIN updated_at across its commands). town_rows = c.execute(''' @@ -148,6 +159,11 @@ def _fetch_pending_builds_all_towns(c, player_id): now = datetime.utcnow().isoformat() for town_row in town_rows: town_id = town_row['town_id'] + + # Skip this town if a build is already executing for it + if town_id in busy_towns: + continue + row = c.execute(''' SELECT * FROM commands WHERE status = 'pending' AND type = 'build'