Skip to content

Commit 717f5e0

Browse files
authored
Refactor matching logic (#83)
1 parent 3c994eb commit 717f5e0

File tree

5 files changed

+42
-15
lines changed

5 files changed

+42
-15
lines changed

backend/gateway-service/src/modules/match/match.controller.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { Inject } from '@nestjs/common';
1212
import { firstValueFrom } from 'rxjs';
1313
import { RedisService } from './redis.service';
1414
import { MatchRequestDto } from './dto';
15-
import { MATCH_SUCCESS, MATCH_TIMEOUT } from './match.event';
15+
import { MATCH_FOUND, MATCH_CANCELLED, MATCH_CONFIRMED, MATCH_TIMEOUT, MATCH_REQUESTED } from './match.event';
1616

1717
@WebSocketGateway({ namespace: '/match' })
1818
export class MatchGateway implements OnGatewayInit {
@@ -48,27 +48,39 @@ export class MatchGateway implements OnGatewayInit {
4848

4949
// Send the match request to the microservice
5050
try {
51-
await firstValueFrom(this.matchingClient.send('match.request', matchPayload));
51+
firstValueFrom(this.matchingClient.send('match.request', matchPayload))
52+
.then(() => console.log(`Match requested for user ${payload.userId}`))
53+
.catch((error) => console.error(`Error requesting match for user ${payload.userId}: ${error.message}`));
54+
this.server.to(client.id).emit(MATCH_REQUESTED, {
55+
message: `Match request sent to the matching service.`,
56+
});
5257
} catch (error) {
5358
client.emit('matchError', `Error requesting match: ${error.message}`);
5459
return;
5560
}
5661
}
5762

63+
@SubscribeMessage('matchCancel')
64+
async handleCancelMatch(@ConnectedSocket() client: Socket, @MessageBody() payload: { userId: string }) {
65+
firstValueFrom(this.matchingClient.send('match.cancel', { userId: payload.userId }))
66+
.then(() => console.log(`Match canceled for user ${payload.userId}`))
67+
.catch((error) => console.error(`Error canceling match for user ${payload.userId}: ${error.message}`));
68+
this.server.to(client.id).emit(MATCH_CANCELLED, {
69+
message: `You have been cancelled from the match.`,
70+
});
71+
}
72+
5873
// Notify both matched users via WebSocket
5974
notifyUsersWithMatch(matchedUsers: string[]) {
6075
const [user1, user2] = matchedUsers;
6176
const user1SocketId = this.getUserSocketId(user1);
6277
const user2SocketId = this.getUserSocketId(user2);
63-
if (user1SocketId) {
64-
this.server.to(user1SocketId).emit(MATCH_SUCCESS, {
78+
if (user1SocketId && user2SocketId) {
79+
this.server.to(user1SocketId).emit(MATCH_FOUND, {
6580
message: `You have been matched with user ${user2}`,
6681
matchedUserId: user2,
6782
});
68-
}
69-
70-
if (user2SocketId) {
71-
this.server.to(user2SocketId).emit(MATCH_SUCCESS, {
83+
this.server.to(user2SocketId).emit(MATCH_FOUND, {
7284
message: `You have been matched with user ${user1}`,
7385
matchedUserId: user1,
7486
});
@@ -95,13 +107,17 @@ export class MatchGateway implements OnGatewayInit {
95107
}
96108
}
97109

98-
handleDisconnect(@ConnectedSocket() client: Socket) {
110+
async handleDisconnect(@ConnectedSocket() client: Socket) {
99111
const userId = [...this.userSockets.entries()].find(
100112
([, socketId]) => socketId === client.id,
101113
)?.[0];
102114

103115
if (userId) {
104116
this.userSockets.delete(userId);
117+
// Remove user from Redis pool
118+
firstValueFrom(this.matchingClient.send('match.cancel', { userId }))
119+
.then(() => console.log(`Match canceled for user ${userId}`))
120+
.catch((error) => console.error(`Error canceling match for user ${userId}: ${error.message}`));
105121
console.log(`User ${userId} disconnected`);
106122
}
107123
}
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
export const MATCH_TIMEOUT = 'matchTimeout';
2-
export const MATCH_SUCCESS = 'matchSuccess';
3-
1+
export const MATCH_FOUND = 'matchFound'; // Emitted when a match is found
2+
export const MATCH_REQUESTED = 'matchRequested'; // Emitted when a user requests a match
3+
export const MATCH_CANCELLED = 'matchCancelled'; // Emitted when a match is cancelled
4+
export const MATCH_CONFIRMED = 'matchConfirmed'; // Emitted when a match is confirmed
5+
export const MATCH_TIMEOUT = 'matchTimeout'; // Emitted after 5 minutes of inactivity

backend/matching-service/src/app.controller.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,9 @@ export class AppController {
1111
async handleMatchRequest(@Payload() data: MatchRequestDto) {
1212
await this.appService.requestMatch(data);
1313
}
14+
15+
@MessagePattern('match.cancel')
16+
async handleMatchCancel(@Payload() data: { userId: string }) {
17+
await this.appService.cancelMatch(data.userId);
18+
}
1419
}

backend/matching-service/src/app.service.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Injectable } from '@nestjs/common';
2-
import Redis from 'ioredis';
32
import { MatchRequestDto } from './dto/match-request.dto';
43
import { RedisService } from './redis.service';
54

@@ -11,6 +10,11 @@ export class AppService {
1110
async requestMatch(data: MatchRequestDto): Promise<void> {
1211
await this.redisService.addUserToPool(data);
1312
}
13+
14+
// Remove user from the Redis pool
15+
async cancelMatch(userId: string): Promise<void> {
16+
await this.redisService.removeUsersFromPool([userId]);
17+
}
1418
}
1519

1620

backend/matching-service/src/match-worker.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class MatchWorkerService {
1212
setInterval(async () => {
1313
const users = await this.redisService.getUsersFromPool();
1414
const currentTime = Date.now();
15-
const timeout = 29000; // Slightly less than 30 seconds to account for processing time
15+
const timeout = 300000; // 5 minutes to remove any zombie users
1616
console.log('Polling', users);
1717
// Filter out users who have timed out
1818
const activeUsers = users.filter(user => currentTime - user.timestamp < timeout);
@@ -33,7 +33,7 @@ export class MatchWorkerService {
3333
// Remove the matched users from the Redis pool
3434
await this.redisService.removeUsersFromPool([bestMatch.user1.userId, bestMatch.user2.userId]);
3535
}
36-
}, 20000);
36+
}, 5000);
3737
}
3838

3939
// Ranking logic for matches

0 commit comments

Comments
 (0)