Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Submission & disconnection logic; bugfixes #40

Merged
merged 6 commits into from
Nov 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/collaboration-service/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ class Events:
CURSOR_UPDATED = 'cursor_updated'
USER_LEFT = 'user_left'
LANGUAGE_CHANGE= 'language_change'
CODE_SUBMITTED = 'code_submitted'
1 change: 1 addition & 0 deletions backend/collaboration-service/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def __init__(self, room_id: str, user: User):
self.id = room_id
self.users: list[User] = [user]
self.code = ""
self.submitted = False
Room.rooms[room_id] = self
user.join_room(self)

Expand Down
25 changes: 24 additions & 1 deletion backend/collaboration-service/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,29 @@ async def language_change(sid, data):
except Exception as e:
logging.error(f"Failed to emit LANGUAGE_CHANGE for user {sid}: {e}")

@sio.on(Events.CODE_SUBMITTED)
async def code_submitted(sid):
logging.debug(f'code_submitted {sid=}')
user: User = User.users.get(sid)

if user is None:
logging.error(f"User not found for sid {sid}")
return

if user.room is None:
logging.error(f"User {sid} is not associated with any room")
return

user.room.submitted = True

try:
await sio.emit(Events.CODE_SUBMITTED, None, room=user.room.id, skip_sid=sid)
logging.debug(f"Emitted CODE_SUBMITTED to room {user.room.id}")
except Exception as e:
logging.error(f"Failed to emit CODE_SUBMITTED for user {sid}: {e}")

await sio.disconnect(sid);


@sio.event
async def disconnect(sid):
Expand All @@ -181,7 +204,7 @@ async def disconnect(sid):

room_still_exists = room.remove_user(user)

if room_still_exists:
if room_still_exists and not room.submitted:
try:
await sio.emit(Events.USER_LEFT, user.details(), room=room.id)
logging.debug(f"Emitted USER_LEFT to room {room.id}")
Expand Down
127 changes: 37 additions & 90 deletions backend/matching-service/src/matchingService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ const DELAY_TIME = 30000;
const CONFIRM_DELAY_TIME = 10000;
const RELAX_CONSTRAINT_DELAY = 10000;

export async function handleMatchingRequest(
userRequest: any,
socketId: string
) {
export async function handleMatchingRequest(userRequest: any, socketId: string) {
userRequest.socketId = socketId;

addUserToQueue(userRequest);
Expand All @@ -39,10 +36,7 @@ function sendConfirmDelayedTimeoutMessage(recordId: string) {
},
CONFIRM_DELAY_TIME
);
console.log(
"Sent delayed message for confirm timeout for recordId: ",
recordId
);
console.log("Sent delayed message for confirm timeout for recordId: ", recordId);
}

function sendRelaxConstraintsMessage(userRequest: any) {
Expand All @@ -51,9 +45,7 @@ function sendRelaxConstraintsMessage(userRequest: any) {
console.log("Scheduled to relax constraints for user:", userRequest.userId);
}

export async function handleUserRequestWithRelaxedConstraints(
userRequest: any
) {
export async function handleUserRequestWithRelaxedConstraints(userRequest: any) {
const { userId, topic, difficulty } = userRequest;

const user = await prisma.matchRecord.findFirst({
Expand All @@ -66,9 +58,7 @@ export async function handleUserRequestWithRelaxedConstraints(
data: { constraintsRelaxed: true },
});
} else {
console.error(
`No match record found for user ${userId} during relaxed constraints matching`
);
console.error(`No match record found for user ${userId} during relaxed constraints matching`);
return;
}

Expand Down Expand Up @@ -148,9 +138,7 @@ export async function handleUserRequestWithRelaxedConstraints(
},
});
} else {
console.error(
`No match record found for user ${userId} during relaxed constraints matching`
);
console.error(`No match record found for user ${userId} during relaxed constraints matching`);
return;
}

