-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/roles and ban system #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0fd8be8
0fae65e
4507278
71c6cd3
9ce16d4
6ff4fc1
0acd843
193c2f2
4f205d0
a7126ce
bd8baac
76ae31b
16e8ac7
431d08c
c73f102
9b5c47d
4cf54f9
da6a42d
04375e2
3d5d04e
683fdd7
4b151c4
b79c134
8f9b791
971bb34
69e2a76
928b38b
a0f32f4
9d68e55
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,10 @@ | |
| from src.presentation.middlewares import MetricsMiddleware | ||
| from src.infrastructure.tasks.cleanup_magic_tokens import cleanup_telegram_tokens | ||
| from src.config import get_database_url | ||
| from src.infrastructure.tasks.remove_bans import remove_expired_bans | ||
| from src.infrastructure.db import database | ||
|
|
||
| scheduler = AsyncIOScheduler() # Планировщик | ||
|
|
||
| @asynccontextmanager | ||
| async def lifespan(app: FastAPI): | ||
|
|
@@ -24,17 +28,31 @@ async def lifespan(app: FastAPI): | |
| DB_URL | ||
| ) | ||
|
|
||
| SessionLocal = async_sessionmaker( | ||
| bind=engine, | ||
| class_=AsyncSession, | ||
| database.SessionLocal = async_sessionmaker( | ||
| bind=engine, | ||
| class_=AsyncSession, | ||
| expire_on_commit=False | ||
| ) | ||
|
|
||
| app.state.SessionLocal = SessionLocal | ||
| @app.on_event("startup") | ||
| async def startup(): | ||
| scheduler.add_job( | ||
| cleanup_telegram_tokens, | ||
| "interval", | ||
| minutes=5 | ||
| ) | ||
| scheduler.add_job( | ||
| remove_expired_bans, | ||
| "interval", | ||
| minutes=10 | ||
| ) | ||
| scheduler.start() | ||
|
|
||
| # При старте выполняется ко до yiled | ||
| yield | ||
| # выполняется код после yiled и остановка | ||
|
|
||
| scheduler.dispose() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): Использование
Original comment in Englishissue (bug_risk): Using
|
||
| await engine.dispose() | ||
|
|
||
|
|
||
|
|
@@ -69,18 +87,6 @@ async def lifespan(app: FastAPI): | |
| allow_credentials=True | ||
| ) | ||
|
|
||
| scheduler = AsyncIOScheduler() # Планировщик | ||
| @app.on_event("startup") | ||
| async def startup(): | ||
| scheduler.add_job( | ||
| cleanup_telegram_tokens, | ||
| "interval", | ||
| minutes=5 | ||
| ) | ||
| scheduler.start() | ||
|
|
||
|
|
||
|
|
||
| @app.get("/") | ||
| @limiter.limit("5/minute") | ||
| def welcome(request: Request): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,18 @@ | ||
| from sqlalchemy.orm import declarative_base | ||
| from fastapi import Request | ||
| from sqlalchemy.ext.asyncio import ( | ||
| AsyncSession, | ||
| async_sessionmaker | ||
| ) | ||
|
|
||
| Base = declarative_base() | ||
|
|
||
| async def get_db(request: Request): | ||
|
|
||
| async with request.app.state.SessionLocal() as session: | ||
| try: | ||
| SessionLocal: async_sessionmaker[AsyncSession] | None = None | ||
|
|
||
| async def get_db(): | ||
| if SessionLocal is None: | ||
| raise RuntimeError("Database is not initialied") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick (typo): Опечатка в сообщении RuntimeError. Замените Original comment in Englishnitpick (typo): Typo in the RuntimeError message. Change |
||
| async with SessionLocal() as session: | ||
| yield session | ||
| finally: | ||
| await session.close() | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| from sqlalchemy import update | ||
| from datetime import datetime, timezone | ||
|
|
||
| from src.domain.models.ban_model import Ban | ||
| from src.infrastructure.db.database import SessionLocal | ||
|
|
||
| async def remove_expired_bans(): | ||
| async with SessionLocal() as db: | ||
| await db.execute(update(Ban).where( | ||
| Ban.expires_at.is_not(None), | ||
| Ban.expires_at < datetime.now(timezone.utc), | ||
| Ban.revoked_at.is_(None) | ||
| ).values( | ||
| revoked_at = datetime.now(timezone.utc), | ||
| revoked_reason="Expiration of the Term" | ||
| ) | ||
|
Comment on lines
+7
to
+16
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Дважды использовать Здесь Original comment in Englishsuggestion: Using Here, |
||
| ) | ||
|
|
||
| await db.commit() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Регистрация обработчика события startup внутри контекста lifespan может повлиять на то, когда именно задачи будут запланированы.
Поскольку декоратор теперь выполняется при входе в контекст lifespan, а не при импорте модуля, обработчик может быть зарегистрирован слишком поздно или более одного раза, если контекст будет входиться повторно. Рассмотрите варианты:
on_event("startup")на этапе импорта модуля и выполнять только привязкуSessionLocalвlifespan, илиlifespan(безon_event), чтобы явно контролировать момент добавления задач и запуска планировщика.Также убедитесь с помощью тестов или логов, что логика startup выполняется ровно один раз в нужный момент жизненного цикла приложения.
Original comment in English
issue (bug_risk): Registering the startup event handler inside the lifespan context may affect when the jobs are actually scheduled.
Because the decorator now runs when the lifespan context is entered rather than at import time, the handler may be registered too late or more than once if the context is re‑entered. Consider either:
on_event("startup")handler at module import time and only wiringSessionLocalinlifespan, orlifespan(withouton_event) so you explicitly control when jobs are added and the scheduler is started.Also verify via tests or logs that the startup logic runs exactly once at the intended point in the app lifecycle.