fix for buildinds
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user