@@ -23,20 +23,20 @@ function matchUsers(channel, msg, userId, language, difficulty) {
23
23
waitingUsers [ criteriaKey ] = [ ] ;
24
24
}
25
25
26
- waitingUsers [ criteriaKey ] . push ( { userId, msg } ) ; // Store both userId and the message
26
+ // Store both the userId, message, and the channel in waitingUsers
27
+ waitingUsers [ criteriaKey ] . push ( { userId, msg, channel } ) ;
27
28
console . log ( `User ${ userId } added to ${ criteriaKey } . Waiting list: ${ waitingUsers [ criteriaKey ] . length } ` ) ;
28
29
29
30
// Check if there are 2 or more users waiting for this criteria
30
31
if ( waitingUsers [ criteriaKey ] . length >= 2 ) {
31
32
const matchedUsers = waitingUsers [ criteriaKey ] . splice ( 0 , 2 ) ; // Match the first two users
32
33
console . log ( `Matched users: ${ matchedUsers . map ( user => user . userId ) } ` ) ;
33
34
34
- // Send match success (this could trigger WebSocket communication)
35
- // notifyUsers(matchedUsers.map(user => user.userId));
35
+ // Notify users of the match
36
36
notifyUsers ( matchedUsers . map ( user => user . userId ) , 'Match found!' , 'match' ) ;
37
37
38
38
// Acknowledge the messages for both matched users
39
- matchedUsers . forEach ( ( { msg } ) => {
39
+ matchedUsers . forEach ( ( { msg, channel } ) => {
40
40
acknowledgeMessage ( channel , msg ) ;
41
41
} ) ;
42
42
@@ -46,6 +46,7 @@ function matchUsers(channel, msg, userId, language, difficulty) {
46
46
return false ;
47
47
}
48
48
49
+
49
50
async function acknowledgeMessage ( channel , msg ) {
50
51
return new Promise ( ( resolve , reject ) => {
51
52
try {
@@ -104,7 +105,6 @@ async function rejectMessage(channel, msg, userId) {
104
105
105
106
async function consumeQueue ( ) {
106
107
try {
107
- // Connect
108
108
const connection = await amqp . connect ( process . env . RABBITMQ_URL ) ;
109
109
const channel = await connection . createChannel ( ) ;
110
110
@@ -123,26 +123,23 @@ async function consumeQueue() {
123
123
// Call matchUsers with channel, message, and user details
124
124
const matched = matchUsers ( channel , msg , userId , language , difficulty ) ;
125
125
126
- // If not matched, set a timeout for rejection
127
126
if ( ! matched ) {
128
127
console . log ( `No match for ${ userId } , waiting for rejection timeout.` ) ;
129
128
130
- // Set a timeout for rejection after 10 seconds
131
129
const timeoutId = setTimeout ( async ( ) => {
132
130
await rejectMessage ( channel , msg , userId ) ;
133
131
} , 10000 ) ; // 10 seconds delay
134
132
135
- // Store the timeout ID
136
133
timeoutMap [ userId ] = timeoutId ;
137
134
}
138
135
}
139
- } ) ;
136
+ } , { noAck : false } ) ; // Ensure manual acknowledgment
140
137
}
141
138
142
139
console . log ( "Listening to matchmaking queues" ) ;
143
140
144
141
await consumeCancelQueue ( ) ;
145
- console . log ( "Listening to Cancel Queue" )
142
+ console . log ( "Listening to Cancel Queue" ) ;
146
143
} catch ( error ) {
147
144
console . error ( 'Error consuming RabbitMQ queue:' , error ) ;
148
145
}
@@ -184,45 +181,62 @@ async function consumeCancelQueue() {
184
181
await channel . consume ( 'cancel_queue' , async ( msg ) => {
185
182
if ( msg !== null ) {
186
183
const { userId } = JSON . parse ( msg . content . toString ( ) ) ;
187
-
188
184
console . log ( `Received cancel request for user: ${ userId } ` ) ;
189
185
190
186
// Process the cancel request
191
187
await cancelMatching ( channel , msg , userId ) ;
192
188
}
193
- } ) ;
189
+ } , { noAck : false } ) ; // Ensure manual acknowledgment
194
190
195
191
console . log ( "Listening for cancel requests" ) ;
196
192
} catch ( error ) {
197
193
console . error ( 'Error consuming cancel queue:' , error ) ;
198
194
}
199
195
}
200
196
201
- async function cancelMatching ( channel , msg , userId ) {
197
+ async function cancelMatching ( cancelChannel , cancelMsg , userId ) {
202
198
try {
203
- // Loop through waitingUsers to find the user
199
+ let foundOriginalMsg = false ;
200
+
201
+ // Loop through waitingUsers to find the original message for the user
204
202
Object . keys ( waitingUsers ) . forEach ( criteriaKey => {
205
203
const userIndex = waitingUsers [ criteriaKey ] . findIndex ( user => user . userId === userId ) ;
206
204
207
205
if ( userIndex !== - 1 ) {
206
+ const { msg, channel } = waitingUsers [ criteriaKey ] [ userIndex ] ; // Get original msg and its channel
207
+
208
+ // Acknowledge the original matchmaking message from the queue (e.g., easy.python)
209
+ if ( msg && channel ) {
210
+ console . log ( `Acknowledging original message for user ${ userId } in queue ${ criteriaKey } ` ) ;
211
+ channel . ack ( msg ) ; // Use the same channel that consumed the message to acknowledge it
212
+ foundOriginalMsg = true ;
213
+ }
214
+
215
+ // Remove the user from the waiting list
208
216
waitingUsers [ criteriaKey ] . splice ( userIndex , 1 ) ;
209
217
console . log ( `User ${ userId } removed from waiting list for ${ criteriaKey } ` ) ;
210
218
}
211
219
} ) ;
212
220
213
- // Clean up the timeout
221
+ // If original message not found, log a warning
222
+ if ( ! foundOriginalMsg ) {
223
+ console . warn ( `Original message for user ${ userId } not found in matchmaking queues.` ) ;
224
+ }
225
+
226
+ // Clear any timeouts for the user
214
227
if ( timeoutMap [ userId ] ) {
215
228
clearTimeout ( timeoutMap [ userId ] ) ;
216
229
delete timeoutMap [ userId ] ;
217
230
}
218
231
219
- // Acknowledge the cancel message
220
- channel . ack ( msg ) ;
221
-
232
+ // Acknowledge the cancel message from the cancel queue
233
+ cancelChannel . ack ( cancelMsg ) ;
222
234
console . log ( `Cancel processed for user ${ userId } ` ) ;
235
+
223
236
} catch ( error ) {
224
237
console . error ( `Failed to process cancel for user ${ userId } :` , error ) ;
225
238
}
226
239
}
227
240
241
+
228
242
module . exports = { consumeQueue, consumeDLQ } ;
0 commit comments