refactor(l4d2-web): drop refresh_global_overlays from scheduler
GLOBAL_OPERATIONS becomes {"install", "refresh_workshop_items"}.
Removes refresh_global_overlays_running from SchedulerState and the
_run_refresh_global_overlays dispatch. Drops dead test cases and pins
GLOBAL_OPERATIONS contents.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9f476e3456
commit
879c54cbda
4 changed files with 28 additions and 82 deletions
|
|
@ -27,7 +27,7 @@ TERMINAL_JOB_STATES = {"succeeded", "failed", "cancelled"}
|
|||
ACTIVE_JOB_STATES = {"running", "cancelling"}
|
||||
SERVER_OPERATIONS = {"initialize", "start", "stop", "delete"}
|
||||
OVERLAY_OPERATIONS = {"build_overlay"}
|
||||
GLOBAL_OPERATIONS = {"install", "refresh_workshop_items", "refresh_global_overlays"}
|
||||
GLOBAL_OPERATIONS = {"install", "refresh_workshop_items"}
|
||||
WORKSHOP_REFRESH_DOWNLOAD_WORKERS = 1
|
||||
|
||||
_claim_lock = threading.Lock()
|
||||
|
|
@ -40,7 +40,6 @@ _workers_started = False
|
|||
class SchedulerState:
|
||||
install_running: bool = False
|
||||
refresh_running: bool = False
|
||||
refresh_global_overlays_running: bool = False
|
||||
running_servers: set[int] = field(default_factory=set)
|
||||
running_overlays: set[int] = field(default_factory=set)
|
||||
blocked_servers_by_overlay: set[int] = field(default_factory=set)
|
||||
|
|
@ -63,7 +62,6 @@ def can_start(job, state: SchedulerState) -> bool:
|
|||
return (
|
||||
not state.install_running
|
||||
and not state.refresh_running
|
||||
and not state.refresh_global_overlays_running
|
||||
and len(state.running_servers) == 0
|
||||
and len(state.running_overlays) == 0
|
||||
)
|
||||
|
|
@ -71,26 +69,17 @@ def can_start(job, state: SchedulerState) -> bool:
|
|||
return (
|
||||
not state.install_running
|
||||
and not state.refresh_running
|
||||
and not state.refresh_global_overlays_running
|
||||
and len(state.running_servers) == 0
|
||||
and len(state.running_overlays) == 0
|
||||
)
|
||||
if job.operation == "refresh_global_overlays":
|
||||
return (
|
||||
not state.install_running
|
||||
and not state.refresh_running
|
||||
and not state.refresh_global_overlays_running
|
||||
and len(state.running_servers) == 0
|
||||
and len(state.running_overlays) == 0
|
||||
)
|
||||
if job.operation == "build_overlay":
|
||||
if state.install_running or state.refresh_running or state.refresh_global_overlays_running:
|
||||
if state.install_running or state.refresh_running:
|
||||
return False
|
||||
if job.overlay_id is None:
|
||||
return False
|
||||
return job.overlay_id not in state.running_overlays
|
||||
# Server operations from here on.
|
||||
if state.install_running or state.refresh_running or state.refresh_global_overlays_running:
|
||||
if state.install_running or state.refresh_running:
|
||||
return False
|
||||
if job.server_id is None:
|
||||
return False
|
||||
|
|
@ -109,8 +98,6 @@ def build_scheduler_state(session: Session) -> SchedulerState:
|
|||
state.install_running = True
|
||||
elif job.operation == "refresh_workshop_items":
|
||||
state.refresh_running = True
|
||||
elif job.operation == "refresh_global_overlays":
|
||||
state.refresh_global_overlays_running = True
|
||||
elif job.operation == "build_overlay" and job.overlay_id is not None:
|
||||
state.running_overlays.add(job.overlay_id)
|
||||
elif job.server_id is not None:
|
||||
|
|
@ -260,15 +247,6 @@ def run_job(job_id: int) -> None:
|
|||
on_stderr=on_stderr,
|
||||
should_cancel=should_cancel,
|
||||
)
|
||||
elif operation == "refresh_global_overlays":
|
||||
_run_with_boundaries(
|
||||
"refresh",
|
||||
"global overlays",
|
||||
_run_refresh_global_overlays,
|
||||
on_stdout=on_stdout,
|
||||
on_stderr=on_stderr,
|
||||
should_cancel=should_cancel,
|
||||
)
|
||||
elif operation == "build_overlay":
|
||||
if overlay_id_for_job is None:
|
||||
raise ValueError("build_overlay job has no overlay_id")
|
||||
|
|
@ -390,21 +368,6 @@ def _run_build_overlay(
|
|||
)
|
||||
|
||||
|
||||
def _run_refresh_global_overlays(
|
||||
*,
|
||||
on_stdout: Callable[[str], None],
|
||||
on_stderr: Callable[[str], None],
|
||||
should_cancel: Callable[[], bool],
|
||||
) -> list[str]:
|
||||
from l4d2web.services.global_overlay_refresh import refresh_global_overlays
|
||||
|
||||
return refresh_global_overlays(
|
||||
on_stdout=on_stdout,
|
||||
on_stderr=on_stderr,
|
||||
should_cancel=should_cancel,
|
||||
)
|
||||
|
||||
|
||||
def _run_refresh_workshop_items(
|
||||
*,
|
||||
on_stdout: Callable[[str], None],
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ def test_system_job_logs_persist(tmp_path, monkeypatch):
|
|||
job = Job(
|
||||
user_id=None,
|
||||
server_id=None,
|
||||
operation="refresh_global_overlays",
|
||||
operation="refresh_workshop_items",
|
||||
state="queued",
|
||||
)
|
||||
db.add(job)
|
||||
|
|
|
|||
|
|
@ -752,46 +752,29 @@ def test_refresh_job_enqueues_build_overlay_without_locking_its_final_log(
|
|||
assert "enqueued build_overlay for 1 overlay(s)" in lines
|
||||
|
||||
|
||||
def test_refresh_global_overlays_blocks_install_build_refresh_and_servers() -> None:
|
||||
from l4d2web.services.job_worker import SchedulerState, can_start
|
||||
def test_global_operations_set() -> None:
|
||||
from l4d2web.services.job_worker import GLOBAL_OPERATIONS
|
||||
|
||||
state = SchedulerState(refresh_global_overlays_running=True)
|
||||
assert can_start(DummyJob(operation="install"), state) is False
|
||||
assert can_start(DummyJob(operation="refresh_workshop_items"), state) is False
|
||||
assert can_start(DummyJob(operation="build_overlay", overlay_id=1), state) is False
|
||||
assert can_start(DummyJob(operation="start", server_id=1), state) is False
|
||||
assert GLOBAL_OPERATIONS == {"install", "refresh_workshop_items"}
|
||||
|
||||
|
||||
def test_refresh_global_overlays_waits_for_active_work() -> None:
|
||||
from l4d2web.services.job_worker import SchedulerState, can_start
|
||||
def test_build_overlay_script_type_blocks_per_overlay(overlay_seeded_worker) -> None:
|
||||
"""Mechanically identical to workshop builds, but pinned for script type."""
|
||||
app, ids = overlay_seeded_worker
|
||||
with session_scope() as s:
|
||||
overlay = s.query(Overlay).filter_by(id=ids.overlay).one()
|
||||
overlay.type = "script"
|
||||
overlay.script = "echo hi"
|
||||
|
||||
add_job(ids.user, "build_overlay", server_id=None, state="running", overlay_id=ids.overlay)
|
||||
|
||||
assert can_start(DummyJob(operation="refresh_global_overlays"), SchedulerState(install_running=True)) is False
|
||||
assert can_start(DummyJob(operation="refresh_global_overlays"), SchedulerState(refresh_running=True)) is False
|
||||
state = SchedulerState()
|
||||
state.running_overlays.add(1)
|
||||
assert can_start(DummyJob(operation="refresh_global_overlays"), state) is False
|
||||
state = SchedulerState()
|
||||
state.running_servers.add(1)
|
||||
assert can_start(DummyJob(operation="refresh_global_overlays"), state) is False
|
||||
|
||||
|
||||
def test_run_worker_once_dispatches_refresh_global_overlays(seeded_worker, monkeypatch):
|
||||
from l4d2web.services import job_worker
|
||||
from l4d2web.models import Job
|
||||
from l4d2web.db import session_scope
|
||||
|
||||
called = []
|
||||
|
||||
def fake_refresh(*, on_stdout, on_stderr, should_cancel):
|
||||
called.append("refresh")
|
||||
on_stdout("global refresh complete")
|
||||
return ["l4d2center-maps"]
|
||||
|
||||
monkeypatch.setattr(job_worker, "_run_refresh_global_overlays", fake_refresh)
|
||||
with session_scope() as db:
|
||||
job = Job(user_id=None, server_id=None, operation="refresh_global_overlays", state="queued")
|
||||
db.add(job)
|
||||
|
||||
app, ids = seeded_worker
|
||||
assert job_worker.run_worker_once() is True
|
||||
assert called == ["refresh"]
|
||||
state.running_overlays.add(ids.overlay)
|
||||
assert (
|
||||
can_start(DummyJob(operation="build_overlay", overlay_id=ids.overlay), state)
|
||||
is False
|
||||
)
|
||||
assert (
|
||||
can_start(DummyJob(operation="build_overlay", overlay_id=ids.overlay + 1), state)
|
||||
is True
|
||||
)
|
||||
|
|
|
|||
|
|
@ -476,13 +476,13 @@ def test_admin_jobs_page_renders_system_job(tmp_path, monkeypatch) -> None:
|
|||
sess["user_id"] = admin_id
|
||||
|
||||
with session_scope() as db:
|
||||
db.add(Job(user_id=None, server_id=None, operation="refresh_global_overlays", state="queued"))
|
||||
db.add(Job(user_id=None, server_id=None, operation="refresh_workshop_items", state="queued"))
|
||||
|
||||
response = admin_client.get("/admin/jobs")
|
||||
text = response.get_data(as_text=True)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert "refresh_global_overlays" in text
|
||||
assert "refresh_workshop_items" in text
|
||||
assert "system" in text
|
||||
|
||||
|
||||
|
|
@ -503,7 +503,7 @@ def test_non_admin_cannot_view_system_job(tmp_path, monkeypatch) -> None:
|
|||
sess["user_id"] = user_id
|
||||
|
||||
with session_scope() as db:
|
||||
job = Job(user_id=None, server_id=None, operation="refresh_global_overlays", state="queued")
|
||||
job = Job(user_id=None, server_id=None, operation="refresh_workshop_items", state="queued")
|
||||
db.add(job)
|
||||
db.flush()
|
||||
job_id = job.id
|
||||
|
|
|
|||
Loading…
Reference in a new issue