feat: implement async scheduler with lifespan management and update README

This commit is contained in:
grillazz
2026-10-22 13:29:43 +02:00
parent 4ea1ef0fe5
commit d1661f6036
6 changed files with 106 additions and 44 deletions
+62
View File
@@ -0,0 +1,62 @@
import pytest
from apscheduler import ConflictPolicy
from apscheduler.triggers.interval import IntervalTrigger
import app.services.scheduler as scheduler_service
@pytest.mark.anyio
async def test_scheduler_lifespan_starts_and_stops_scheduler(monkeypatch) -> None:
events = []
data_store = object()
event_broker = object()
class SchedulerStub:
async def __aenter__(self):
events.append("enter")
return self
async def __aexit__(self, *_args: object) -> None:
events.append("exit")
async def add_schedule(
self, func, trigger, *, id: str, conflict_policy: ConflictPolicy
) -> None:
events.append(("schedule", func, trigger, id, conflict_policy))
async def start_in_background(self) -> None:
events.append("start")
scheduler = SchedulerStub()
def create_data_store(actual_engine, *, schema):
assert actual_engine is scheduler_service.engine
assert schema == "scheduler"
return data_store
def create_event_broker(*, client_or_url):
assert client_or_url == (
scheduler_service.global_settings.redis_url.unicode_string()
)
return event_broker
def create_scheduler(actual_data_store, actual_event_broker):
assert actual_data_store is data_store
assert actual_event_broker is event_broker
return scheduler
monkeypatch.setattr(scheduler_service, "SQLAlchemyDataStore", create_data_store)
monkeypatch.setattr(scheduler_service, "RedisEventBroker", create_event_broker)
monkeypatch.setattr(scheduler_service, "AsyncScheduler", create_scheduler)
async with scheduler_service.scheduler_lifespan():
assert events[0] == "enter"
event_type, func, trigger, schedule_id, conflict_policy = events[1]
assert event_type == "schedule"
assert func is scheduler_service.tick
assert isinstance(trigger, IntervalTrigger)
assert schedule_id == "tick-sql-25"
assert conflict_policy is ConflictPolicy.replace
assert events[2:] == ["start"]
assert events[-1] == "exit"