Skip to content

Commit 7f18eb0

Browse files
authored
Merge pull request #50 from CS3219-AY2324S1/assignment5-resolveError
resolve some logic error within the matching algorithm
2 parents 0edbb20 + 750b078 commit 7f18eb0

File tree

4 files changed

+90
-24
lines changed

4 files changed

+90
-24
lines changed

peer-prep/src/matching-service/controllers/matchingController.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,30 @@ const matchingService = require('../services/matchingService');
22

33
async function findMatch(req, res, next) {
44
try {
5-
const { id, language, proficiency, difficulty, topic } = req.body;
5+
const {language, proficiency, difficulty, topic } = req.body;
6+
const id = req.params.userId; // Extract user id from request params
67
console.log(req.body);
78
console.log(`${id}, ${language}, ${proficiency}, ${difficulty}, ${topic}`);
89

9-
const matchResult = await matchingService.findMatch({ id, language, proficiency, difficulty, topic });
10-
11-
res.status(200).json(matchResult);
10+
const matchResult = await matchingService.findMatch({id, language, proficiency, difficulty, topic});
11+
12+
switch(matchResult.status) {
13+
case 'success':
14+
res.status(200).json(matchResult);
15+
break;
16+
case 'error':
17+
res.status(500).json(matchResult);
18+
break;
19+
case 'cancel':
20+
res.status(200).json(matchResult);
21+
break;
22+
default:
23+
res.status(500).json({message:'Unknown error. Please try again!'});
24+
}
1225

1326
} catch (error) {
14-
next(error);
27+
console.error(error);
28+
res.status(500).json({message:'Failed to find a match. Please try again!'})
1529
}
1630
}
1731

