redis & listening works!!
This commit is contained in:
10
backend/app/db/redis.py
Normal file
10
backend/app/db/redis.py
Normal 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
|
||||
@ -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()
|
||||
|
||||
@ -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"}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -5,4 +5,5 @@ sqlalchemy
|
||||
psycopg2-binary
|
||||
python-jose[cryptography]
|
||||
passlib[all]
|
||||
captcha
|
||||
captcha
|
||||
redis[hiredis]
|
||||
12
dev.yml
12
dev.yml
@ -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
4
env/backend/dev.env
vendored
@ -1,4 +1,6 @@
|
||||
POSTGRES_USER=user
|
||||
POSTGRES_PASSWORD=password
|
||||
POSTGRES_DB=db
|
||||
DEBUG=1
|
||||
DEBUG=1
|
||||
REDIS_HOST=redis
|
||||
REDIS_PORT=6379
|
||||
7
frontend/app/src/components/user/AnonUserCard.tsx
Normal file
7
frontend/app/src/components/user/AnonUserCard.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import React from "react";
|
||||
|
||||
const UUIDToColor = (uuid: string): string => {};
|
||||
|
||||
const AnonUserCard = (): JSX.Element => {
|
||||
return;
|
||||
};
|
||||
Reference in New Issue
Block a user