Expand All @@ -169,15 +157,11 @@ export async function handleUserRequestWithRelaxedConstraints(
sendConfirmDelayedTimeoutMessage(currentUserRecord.recordId.toString());
sendConfirmDelayedTimeoutMessage(existingMatch.recordId.toString());
} else {
console.log(
`No match found for ${userId} after relaxing constraints, waiting for future matches`
);
console.log(`No match found for ${userId} after relaxing constraints, waiting for future matches`);
}
}

export async function handleUserRequestWithoutRelaxedConstraints(
userRequest: any
) {
export async function handleUserRequestWithoutRelaxedConstraints(userRequest: any) {
const { userId, topic, difficulty, socketId } = userRequest;

// Check if user already has a match record
Expand Down Expand Up @@ -300,13 +284,9 @@ export async function handleUserRequestWithoutRelaxedConstraints(

io.to(socketId).emit("matched", {
matchedWith: existingMatch.userId,
roomNumber,
questionId: question.questionId,
});
io.to(existingMatch.socketId).emit("matched", {
matchedWith: userId,
roomNumber,
questionId: question.questionId,
});

// Add confirm timeout messages
Expand All @@ -315,9 +295,7 @@ export async function handleUserRequestWithoutRelaxedConstraints(
} else {
// No match found
// Add user to match record and schedule constraint relaxation
console.log(
`No match found for ${userId}, added to record and scheduling constraint relaxation`
);
console.log(`No match found for ${userId}, added to record and scheduling constraint relaxation`);
await addOrUpdateMatchRecord(userRequest);
sendRelaxConstraintsMessage(userRequest);
}
Expand Down Expand Up @@ -372,20 +350,14 @@ export async function handleMatchingConfirm(userRequest: any) {
where: { recordId: matchedRecord.recordId },
data: { isArchived: true },
});
io.to(matchedRecord.socketId).emit(
"other_declined",
"Match not confirmed. Please try again."
);
io.to(matchedRecord.socketId).emit("other_declined", "Match not confirmed. Please try again.");
}
if (userRecord !== null) {
await prisma.matchRecord.update({
where: { recordId: userRecord.recordId },
data: { isArchived: true },
});
io.to(userRecord.socketId).emit(
"other_declined",
"Match not confirmed. Please try again."
);
io.to(userRecord.socketId).emit("other_declined", "Match not confirmed. Please try again.");
}
return;
}
Expand Down Expand Up @@ -413,33 +385,34 @@ export async function handleMatchingConfirm(userRequest: any) {
where: { recordId: userRecord.recordId },
data: { isArchived: true },
});

// Set roomNumber and questionId in this session
// Currently: use data from matchedRecord, i.e. user who confirmed first
const roomNumber = matchedRecord.roomNumber;
const questionId = matchedRecord.questionId ?? userRecord.questionId ?? 1;

await prisma.sessionHistory.create({
data: {
roomNumber: matchedRecord.roomNumber,
questionId: matchedRecord.questionId ?? userRecord.questionId ?? 0,
roomNumber: roomNumber,
questionId: questionId,
isOngoing: true,
userOneId: userRecord.userId,
userTwoId: matchedRecord.userId,
},
});

io.to(userRecord.socketId).emit(
"matching_success",
"Match confirmed. Proceeding to collaboration service."
);
io.to(matchedRecord.socketId).emit(
"matching_success",
"Match confirmed. Proceeding to collaboration service."
);
io.to(userRecord.socketId).emit("matching_success", {
roomNumber,
questionId,
});
io.to(matchedRecord.socketId).emit("matching_success", {
roomNumber,
questionId,
});
// TODO: add further logic here to proceed to collaboration service
} else {
console.log(
`User ${userId} confirmed match, waiting for other user to confirm`
);
io.to(matchedRecord.socketId).emit(
"other_accepted",
"Other user confirmed match. Please confirm."
);
console.log(`User ${userId} confirmed match, waiting for other user to confirm`);
io.to(matchedRecord.socketId).emit("other_accepted", "Other user confirmed match. Please confirm.");
}
}

