fix: reduce chess-results.com request volume by ~20-50x
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 5s
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 5s
- check_all_subscriptions: quick pre-check (1 req, art=4 only) before full fetch; full fetch only when results_count or current_round changed. Interval 60s → 300s. Saves ~10,000 req/day per active subscription. - rescan_existing_tournaments: filter to tournaments ended within last 30 days (or no end_date). Drops from ~2000 cached TNRs to ~30-100 active ones per run, saving ~22,000 req/day. - warmup: sleep 1s per TNR instead of 20ms per 500 — spreads initial full-scan over hours rather than minutes. - parser: extract _normalize_url helper, add fetch_tournament_quick(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
66b10d9425
commit
8058080c3a
3 changed files with 65 additions and 12 deletions
|
|
@ -734,7 +734,7 @@ def main():
|
|||
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_url))
|
||||
|
||||
app.job_queue.run_repeating(
|
||||
tracker.check_all_subscriptions, interval=60, first=10)
|
||||
tracker.check_all_subscriptions, interval=300, first=10)
|
||||
app.job_queue.run_repeating(
|
||||
tracker.rescan_new_tournaments, interval=3600, first=60)
|
||||
app.job_queue.run_repeating(
|
||||
|
|
|
|||
|
|
@ -768,21 +768,31 @@ def _warmup_cache_sync():
|
|||
if tnr % 100 == 0:
|
||||
set_tnr_state('warmup_tnr', str(tnr))
|
||||
if tnr % 500 == 0:
|
||||
elapsed = (start_tnr - tnr) // 500 * 500 # rough
|
||||
print(f'warmup: progress TNR {tnr} (started at {start_tnr})', file=sys.stderr)
|
||||
time.sleep(0.02)
|
||||
# Rate-limit: ~1 req/sec to stay within chess-results.com daily limit.
|
||||
# Cached TNRs return instantly (no HTTP), so this only applies to misses.
|
||||
time.sleep(1.0)
|
||||
|
||||
# Mark warmup as complete — next run will see this and skip
|
||||
set_tnr_state('warmup_tnr', 'done')
|
||||
|
||||
|
||||
async def rescan_existing_tournaments(context):
|
||||
"""Every 2h: refetch art=0 for all cached TNRs, detect new players."""
|
||||
"""Every 2h: refetch art=0 for recent/active cached TNRs, detect new players.
|
||||
|
||||
Only rescans tournaments that ended within the last 30 days (or have no
|
||||
end_date). Old completed tournaments never get new players, so skipping
|
||||
them keeps daily request volume within chess-results.com rate limits.
|
||||
"""
|
||||
import time
|
||||
from datetime import timedelta
|
||||
from bots.client_bot import _md_escape as _md_esc
|
||||
|
||||
cutoff = (date.today() - timedelta(days=30)).isoformat()
|
||||
conn = _get_conn()
|
||||
cached_tnrs = [r[0] for r in conn.execute('SELECT tnr FROM tnr_cache ORDER BY tnr DESC').fetchall()]
|
||||
cached_tnrs = [r[0] for r in conn.execute(
|
||||
'SELECT tnr FROM tnr_cache WHERE end_date = "" OR end_date >= ? ORDER BY tnr DESC',
|
||||
(cutoff,)).fetchall()]
|
||||
conn.close()
|
||||
if not cached_tnrs:
|
||||
return
|
||||
|
|
@ -840,7 +850,7 @@ async def rescan_existing_tournaments(context):
|
|||
|
||||
|
||||
async def check_all_subscriptions(context):
|
||||
from swiss_calc.parser import fetch_tournament
|
||||
from swiss_calc.parser import fetch_tournament, fetch_tournament_quick
|
||||
from swiss_calc.swiss import calculate_next_round
|
||||
from bots.client_bot import format_pairings, _render_chunks
|
||||
from telegram.constants import ParseMode
|
||||
|
|
@ -849,10 +859,22 @@ async def check_all_subscriptions(context):
|
|||
if not subs:
|
||||
return
|
||||
|
||||
today_str = date.today().isoformat()
|
||||
for sub in subs:
|
||||
if sub['tournament_url'] == 'fide_only':
|
||||
continue
|
||||
|
||||
# Quick check: 1 request — skip full fetch if nothing changed
|
||||
try:
|
||||
quick = fetch_tournament_quick(sub['tournament_url'])
|
||||
except Exception:
|
||||
continue
|
||||
quick_player = find_player(quick, sub['player_name'], sub['player_sno'])
|
||||
quick_results = len(quick_player.get('results', [])) if quick_player else 0
|
||||
quick_rd = quick.get('current_round', 0)
|
||||
if quick_results <= sub['last_results_count'] and quick_rd <= sub['last_round_done']:
|
||||
continue
|
||||
|
||||
# Something changed — do full fetch for accurate data and pairing calc
|
||||
try:
|
||||
tournament = fetch_tournament(sub['tournament_url'])
|
||||
except Exception:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue