|
| 1 | +from fastapi.responses import JSONResponse, Response |
1 | 2 | from typing import Union
|
2 | 3 |
|
3 | 4 | from models.match import MatchModel, MessageModel
|
4 |
| -from utils.redis import get_redis, acquire_lock, release_lock |
| 5 | +from utils.redis import acquire_lock, redis_client, release_lock |
5 | 6 | from utils.socketmanager import manager
|
6 | 7 |
|
7 | 8 | async def find_match_else_enqueue(
|
8 | 9 | user_id: str,
|
9 | 10 | topic: str,
|
10 | 11 | difficulty: str
|
11 |
| -) -> Union[MessageModel, MatchModel]: |
12 |
| - redis_client = await get_redis() |
| 12 | +) -> Union[Response, JSONResponse]: |
13 | 13 | queue_key = _build_queue_key(topic, difficulty)
|
14 |
| - |
15 |
| - result = None |
16 |
| - |
17 |
| - # ACQUIRE LOCK |
18 | 14 | islocked = await acquire_lock(redis_client, queue_key)
|
19 | 15 |
|
20 | 16 | if not islocked:
|
21 | 17 | raise Exception("Could not acquire lock")
|
22 | 18 |
|
23 | 19 | # Check if the user is already in the queue
|
24 |
| - user_in_queue = await redis_client.lrange(queue_key, 0, -1) |
25 |
| - if user_id in user_in_queue: |
26 |
| - result = MessageModel( |
27 |
| - message=f"User {user_id} is already in the queue, waiting for a match" |
28 |
| - ) |
29 |
| - else: |
30 |
| - queue_length = await redis_client.llen(queue_key) |
31 |
| - if queue_length > 0: |
32 |
| - matched_user = await redis_client.rpop(queue_key) |
33 |
| - result = MatchModel( |
34 |
| - user1=user_id, |
35 |
| - user2=matched_user, |
36 |
| - topic=topic, |
37 |
| - difficulty=difficulty, |
38 |
| - ) |
39 |
| - await manager.broadcast(matched_user, topic, difficulty, result.json()) |
40 |
| - # await manager.disconnect(matched_user, topic, difficulty) |
41 |
| - else: |
42 |
| - await redis_client.lpush(queue_key, user_id) |
43 |
| - result = MessageModel( |
44 |
| - message=f"User {user_id} enqueued, waiting for a match" |
45 |
| - ) |
| 20 | + if user_id in await redis_client.lrange(queue_key, 0, -1): |
| 21 | + await release_lock(redis_client, queue_key) |
| 22 | + return Response(status_code=304) |
46 | 23 |
|
47 |
| - # RELEASE LOCK |
| 24 | + # Check if there are no other users in the queue |
| 25 | + if await redis_client.llen(queue_key) == 0: |
| 26 | + await redis_client.lpush(queue_key, user_id) |
| 27 | + await release_lock(redis_client, queue_key) |
| 28 | + return Response(status_code=202) |
| 29 | + |
| 30 | + # There is a user in the queue |
| 31 | + matched_user = await redis_client.rpop(queue_key) |
48 | 32 | await release_lock(redis_client, queue_key)
|
49 |
| - return result |
| 33 | + response = MatchModel( |
| 34 | + user1=matched_user, |
| 35 | + user2=user_id, |
| 36 | + topic=topic, |
| 37 | + difficulty=difficulty, |
| 38 | + ) |
| 39 | + await manager.broadcast(matched_user, topic, difficulty, response.json()) |
| 40 | + await manager.disconnect_all(matched_user, topic, difficulty) |
| 41 | + return JSONResponse(status_code=201, content=response.json()) |
50 | 42 |
|
51 | 43 | async def remove_user_from_queue(
|
52 | 44 | user_id: str,
|
53 | 45 | topic: str,
|
54 | 46 | difficulty: str
|
55 |
| -) -> MessageModel: |
56 |
| - redis_client = await get_redis() |
| 47 | +) -> Response: |
57 | 48 | queue_key = _build_queue_key(topic, difficulty)
|
58 |
| - |
59 |
| - # ACQUIRE LOCK |
60 | 49 | islocked = await acquire_lock(redis_client, queue_key)
|
61 | 50 |
|
62 | 51 | if not islocked:
|
63 | 52 | raise Exception("Could not acquire lock")
|
64 | 53 |
|
65 |
| - # Check if the user is already in the queue |
66 |
| - user_in_queue = await redis_client.lrange(queue_key, 0, -1) |
67 |
| - if user_id in user_in_queue: |
| 54 | + if user_id in await redis_client.lrange(queue_key, 0, -1): |
68 | 55 | await redis_client.lrem(queue_key, 0, user_id)
|
69 |
| - result = MessageModel(message=f"User {user_id} removed from the queue") |
70 |
| - else: |
71 |
| - result = MessageModel(message=f"User {user_id} is not in the queue") |
72 | 56 |
|
73 |
| - # RELEASE LOCK |
74 | 57 | await release_lock(redis_client, queue_key)
|
75 |
| - return result |
| 58 | + await manager.disconnect_all(user_id, topic, difficulty) |
| 59 | + return Response(status_code=200) |
76 | 60 |
|
77 | 61 | '''
|
78 | 62 | Helper functions for matching.
|
|
0 commit comments