peer-prep/src/matching-service/database/matchedPairDb.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ async function endSession(sessionId) {
3838
try {
3939
const filter = { sessionId: sessionId };
4040
const update = { $set: { isEnded: true } };
41-
await MatchedPair.updateOne(filter, update);
41+
const result = await MatchedPair.updateOne(filter, update);
42+
43+
if (result.nModified == 0) {
44+
console.warn(`No session was updated for session ${sessionId}`);
45+
}
46+
4247
console.log(`Successfully update session state for session ${sessionId}`);
4348

4449
} catch (error) {

peer-prep/src/matching-service/server.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
const express = require('express');
22
const app = express();
33
const mongoose = require('mongoose');
4-
const bodyParser = require('body-parser');
5-
const routes = require('./routes/routes');
64
const config = require('./config/config');
5+
const routes = require('./routes/routes');
6+
77

88
mongoose.connect(config.mongodbUri, {
99
useNewUrlParser: true,
1010
useUnifiedTopology: true,
1111
});
1212

13-
app.use(bodyParser.urlencoded({ extended: true }));
13+
app.use(express.urlencoded({ extended: true })); // use express's built-in middleware
14+
app.use(express.json()); // This is the middleware to handle JSON payloads
1415

1516
app.use('/', routes);
1617

peer-prep/src/matching-service/services/matchingService.js

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ const amqp = require('amqplib');
33
const { v4: uuidv4 } = require('uuid');
44
const { addMatchedPair, getCurrentMatchedPair } = require('../database/matchedPairDb');
55
const MatchedPair = require('../models/matchedPairModel');
6+
const matchedPairDb = require('../database/matchedPairDb');
7+
68

79
const refreshDuration = 3000; // 3 seconds
810
const waitingDuration = 3000;
@@ -14,6 +16,7 @@ let availabilityCache = new Set();
1416

1517
// Find matching pair based on the selected criteria : language, proficiency, difficulty, topic
1618
async function findMatch(request) {
19+
1720
return new Promise(async(resolve) => {
1821
let connection;
1922
let channel;
@@ -25,22 +28,23 @@ async function findMatch(request) {
2528

2629
console.log('Successfully connected to RabbitMQ');
2730

28-
const criteria = `${request.language}
29-
.${request.proficiency}
30-
.${request.difficulty}
31-
.${request.topic}`;
31+
const criteria = `${request.language || 'None'}
32+
.${request.proficiency || 'None'}
33+
.${request.difficulty || 'None'}
34+
.${request.topic || 'None'}`;
3235

3336
checkCancel = setInterval(async() => {
3437
if (isCancelled.has(parseInt(request.id))) {
3538
clearInterval(checkCancel);
36-
resolve({ isMatched: false, collaboratorId: null, request: request });
39+
resolve({status: 'cancel', isMatched: false, collaboratorId: null, request: request });
3740

3841
} else {
3942
const checkMatchedPair = await getCurrentMatchedPair(request.id);
4043

4144
if (checkMatchedPair) {
4245
clearInterval(checkCancel);
4346
resolve({
47+
status: 'success',
4448
isMatched: true,
4549
collaboratorId: String(checkMatchedPair.id1) === String(request.id) ?
4650
parseInt(checkMatchedPair.id2) : parseInt(checkMatchedPair.id1),
@@ -63,10 +67,11 @@ async function findMatch(request) {
6367
if (!isMatched) {
6468
console.log(`Matched pair could not be found for ${request.id}`);
6569

66-
resolve({ isMatched: false, collaboratorId: null, request: request });
70+
resolve({status: 'error', isMatched: false, collaboratorId: null, request: request });
6771

6872
} else if (stored) {
6973
resolve({
74+
status: 'success',
7075
isMatched: true,
7176
collaboratorId: parseInt(collaboratorId),
7277
request: request
@@ -87,13 +92,16 @@ async function findMatch(request) {
8792
await addMatchedPair(matchedPair);
8893

8994
resolve({
95+
status: 'success',
9096
isMatched: true,
9197
collaboratorId: parseInt(collaboratorId),
9298
request: request
9399
});
94100
}
95101
} catch (error) {
96102
console.log('Error finding match: ', error);
103+
resolve({ status: 'error', message: error.message, isMatched: false, collaboratorId: null, request: request });
104+
97105
} finally {
98106
availabilityCache.delete(request.id);
99107

@@ -107,6 +115,18 @@ async function findMatch(request) {
107115
});
108116
}
109117

118+
function criteriaMatches(requestCriteria, currentCriteria) {
119+
const fields = ['language', 'proficiency', 'difficulty', 'topic'];
120+
for (let field of fields) {
121+
if (requestCriteria[field] !== "None" &&
122+
currentCriteria[field] !== "None" &&
123+
requestCriteria[field] !== currentCriteria[field]) {
124+
return false;
125+
}
126+
}
127+
return true;
128+
}
129+
110130
// Add new request into the queue, 'topic' exchange type is used to route the message
111131
async function addRequestIntoQueue(channel, criteria, request) {
112132
try {
@@ -167,29 +187,26 @@ async function listenToMatchingQueue(channel, criteria, request) {
167187
channel.consume(queueName, async(message) => {
168188
const currentRequest = JSON.parse(message.content.toString());
169189
const checkActivePair = await getCurrentMatchedPair(currentRequest.request.id);
170-
171-
if (checkActivePair &&
172-
(String(checkActivePair.id1) === String(request.id) ||
173-
String(checkActivePair.id2) === String(request.id))) {
174-
190+
191+
// Check if there is an active pair and if the criteria still match
192+
if (checkActivePair && criteriaMatches(request, currentRequest.request)) {
193+
const collaboratorId = String(checkActivePair.id1) === String(request.id) ? checkActivePair.id2 : checkActivePair.id1;
175194
resolve({
176195
stored: true,
177196
isMatched: true,
178197
id: request.id,
179-
collaboratorId: currentRequest.request.id
198+
collaboratorId: collaboratorId
180199
});
181200

182201
} else if (checkActivePair ||
183202
isCancelled.has(parseInt(currentRequest.request.id))) {
184203

185204
console.log(`Remove match ${currentRequest.request.id}`);
186-
187205
availabilityCache.delete(currentRequest.request.id);
188206
channel.ack(message);
189207

190208
} else if (!matched &&
191-
currentRequest.request.id !== request.id &&
192-
currentRequest.criteria === criteria &&
209+
currentRequest.request.id !== request.id && criteriaMatches(request, currentRequest.request) &&
193210
availabilityCache.has(currentRequest.request.id)) {
194211

195212
console.log(`Found a match for ${request.id}`);
@@ -219,13 +236,42 @@ async function listenToMatchingQueue(channel, criteria, request) {
219236

220237
// Cancel matching service
221238

239+
//async function cancelMatch(requestId) {
240+
// isCancelled.add(parseInt(requestId));
241+
// availabilityCache.delete(requestId);
242+
//
243+
// console.log(`Matching service is cancelled for ${requestId}`);
244+
245+
// return true;
246+
//}
247+
222248
async function cancelMatch(requestId) {
249+
// Adding the requestId to the cancelled set
223250
isCancelled.add(parseInt(requestId));
251+
252+
// Removing the requestId from the availability cache
224253
availabilityCache.delete(requestId);
225254

226255
console.log(`Matching service is cancelled for ${requestId}`);
227256

257+
// Check if there's an ongoing session for the given requestId
258+
const currentMatchedPair = await matchedPairDb.getCurrentMatchedPair(requestId);
259+
if (currentMatchedPair) {
260+
console.log(`Found ongoing session for ${requestId}. Terminating...`);
261+
262+
try {
263+
await matchedPairDb.endSession(currentMatchedPair.sessionId);
264+
console.log(`Successfully terminated session for ${requestId}`);
265+
} catch (error) {
266+
console.error(`Error while terminating session for ${requestId}:`, error);
267+
throw error;
268+
}
269+
} else {
270+
console.log(`No ongoing session found for ${requestId}`);
271+
}
272+
228273
return true;
229274
}
230275

276+
231277
module.exports = { findMatch, cancelMatch };

0 commit comments

Comments
 (0)