mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-08-11 21:58:05 +00:00
fix(odds): stop a stalled ESPN taking the whole plugin update with it
Odds are fetched per live game from inside SportsLive.update(), with
show_odds defaulting on, and the plugin executor kills an operation at
30s. The odds request timeout was also 30s, so a single stalled request
consumed the entire budget and the update carrying every game's score
was killed.
Out of season that is invisible: preseason week 1 returns one game. A
Sunday slate is around sixteen, so the odds of at least one slow request
rise sharply just as the cost of losing the update does.
Shorten the request timeout to 5s, and after a network failure skip the
network for 60s. The timeout alone is not enough -- sixteen consecutive
5s timeouts still blow through -- and when ESPN is unreachable it is
unreachable for the whole slate, so the first failure already answers
the question for the rest of the pass.
before: one stalled request = 30s = the entire budget
after : 5s, the rest of the slate skipped, retry after 60s
The stale-cache fallback is unchanged: the cache is consulted before any
of this, and the failing request still falls back to it.
An earlier version of this branch also jittered the cache TTL to stagger
expiry across a slate. That has been dropped: CacheManager.set() stores
ttl for compatibility but the read path expires entries by a per-type
max_age (1800s for odds), so the jitter was inert. Making the read path
honour a per-entry ttl is a real fix but changes a contract 48 plugin
call sites already rely on, which is not a change to make two weeks
before the season.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Udr6MfaFLUPhX5Fgo67Jf5
This commit is contained in:
co-authored by
Claude Opus 5
parent
ca26c1b83b
commit
ecf9195c11
@@ -87,7 +87,11 @@ class TestGetOdds:
|
||||
assert '/events/401/competitions/401/odds' in url
|
||||
assert url == ('https://sports.core.api.espn.com/v2/sports/football/'
|
||||
'leagues/nfl/events/401/competitions/401/odds')
|
||||
assert mock_get.call_args.kwargs['timeout'] == 30
|
||||
# The number matters less than the property: a single stalled request
|
||||
# must not be able to consume the plugin executor's 30s operation
|
||||
# budget, since odds are fetched per live game inside update().
|
||||
assert mock_get.call_args.kwargs['timeout'] == 5
|
||||
assert mock_get.call_args.kwargs['timeout'] < 30
|
||||
|
||||
def test_ncaa_fb_maps_to_college_football(self, manager, mock_get):
|
||||
manager.get_odds('football', 'ncaa_fb', '401')
|
||||
@@ -355,5 +359,5 @@ class TestLoadConfiguration:
|
||||
manager = BaseOddsManager(cache_manager, config_manager=config_manager)
|
||||
|
||||
assert manager.update_interval == 3600
|
||||
assert manager.request_timeout == 30
|
||||
assert manager.request_timeout == 5
|
||||
assert manager.cache_ttl == 1800
|
||||
|
||||
Reference in New Issue
Block a user