generated from john/python-template
feat: run stale-job recovery periodically
Co-authored-by: Copilot App <[email protected]>
This commit is contained in:
co-authored by
Copilot App
parent
736d0c06f4
commit
f193b2800b
@@ -1,9 +1,15 @@
|
||||
import asyncio
|
||||
import logging
|
||||
from datetime import UTC
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
from typing import cast
|
||||
|
||||
import pytest
|
||||
from sqlalchemy.ext.asyncio import async_sessionmaker
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
from transcription.config import Settings
|
||||
from transcription.errors import AppError
|
||||
from transcription.errors import ErrorCategory
|
||||
from transcription.services import ServiceBundle
|
||||
@@ -79,6 +85,45 @@ async def test_run_worker_loop_survives_retriable_exception(monkeypatch, caplog)
|
||||
assert worker_health.snapshot().state == "stopped"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_run_worker_loop_periodically_requeues_stale_processing_jobs(monkeypatch):
|
||||
stop_event = asyncio.Event()
|
||||
stale_sweep_calls: list[datetime] = []
|
||||
|
||||
class _Jobs:
|
||||
settings = Settings(openrouter_api_key="test-key", worker_stale_job_seconds=120.0)
|
||||
|
||||
async def requeue_stale_processing_jobs(self, *, stale_before, session=None):
|
||||
_ = session
|
||||
stale_sweep_calls.append(stale_before)
|
||||
return 1
|
||||
|
||||
class _Bundle:
|
||||
jobs = _Jobs()
|
||||
|
||||
async def aclose(self):
|
||||
return
|
||||
|
||||
monkeypatch.setattr(
|
||||
"transcription.worker.ServiceBundle.from_session_factory",
|
||||
classmethod(lambda _cls, _factory=None, **_kwargs: cast(ServiceBundle, _Bundle())),
|
||||
)
|
||||
|
||||
async def _fake_process_next_queued_job(*, session=None, session_factory=None, services=None):
|
||||
_ = (session, session_factory, services)
|
||||
stop_event.set()
|
||||
return False
|
||||
|
||||
monkeypatch.setattr("transcription.worker.process_next_queued_job", _fake_process_next_queued_job)
|
||||
|
||||
fake_session_factory = cast(async_sessionmaker[AsyncSession], object())
|
||||
await run_worker_loop(stop_event=stop_event, poll_interval_seconds=0, session_factory=fake_session_factory)
|
||||
|
||||
assert len(stale_sweep_calls) >= 1
|
||||
expected_upper_bound = datetime.now(UTC) - timedelta(seconds=120.0)
|
||||
assert stale_sweep_calls[0] <= expected_upper_bound
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_run_worker_loop_reuses_one_bundle_across_jobs(monkeypatch):
|
||||
"""HIGH-02: the provider client is built once per loop, not once per job."""
|
||||
|
||||
Reference in New Issue
Block a user