fix for buildinds

This commit is contained in:
2026-04-29 22:05:57 +03:00
parent d952e7ca56
commit 1db8d744c8
4 changed files with 71 additions and 10 deletions

View File

@@ -105,10 +105,11 @@ def receive_state():
# so both queues are served in parallel without blocking each other.
# ------------------------------------------------------------------
def _fetch_pending_of_type(c, cmd_type, player_id):
"""Fetch a single oldest pending command of a given type (recruit, market, etc.)."""
row = c.execute('''
SELECT * FROM commands
WHERE status = 'pending' AND type = ? AND player_id = ?
ORDER BY id ASC
ORDER BY updated_at ASC, id ASC
LIMIT 1
''', (cmd_type, player_id)).fetchone()
if not row:
@@ -125,6 +126,49 @@ def _fetch_pending_of_type(c, cmd_type, player_id):
'payload': json.loads(row['payload'])
}
def _fetch_pending_builds_all_towns(c, player_id):
"""
Fetch ONE pending 'build' command per distinct town_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.
"""
# 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('''
SELECT town_id
FROM commands
WHERE status = 'pending' AND type = 'build' AND player_id = ?
GROUP BY town_id
ORDER BY MIN(updated_at) ASC
''', (player_id,)).fetchall()
results = []
now = datetime.utcnow().isoformat()
for town_row in town_rows:
town_id = town_row['town_id']
row = c.execute('''
SELECT * FROM commands
WHERE status = 'pending' AND type = 'build'
AND player_id = ? AND town_id = ?
ORDER BY updated_at ASC, id ASC
LIMIT 1
''', (player_id, town_id)).fetchone()
if not row:
continue
c.execute('''
UPDATE commands SET status = 'executing', updated_at = ?
WHERE id = ?
''', (now, row['id']))
results.append({
'id': row['id'],
'town_id': row['town_id'],
'type': row['type'],
'payload': json.loads(row['payload'])
})
return results
@api.route('/api/commands/pending', methods=['GET'])
def get_pending_command():
player_id = request.args.get('player_id')
@@ -134,7 +178,7 @@ def get_pending_command():
conn = get_db()
c = conn.cursor()
build_cmd = _fetch_pending_of_type(c, 'build', player_id)
build_cmds = _fetch_pending_builds_all_towns(c, player_id) # one per town
recruit_cmd = _fetch_pending_of_type(c, 'recruit', player_id)
market_cmd = _fetch_pending_of_type(c, 'market_offer', player_id)
farm_cmd = _fetch_pending_of_type(c, 'farm_loot', player_id)
@@ -164,7 +208,7 @@ def get_pending_command():
conn.close()
return jsonify({
'build': build_cmd,
'builds': build_cmds, # list: one build command per town
'recruit': recruit_cmd,
'market': market_cmd,
'research': research_cmd,