Expand All @@ -460,28 +433,16 @@ export async function handleMatchingDecline(userRequest: any) {
where: { recordId: matchedRecord.recordId },
data: { isArchived: true },
});
io.to(matchedRecord.socketId).emit(
"other_declined",
"Match not confirmed. Please try again."
);
io.to(matchedRecord.socketId).emit(
"matching_fail",
"Match not confirmed. Please try again."
);
io.to(matchedRecord.socketId).emit("other_declined", "Match not confirmed. Please try again.");
io.to(matchedRecord.socketId).emit("matching_fail", "Match not confirmed. Please try again.");
}
if (userRecord !== null) {
await prisma.matchRecord.update({
where: { recordId: userRecord.recordId },
data: { isArchived: true },
});
io.to(userRecord.socketId).emit(
"other_declined",
"Match not confirmed. Please try again."
);
io.to(userRecord.socketId).emit(
"matching_fail",
"Match not confirmed. Please try again."
);
io.to(userRecord.socketId).emit("other_declined", "Match not confirmed. Please try again.");
io.to(userRecord.socketId).emit("matching_fail", "Match not confirmed. Please try again.");
}

return;
Expand All @@ -494,23 +455,14 @@ export async function handleMatchingDecline(userRequest: any) {

// user decline, match failed regardless
console.log(`User ${userId} declined match`);
io.to(matchedRecord.socketId).emit(
"other_declined",
"Match not confirmed. Please try again."
);
io.to(matchedRecord.socketId).emit("other_declined", "Match not confirmed. Please try again.");
await prisma.matchRecord.update({
where: { recordId: matchedRecord.recordId },
data: { isArchived: true },
});

io.to(userRecord.socketId).emit(
"matching_fail",
"Match not confirmed. Please try again."
);
io.to(matchedRecord.socketId).emit(
"matching_fail",
"Match not confirmed. Please try again."
);
io.to(userRecord.socketId).emit("matching_fail", "Match not confirmed. Please try again.");
io.to(matchedRecord.socketId).emit("matching_fail", "Match not confirmed. Please try again.");
}

export async function handleTimeout(userRequest: any) {
Expand Down Expand Up @@ -541,18 +493,13 @@ export async function handleConfirmTimeout(recordId: string) {
console.log(`Timeout: Confirm timeout for recordId ${recordId}`);
if (result !== null && !result.isArchived) {
if (result.isConfirmed === false) {
console.log(
`Timeout: Match not confirmed for recordId ${recordId} with userId ${result.userId}`
);
console.log(`Timeout: Match not confirmed for recordId ${recordId} with userId ${result.userId}`);
} else {
console.log(
`Timeout: Match confirmed for recordId ${recordId} with userId ${result.userId} but other user did not confirm`
);
}
io.to(result.socketId).emit(
"matching_fail",
"Match not confirmed. Please try again."
);
io.to(result.socketId).emit("matching_fail", "Match not confirmed. Please try again.");
await prisma.matchRecord.update({
where: { recordId: recordIdInt },
data: { isArchived: true },
Expand Down
62 changes: 62 additions & 0 deletions frontend/src/components/CodeContainer/CodeContainer.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.CodeContainer {
display: flex;

.left-side {
flex: 0.4;
padding: 10px;
color: #fff;
display: flex;
flex-direction: column;

.md-editor {
background-color: #1e1e1e;
border-radius: 10px;
border: 1px solid #3c3c3c;
padding: 20px;
color: #fff;
height: 500px;
overflow: auto;
}
}

.right-side {
flex: 0.6;
padding: 10px;
color: #fff;
display: flex;
flex-direction: column;

.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;

.language-select {
background-color: #1e1e1e;
color: #fff;
border: 1px solid #3c3c3c;
padding: 5px;
border-radius: 5px;
}

.submit-button {
background-color: #caff33;
color: #121212;
border-radius: 5px;

&.disabled {
color: #6c757d;
}
}
}

.code-editor {
background-color: #1e1e1e;
border-radius: 10px;
border: 1px solid #3c3c3c;
color: #fff;
overflow: hidden;
}
}
}
Loading
Loading