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

[#11402] Submission status stays as pending for team submissions #11518

Conversation

shadowezz
Copy link
Contributor

Fixes #11402

Outline of Solution

As discussed with @damithc under the issue:

  • individual questions: pending if the student has not answered any questions i.e., all questions are blank
  • team questions: pending if no team member has answered any of them
  • If a session has both types, it is considered pending if the individual questions are pending (with no consideration of team questions)

@ypinhsuan ypinhsuan self-requested a review January 11, 2022 02:13
@ypinhsuan ypinhsuan added the s.ToReview The PR is waiting for review(s) label Jan 11, 2022
Copy link
Contributor

@ypinhsuan ypinhsuan 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 overall, just some minor comments

if (allQuestions.isEmpty()) {
return true;
}
Boolean isAllTeamQuestions = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can use the primitive type boolean here

student = dataBundle.students.get("student5InCourse1");
assertFalse(fsLogic.isFeedbackSessionCompletedByStudent(fs, student.getEmail(), student.getTeam()));

______TS("success: second feedback session (both team and individual questions");
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing a close bracket questions)

Copy link
Contributor

@ypinhsuan ypinhsuan left a comment

Choose a reason for hiding this comment

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

LGTM

@madanalogy madanalogy added s.FinalReview The PR is ready for final review and removed s.ToReview The PR is waiting for review(s) labels Jan 18, 2022
Copy link
Contributor

@moziliar moziliar left a comment

Choose a reason for hiding this comment

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

Minor comments.

You can also help to deprecate fqLogic.sessionHasQuestions if you have removed the only place it is used! The old way of checking this seems irrelevant.

@@ -237,15 +238,33 @@ public boolean isFeedbackSessionHasQuestionForStudents(
*
* <p> If there is no question for students, the feedback session is completed</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be good to update the logic in the javadoc writeup:)

