redis & listening works!!

This commit is contained in:
2024-05-10 15:11:25 +03:00
parent 2a696f96c1
commit 0ebfd11851
10 changed files with 105 additions and 14 deletions

10
backend/app/db/redis.py Normal file
View File

@ -0,0 +1,10 @@
import redis
import os
REDIS_HOST = os.environ.get("REDIS_HOST", "redis")
REDIS_PORT = int(os.environ.get("REDIS_PORT", "6379"))
async def create_redis() -> redis.Redis:
redis_connection = await redis.asyncio.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0)
return redis_connection

View File

@ -1,4 +1,9 @@
from typing import Annotated
from fastapi import Depends
import redis
from .db.database import SessionLocal
from .db.redis import create_redis
def get_db():
@ -7,3 +12,19 @@ def get_db():
yield db
finally:
db.close()
async def get_redis():
r = await create_redis()
try:
yield r
finally:
r.close()
async def get_pubsub(r: Annotated[redis.Redis, Depends(get_redis)]):
ps = r.pubsub()
try:
yield ps
finally:
ps.close()

View File

@ -1,8 +1,10 @@
from typing import Union
from typing import Union, Annotated
from fastapi import FastAPI, Depends
import redis
from .db import models
from .db.database import SessionLocal, engine
from .db.redis import create_redis
from .dependencies import get_db
from .views.auth.api import router as auth_router
@ -17,6 +19,12 @@ app.include_router(auth_router)
app.include_router(news_router)
@app.on_event("startup")
async def startup_event():
r = await create_redis()
await r.flushall()
@app.get("/")
async def read_root():
return {"message": "OK"}

View File

@ -53,3 +53,10 @@ async def join_queue(
queue_user: Annotated[schemas.QueueUser, Depends(services.join_queue)]
) -> schemas.QueueUser:
return queue_user
@router.post("/{queue_id}/listen")
async def listen_queue(
updated_queue: Annotated[schemas.QueueDetail, Depends(services.set_queue_listener)]
) -> schemas.QueueDetail:
return updated_queue

View File

@ -1,11 +1,23 @@
from typing import Union
from typing import Union, List
from pydantic import BaseModel
from uuid import UUID
from ..auth import schemas as auth_schemas
class QueueUser(BaseModel):
id: UUID
position: int
passed: bool
user: auth_schemas.AnonUser
class Config:
from_attributes = True
class ParticipantInfo(BaseModel):
total: int
remaining: int
users_list: List[QueueUser]
class Queue(BaseModel):
@ -30,12 +42,3 @@ class QueueInDb(Queue):
class QueueDetail(Queue):
id: UUID
participants: ParticipantInfo
class QueueUser(BaseModel):
id: UUID
position: int
passed: bool
class Config:
from_attributes = True

View File

@ -2,8 +2,10 @@ from fastapi import Depends, HTTPException, status
from typing import Annotated
from sqlalchemy.orm import Session
from uuid import UUID
import redis
import asyncio
from ...dependencies import get_db
from ...dependencies import get_db, get_pubsub
from ...db import models
from ..auth import services as auth_services
@ -50,6 +52,9 @@ def get_detailed_queue(
participants=schemas.ParticipantInfo(
total=q.users.count(),
remaining=q.users.filter(models.QueueUser.passed == False).count(),
users_list=q.users.filter(models.QueueUser.passed == False).order_by(
models.QueueUser.position.asc()
),
),
)
raise HTTPException(
@ -82,3 +87,18 @@ def join_queue(
status_code=status.HTTP_404_NOT_FOUND,
detail="Not Found",
)
async def set_queue_listener(
queue_id: UUID,
db: Annotated[Session, Depends(get_db)],
ps: Annotated[redis.client.PubSub, Depends(get_pubsub)],
) -> schemas.QueueDetail:
await ps.subscribe(str(queue_id))
async for m in ps.listen():
print(m, flush=True)
if m.get("data", None) == b"updated":
print("UPDATED", flush=True)
break
new_queue = get_detailed_queue(queue_id=queue_id, db=db)
return new_queue

View File

@ -5,4 +5,5 @@ sqlalchemy
psycopg2-binary
python-jose[cryptography]
passlib[all]
captcha
captcha
redis[hiredis]

12
dev.yml
View File

@ -13,6 +13,8 @@ services:
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
frontend:
build:
context: frontend
@ -51,3 +53,13 @@ services:
interval: 2s
timeout: 2s
retries: 5
redis:
image: redis:7.2.4-alpine
restart: unless-stopped
ports:
- 6379
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval: 2s
timeout: 2s
retries: 5

4
env/backend/dev.env vendored
View File

@ -1,4 +1,6 @@
POSTGRES_USER=user
POSTGRES_PASSWORD=password
POSTGRES_DB=db
DEBUG=1
DEBUG=1
REDIS_HOST=redis
REDIS_PORT=6379

View File

@ -0,0 +1,7 @@
import React from "react";
const UUIDToColor = (uuid: string): string => {};
const AnonUserCard = (): JSX.Element => {
return;
};