*
* @see org.olat.course.assessment.AssessmentManager#saveScoreEvaluation(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity, org.olat.core.id.Identity, org.olat.course.run.scoring.ScoreEvaluation)
*/
public void saveScoreEvaluation(final CourseNode courseNode, final Identity identity, final Identity assessedIdentity, final ScoreEvaluation scoreEvaluation,
final UserCourseEnvironment userCourseEnv, final boolean incrementUserAttempts) {
ICourse course = CourseFactory.loadCourse(ores);
final CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager();
// o_clusterREVIEW we could sync on a element finer than course, e.g. the composite course+assessIdentity.
// +: concurrency would be higher
// -: many entries (num of courses * visitors of given course) in the locktable.
// we could also sync on the assessedIdentity.
Codepoint.codepoint(NewCachePersistingAssessmentManager.class, "beforeSyncUpdateUserEfficiencyStatement");
Long attempts = CoordinatorManager.getCoordinator().getSyncer().doInSync(createOLATResourceableForLocking(assessedIdentity), new SyncerCallback<Long>(){
public Long execute() {
Long attempts = null;
Codepoint.codepoint(NewCachePersistingAssessmentManager.class, "doInSyncUpdateUserEfficiencyStatement");
saveNodeScore(courseNode, identity, assessedIdentity, scoreEvaluation.getScore(), cpm);
saveNodePassed(courseNode, identity, assessedIdentity, scoreEvaluation.getPassed(), cpm);
saveAssessmentID(courseNode, assessedIdentity, scoreEvaluation.getAssessmentID(), cpm);
if(incrementUserAttempts) {
attempts = incrementNodeAttemptsProperty(courseNode, assessedIdentity, cpm);
}
if(courseNode instanceof AssessableCourseNode) {
userCourseEnv.getScoreAccounting().scoreInfoChanged((AssessableCourseNode)courseNode, scoreEvaluation);
// Update users efficiency statement
EfficiencyStatementManager esm = EfficiencyStatementManager.getInstance();
esm.updateUserEfficiencyStatement(userCourseEnv);
}
return attempts;
}});
// here used to be a codepoint which lead to error (OLAT-3570) in AssessmentWithCodepointsTest.
// The reason for this error was that the AuditManager appendToUserNodeLog() is not synchronized, so could be called by several threads simultaneously.
// The end effect of this error is data inconsistency: the score/passed info is stored but the userNodeLog info is not updated and the AssessmentChangedEvent is not fired.
// This case is very seldom, but could be avoided if the test could be protected by a lock.
// node log
UserNodeAuditManager am = course.getCourseEnvironment().getAuditManager();
am.appendToUserNodeLog(courseNode, identity, assessedIdentity, SCORE + " set to: " + String.valueOf(scoreEvaluation.getScore()));
if(scoreEvaluation.getPassed()!=null) {
am.appendToUserNodeLog(courseNode, identity, assessedIdentity, PASSED + " set to: " + scoreEvaluation.getPassed().toString());
} else {
am.appendToUserNodeLog(courseNode, identity, assessedIdentity, PASSED + " set to \"undefined\"");