Comment on lines 262 to 266
return frLogic.hasGiverRespondedForSession(userTeam, feedbackSessionName, courseId);
} else {
// if there are individual questions, session is complete only if
// the student has responded to the individual questions
return frLogic.hasGiverRespondedForSession(userEmail, feedbackSessionName, courseId);
Copy link
Contributor

Choose a reason for hiding this comment

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

The userEmail param in hasGiverRespondedForSession seems overloaded with userTeam now. Do you have a better way of phrasing it?

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 think a more accurate name for userEmail param in hasGiverRespondedForSession is giverIdentifier since from what I understand, email is used for individual responses but team name is used for team responses. It will be good to probably change the giverEmail column in FeedbackResponse entity to giverIdentifier also.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds good to me. Let's see how it looks?

Copy link
Contributor

Choose a reason for hiding this comment

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

It will be good to probably change the giverEmail column in FeedbackResponse entity to giverIdentifier also.

I think this might not be backward compatible... An alternative way would be to get all students in the team and return true if at least one of the students in the team has responded for the session.

@moziliar what do you think.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh sorry, I missed out the part about changing the entity field... @jianhandev you are right. Let's keep the entity untouched. We should only touch the code logic.

Changing the userEmail param to giverIdentifier or something similar will do. The problem is minor in that a userTeam is given as userEmail param.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changing the userEmail param to giverIdentifier or something similar will do.

Ok sure

@jianhandev jianhandev added s.Ongoing The PR is being worked on by the author(s) and removed s.FinalReview The PR is ready for final review labels Jan 19, 2022
Copy link
Contributor

@moziliar moziliar left a comment

Choose a reason for hiding this comment

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

I am good with the change in code. However, the addition of entity reads makes raise my eyebrows a little. @damithc is it ok?

Comment on lines 273 to 276
@Deprecated
public boolean sessionHasQuestions(String feedbackSessionName, String courseId) {
return fqDb.hasFeedbackQuestionsForGiverType(feedbackSessionName, courseId, FeedbackParticipantType.STUDENTS)
|| fqDb.hasFeedbackQuestionsForGiverType(feedbackSessionName, courseId, FeedbackParticipantType.TEAMS);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can just remove this altogether since it is not used anywhere after this change.

String courseId = fsa.getCourseId();

List<FeedbackQuestionAttributes> allQuestions =
fqLogic.getFeedbackQuestionsForStudents(feedbackSessionName, courseId);
Copy link
Contributor

Choose a reason for hiding this comment

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

This might actually incur many data read. @damithc can we evaluate the volume of such call?
Before this change, this execution flow only performs key only queries (in frLogic.hasGiverRespondedForSession and fqLogic.sessionHasQuestions). This solution is clean if adding back entity reads will not incur any concern on the cost.
From the logs, I don't see it though. Perhaps it is about the period.

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 have refactored to only perform key-only queries.

Comment on lines 33 to 38
List<StudentAttributes> studentsToRemindList = new ArrayList<>();
for (StudentAttributes student : studentList) {
if (!logic.isFeedbackSessionCompletedByStudent(session, student.getEmail())) {
if (!logic.isFeedbackSessionCompletedByStudent(session, student.getEmail(), student.getTeam())) {
studentsToRemindList.add(student);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can try to use stream for this part of code:)

List<StudentAttributes> studentsToRemindList = studentList.stream().filter(student -> 
        !logic.isFeedbackSessionCompletedByStudent(session, student.getEmail())
);

Copy link
Contributor

Choose a reason for hiding this comment

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

Use of stream is encouraged, as it presents a cleaner, possibly immutable semantics. The use of filter means that we are getting the same set of data, possibly less, instead of potentially doing something to the data.

Comment on lines 263 to 266
if (isAllTeamQuestions) {
return frLogic.hasGiverRespondedForSession(userTeam, feedbackSessionName, courseId);
} else {
return frLogic.hasGiverRespondedForSession(userEmail, feedbackSessionName, courseId);
Copy link
Contributor

Choose a reason for hiding this comment

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

If we trace hasGiverRespondedForSession until the DB layer, in FeedbackResponseDb.java, the hasResponsesFromGiverInSession method filters the responses by giverEmail. Passing the team name to hasResponsesFromGiverInSession does not seem to make sense as giverEmail is different from team name.

public boolean hasResponsesFromGiverInSession(
String giverEmail, String feedbackSessionName, String courseId) {
assert giverEmail != null;
assert feedbackSessionName != null;
assert courseId != null;
return !load()
.filter("giverEmail =", giverEmail)
.filter("feedbackSessionName =", feedbackSessionName)
.filter("courseId =", courseId)
.limit(1)
.keys() // key query is free query
.list()
.isEmpty();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea but from what I understand for team questions, the team name is what is actually stored in the db under giverEmail, which is why I initially suggest renaming the entity field. But I do agree there will prob be backward compatibility issues.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. The entity field is unfortunately giverEmail, possibly due to legacy issue. However, FeedbackResponseAttribute class has a more neutral field called giver with brief explanation about the nature of the field. We can also put some remark in the form of comment in the FeedbackResponse class to indicate this the same way the Attribute class does.

Copy link
Contributor

Choose a reason for hiding this comment

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

The gitblame shows that the entity class is created back in 2013, and the renaming of giverEmail to giver in the Attribute class was performed in 2016 by PR #5547.

I am ok with renaming in code logic and adding comments in entity class to reflect this ambiguity.

Copy link
Contributor

@jianhandev jianhandev Jan 20, 2022

Choose a reason for hiding this comment

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

(Alternatively) we could try fetching all students in the team and for each student check if the student has responded using hasResponsesFromGiverInSession, return true if at least one of the students in the team has responded for the session, but this will incur more DB reads I believe.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea that does seem a little expensive and will require storing the student email instead of the team name for team question responses.

We can also put some remark in the form of comment in the FeedbackResponse class to indicate this the same way the Attribute class does.

Personally I think this should be sufficient for now unless we need to track which team member answered the team questions.

Copy link
Contributor

Choose a reason for hiding this comment

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

Slowly I feel like the cost might not justify the improvement of the UX as we moved away from key only query to reading many entities.

Copy link
Contributor

@moziliar moziliar left a comment

Choose a reason for hiding this comment

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

Neat. LGTM.

@moziliar moziliar added s.FinalReview The PR is ready for final review and removed s.Ongoing The PR is being worked on by the author(s) labels Jan 22, 2022
@moziliar
Copy link
Contributor

@jianhandev take a final look? Am good with the kind of additional read (1 entity max)

Copy link
Contributor

@jianhandev jianhandev left a comment

Choose a reason for hiding this comment

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

LGTM too, although you have written tests to verify that it works, which should be sufficient in this case, but it'll be even better if you can provide a few screenshots of the changes in the PR description as well.

Comment on lines +38 to 42
/**
* {@code giverEmail} does not necessarily contain an email. Depending on the question giver type,
* it may contain the giver's email, the team name, "anonymous", etc.
*/
private String giverEmail;
Copy link
Contributor

Choose a reason for hiding this comment

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

We might want to change giverEmail to giver as well in the future, but maybe not now

@madanalogy madanalogy added c.Bug Bug/defect report s.ToMerge The PR is approved by all reviewers including final reviewer; ready for merging and removed s.FinalReview The PR is ready for final review labels Jan 29, 2022
@madanalogy madanalogy added this to the V8.7.0 milestone Jan 29, 2022
@madanalogy madanalogy merged commit 55debdb into TEAMMATES:master Jan 31, 2022
FergusMok pushed a commit to ziqing26/teammates that referenced this pull request Feb 5, 2022
…ions (TEAMMATES#11518)

* Fixed team questions submission stauts bug.

* Updated tests.

* Fixed linting.

* Minor fixes.

* Add javadoc and minor refactoring.

* Refactor code to use key-only db query.

* Fix linting.

Co-authored-by: Ahmed Bahajjaj <42177597+madanalogy@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c.Bug Bug/defect report s.ToMerge The PR is approved by all reviewers including final reviewer; ready for merging
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Submission status stays as pending for team submissions
5 participants