mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-10 09:06:36 +00:00
revert(vegas): gate only the prefetch thread; gating ESPN fetches measured worse
84043468 also gated the ESPN chunk fetches and the background data
service's workers, for the hourly sports refresh. A burst test on hdpi
(baseball and football refreshing every 5 minutes, 10-minute soaks, G F F G):
G prefetch gated only 0.87%, 0.83% late; 6+ late 20, 16; fetches 0.3-1.8s
F + fetch threads gated 1.23%, 1.05% late; 6+ late 12, 16; fetches 1.6-4.6s
Every parked fetch thread wakes at each swap and has to take the GIL again
just to park at the end of the window, so twenty of them cost more than
they saved, and the fetches ran two to three times as long. The plugins'
own copies of espn_dates (half the burst) were never gated anyway.
espn_dates and the background data service go back to main's versions and
the module-level active gate goes. Kept from that commit: the render thread
is never gated, a live refresh from another thread can't take its place,
and nested blocks keep the outer boundary.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -299,60 +299,6 @@ class TestWhoIsGated:
|
||||
assert kept and final is None
|
||||
|
||||
|
||||
class TestActiveGate:
|
||||
@pytest.fixture(autouse=True)
|
||||
def no_gate_left_behind(self):
|
||||
yield
|
||||
render_gate.set_active(None)
|
||||
|
||||
def test_without_a_vegas_run_nothing_is_gated(self):
|
||||
render_gate.set_active(None)
|
||||
with render_gate.yielding():
|
||||
assert sys.getprofile() is None
|
||||
|
||||
def test_with_one_background_work_gives_way(self):
|
||||
gate = RenderGate()
|
||||
render_gate.set_active(gate)
|
||||
with render_gate.yielding():
|
||||
assert sys.getprofile() == gate._hook
|
||||
assert sys.getprofile() is None
|
||||
|
||||
def test_espn_chunk_fetches_give_way(self):
|
||||
from src.common import espn_dates
|
||||
gate = RenderGate()
|
||||
render_gate.set_active(gate)
|
||||
seen = []
|
||||
|
||||
class Response:
|
||||
content = b'{"events": []}'
|
||||
|
||||
def raise_for_status(self):
|
||||
pass
|
||||
|
||||
def json(self):
|
||||
return {"events": []}
|
||||
|
||||
class Session:
|
||||
def get(self, *args, **kwargs):
|
||||
seen.append(sys.getprofile() == gate._hook)
|
||||
return Response()
|
||||
assert espn_dates._fetch_one_chunk(
|
||||
Session(), "http://x", {}, {}, 5, None, "20260924") == {"events": []}
|
||||
assert seen == [True]
|
||||
|
||||
def test_background_data_fetches_give_way(self):
|
||||
from src.background_data_service import BackgroundDataService
|
||||
gate = RenderGate()
|
||||
render_gate.set_active(gate)
|
||||
service = BackgroundDataService.__new__(BackgroundDataService)
|
||||
service._shutdown = True # never started: nothing for __del__ to stop
|
||||
seen = []
|
||||
service._fetch_data = lambda request: seen.append(
|
||||
sys.getprofile() == gate._hook) or "result"
|
||||
assert service._fetch_data_worker(object()) == "result"
|
||||
assert seen == [True]
|
||||
|
||||
|
||||
class TestDisplayManager:
|
||||
@pytest.fixture
|
||||
def dm(self):
|
||||
@@ -443,10 +389,8 @@ class TestVegasWiring:
|
||||
assert c._state_lock in gate._guarded
|
||||
assert c.stream_manager._buffer_lock in gate._guarded
|
||||
assert c.plugin_adapter._cache_lock in gate._guarded
|
||||
assert render_gate.active() is gate # background fetches use it too
|
||||
c._remove_render_gate()
|
||||
assert c.display_manager.render_gate is None
|
||||
assert render_gate.active() is None
|
||||
|
||||
@pytest.mark.parametrize("releases", [False, None])
|
||||
def test_ignored_without_a_binding_that_releases_the_gil(self, monkeypatch, releases):
|
||||
|
||||
Reference in New Issue
Block a user