mirror of
https://github.com/grillazz/fastapi-sqlalchemy-asyncpg.git
synced 2026-11-01 01:24:45 +03:00
feat: implement async scheduler with lifespan management and update README
This commit is contained in:
+22
-26
@@ -1,13 +1,16 @@
|
||||
from collections.abc import AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
from datetime import datetime
|
||||
|
||||
from apscheduler import AsyncScheduler
|
||||
from apscheduler import AsyncScheduler, ConflictPolicy
|
||||
from apscheduler.datastores.sqlalchemy import SQLAlchemyDataStore
|
||||
from apscheduler.eventbrokers.redis import RedisEventBroker
|
||||
from apscheduler.triggers.interval import IntervalTrigger
|
||||
from attrs import define
|
||||
from rotoger import get_logger
|
||||
from sqlalchemy import text
|
||||
from starlette.types import ASGIApp, Receive, Scope, Send
|
||||
|
||||
from app.database import AsyncSessionFactory
|
||||
from app.config import settings as global_settings
|
||||
from app.database import AsyncSessionFactory, engine
|
||||
|
||||
logger = get_logger()
|
||||
|
||||
@@ -21,26 +24,19 @@ async def tick():
|
||||
return True
|
||||
|
||||
|
||||
@define
|
||||
class SchedulerMiddleware:
|
||||
app: ASGIApp
|
||||
scheduler: AsyncScheduler
|
||||
@asynccontextmanager
|
||||
async def scheduler_lifespan() -> AsyncIterator[None]:
|
||||
scheduler = AsyncScheduler(
|
||||
SQLAlchemyDataStore(engine, schema="scheduler"),
|
||||
RedisEventBroker(client_or_url=global_settings.redis_url.unicode_string()),
|
||||
)
|
||||
|
||||
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
|
||||
"""
|
||||
Handles the incoming request and schedules tasks if the scope type is 'lifespan'.
|
||||
|
||||
Args:
|
||||
scope (Scope): The ASGI scope dictionary containing request information.
|
||||
receive (Receive): The ASGI receive callable.
|
||||
send (Send): The ASGI send callable.
|
||||
"""
|
||||
if scope["type"] == "lifespan":
|
||||
async with self.scheduler:
|
||||
await self.scheduler.add_schedule(
|
||||
tick, IntervalTrigger(seconds=25), id="tick-sql-25"
|
||||
)
|
||||
await self.scheduler.start_in_background()
|
||||
await self.app(scope, receive, send)
|
||||
else:
|
||||
await self.app(scope, receive, send)
|
||||
async with scheduler:
|
||||
await scheduler.add_schedule(
|
||||
tick,
|
||||
IntervalTrigger(seconds=25),
|
||||
id="tick-sql-25",
|
||||
conflict_policy=ConflictPolicy.replace,
|
||||
)
|
||||
await scheduler.start_in_background()
|
||||
yield
|
||||
|
||||
Reference in New Issue
Block a user