Skip to content

Conversation

@zpChris
Copy link
Contributor

@zpChris zpChris commented Jun 30, 2021

List of Changes:

  • Add createGameReport method within the GameManagementService.
  • Trigger the creation of the game report through CreateGameReportTask one minute after the game ends (to ensure all submissions are recorded).
  • Update the deleteProblem method to remove all room_problems and problem_containers references.
  • Add tests for the CreateGameReportTask.
  • Add two service tests (one large test) for the createGameReport method.

Notes:

  • Should I add a test within GameTests.java to check that the game report is created, or are the service and task tests enough @alankbi?
  • The game report save functionality is set to run a minute after the game ends - this is because a submission could run immediately after the game ends and take up to forty-five seconds to see a response. I rounded that time up to a minute, and created a timer task to wait that amount of time before calling createGameReport.
    • Note: The Tester repository does not allow a method to run longer than ten seconds, whereas the main repository only times out the method after forty-five seconds. I think it'd make sense to change one of those values, either allow the method to run longer or have the method time-out sooner - I could potentially then create the game report faster, which could be nice as it'd allow the teacher to go immediately from the results page to the game report after it loads. (There could be a loading bar at the top that would approximate how long that process takes.) Thoughts?
  • The deleteProblem method can now take a very long time, depending on the references in the room_problems table (the selected problems in rooms) and the references with the problem_containers (the problem with statistics in the game report). Let me know if you think we should give some sort of ongoing progress update on the frontend, or just a note that the delete process will take a while, or if we should just redirect them immediately.

Screencast and Images:

Screencast of Create Game Report in Database

New Database Model with Game Report
New Database Model with Game Report

zpChris added 30 commits June 17, 2021 17:38
@alankbi
Copy link
Contributor

alankbi commented Jul 7, 2021

Looks like there are some commit issues similar to what was on #174 so I'll hold off on reviewing for now - however, after #172 was merged those commit issues went away for #174 so I'd imagine this will get resolved pretty quickly (as soon as #174 is merged)

@zpChris
Copy link
Contributor Author

zpChris commented Jul 8, 2021

Looks like there are some commit issues similar to what was on #174 so I'll hold off on reviewing for now - however, after #172 was merged those commit issues went away for #174 so I'd imagine this will get resolved pretty quickly (as soon as #174 is merged)

I'll resolve all the merge conflicts at once after #174 is merged, since I just approved that and #178.

Base automatically changed from MultiProblemUI to main July 9, 2021 03:25
@alankbi
Copy link
Contributor

alankbi commented Jul 9, 2021

Looks like the commits are fixed, but maybe not the line numbers 😮 hopefully a merge will fix that tho, in which case will try to review this quickly (sorry for the delay)

Copy link
Contributor

@alankbi alankbi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a quick look, this looks great! Just leaving some preliminary comments since the bulk of changes seem to be in the GameManagementService file, and that way once you fix the merge conflicts/lines changed hopefully you won't be completely blocked waiting on a review

createGameReportTimer.schedule(createGameReportTask, GameTimer.DURATION_1 * 1000);
}

public GameReport createGameReport(Game game) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: move this + other report logic into a new ReportService

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good - done! ✅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I created the new ReportService class, I also created the new ReportServiceTests class; in the original tests, I also used a Spy for GameManagementService not just for the createGameReport method, but also to add submissions and add the game from the room. Is it ok that I have Spy objects for both GameManagementService and ReportService within that file, or should I find some workaround?

(I ask because this change makes the ReportServiceTests dependent not only on ReportService, but also on the GameManagementService - so it's not entirely isolated, but the work to get there may be large.) Thoughts @alankbi?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this cause any issues? Never tried that before, but I guess if it works then it hopefully shouldn't be an issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't cause any issues, just makes the code styling arguably a bit worse. In the interest of keeping progress moving given how long this PR has been out, I'll merge this change in though, if that's alright. 👍

numTestCases += problem.getTestCases().size();

ProblemContainer problemContainer = new ProblemContainer();
problemContainer.setProblem(problem);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will happen if a problem is deleted in the middle of a game? I believe the problem will still exist in the game object since it's in the backend, but what will happen here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point! You're right - I believe the problem will still exist in the game object, but it will not exist in the database. The following error thus exists.

Problem Deleted During Game
Problem Deleted During Game

I therefore want to make the change to check if the problem does not exist in the database, then I want to set the problem within the ProblemContainer as null. I'm adding this, and I'm also going to do this right before I save the game report.

There is still a chance, I believe, that while looping through the problems, one of the problems is deleted after it is already visited. I'm not sure what to do about conflicts like this - I think that relates to the issue we've had elsewhere of simultaneous SQL updates.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will note that after I implemented this change, it worked, but still produced the below error in the Terminal; I'm not sure whether this is something that I should be concerned about or not.

Terminal Problem Not Found Error
Terminal Problem Not Found Error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this error still happen? If so, I wonder if it has to do with one of the timer tasks not canceling properly? If it doesn't affect anything then should hopefully be fine, assuming that it only shows up in the edge case of deleting a problem

@zpChris zpChris requested a review from alankbi August 2, 2021 01:13
Copy link
Contributor

@alankbi alankbi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Mainly just left a few questions here and there. Also, another potential suggestion would be to add a new README under model/report diagraming/explaining how all the report model classes fit together (since it can be confusing), but not a huge deal

private List<SubmissionGroupReport> submissionGroupReports = new ArrayList<>();

public void addSubmissionGroupReport(SubmissionGroupReport submissionGroupReport) {
submissionGroupReports.add(submissionGroupReport);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to double-check, this isn't included in the UserDto right? Since it's only used for the report related stuff?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right - this is not included in the standard UserDto class, nor will I add it there. I don't yet have a GameReportDto class as I've been working in the backend thus far, but I will add that at some point - I'll make another DTO class for the User object specifically for the report purposes, so it is only passed to the frontend when necessary.

for (ProblemContainer problemContainer : problemContainers) {
problemContainer.setProblem(null);
problemContainerRepository.save(problemContainer);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How long does this take to run? I can imagine at some point in the future we might need ways to optimize this process it if takes too long

Copy link
Contributor Author

@zpChris zpChris Aug 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, this can take a very long time - I agree, some method to optimize this would be very useful. This is especially a problem because after clicking the "Delete Problem" button, the page does not redirect until the REST call returns. I think we could address this issue in a future PR, though I'll leave a few ideas here (not mutually exclusive):

  1. Add a boolean deletionInProgress field that allows us to show a notice that the problem is currently being deleted on the frontend.
  2. Redirect immediately after the call is made rather than waiting for the return.
  3. Have the function return success if it parses through everything, even if it has not finished deleting the problem - this may require having the for loop above continue in a separate thread or something, which I'm fairly certain is possible though I don't know how that would really work.
  4. Somehow speed up the actual deletion process.
  5. Remove the problem relation and replace it with a problemId, then simply replace those with null whenever a reference is attempted and not found.

}
}

// TODO: Will this be an issue if the submission is not actually counted? Should I return null in that case?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure - if I remember correctly this value isn't sent via socket to the frontend right? If so (if it's just the game to being sent), then I'm guessing this should be fine, but idk

room.addUser(user4);
room.setHost(user1);
Problem problem1 = TestFields.problem1();
Problem problem2 = TestFields.problem2();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add these to TestFields as user1, user2, etc. and also potentially a room1 method (if this room is good enough to be reused in other tests)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants