fix: stop burning request limit on finished tournaments + reset stale result counts
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 4s

check_all_subscriptions: always call update_round even for the final round.
Previously, last_round_done was never updated past the second-to-last round
(because pairings aren't calculated for the last round). This kept
quick_rd > last_round_done forever on finished tournaments, triggering a full
fetch (~22 HTTP requests) every 5 minutes — causing 26k+ daily requests to
chess-results.com against a 2000-request daily limit.

rescan_existing_tournaments: when correcting player_sno, also reset
last_results_count to 0. Stale counts from a wrong player (from the FIDE ID
parsing bug) could be higher than the real player's count, permanently
suppressing result notifications for the correct player.

DB patched directly: last_results_count reset to 0 for subs 40 (Vrubel)
and 47 (Aslanbekov) so they re-learn correct scores on next fetch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
vrubel 2026-06-22 15:19:39 +00:00
parent e64e436b6f
commit 77c8a87e16

View file

@ -825,7 +825,10 @@ async def rescan_existing_tournaments(context):
continue # tournament deleted or unreachable
new_fids = set(new_data['players'].keys())
# Correct player_sno for subscriptions whose SNo drifted from the cache
# Correct player_sno for subscriptions whose SNo drifted from the cache.
# Also reset last_results_count so the bot re-learns points for the
# correct player (stale counts from the old wrong player could be higher
# than the real player's count, suppressing result notifications forever).
tnr_url_frag = f'tnr{tnr}.aspx'
for fid in new_fids:
if fid not in fide_to_users:
@ -833,7 +836,7 @@ async def rescan_existing_tournaments(context):
correct_sno = new_data['players'][fid]['sno']
conn = _get_conn()
conn.execute(
'UPDATE subscriptions SET player_sno = ? '
'UPDATE subscriptions SET player_sno = ?, last_results_count = 0 '
'WHERE fide_id = ? AND tournament_url LIKE ? '
'AND player_sno != ? AND active = 1',
(correct_sno, fid, f'%{tnr_url_frag}%', correct_sno))
@ -922,24 +925,29 @@ async def check_all_subscriptions(context):
pass
update_result(sub['id'], results_count, points)
# Round fully completed → calculate next round pairings
# Round fully completed → calculate next round pairings (if not the last round)
current_rd = tournament.get('current_round', 0)
if current_rd > sub['last_round_done'] and current_rd < tournament.get('num_rounds', 0):
try:
result = calculate_next_round(tournament)
fmt = format_pairings(result, tournament.get('name', ''), sub['lang'],
sub['player_name'], sub['player_sno'])
chunks = _render_chunks(fmt)
for chunk in chunks:
try:
await context.bot.send_message(
sub['user_id'], chunk,
parse_mode=ParseMode.MARKDOWN_V2,
disable_web_page_preview=True)
except Exception:
break
except Exception:
pass
if current_rd > sub['last_round_done']:
if current_rd < tournament.get('num_rounds', 0):
try:
result = calculate_next_round(tournament)
fmt = format_pairings(result, tournament.get('name', ''), sub['lang'],
sub['player_name'], sub['player_sno'])
chunks = _render_chunks(fmt)
for chunk in chunks:
try:
await context.bot.send_message(
sub['user_id'], chunk,
parse_mode=ParseMode.MARKDOWN_V2,
disable_web_page_preview=True)
except Exception:
break
except Exception:
pass
# Always advance last_round_done — even for the final round.
# Without this, the quick-check condition (quick_rd > last_round_done)
# stays True forever on finished tournaments, causing a full fetch
# (~22 HTTP requests) every 5 minutes.
update_round(sub['id'], current_rd)