use of org.olat.core.util.coordinate.SyncerExecutor in project OpenOLAT by OpenOLAT.
the class InfoMessageManager method setInfoMessage.
/**
* @param message The new info message that will show up on the login screen
* Synchronized to prevent two users creating or updating the info message property
* at the same time
*/
public void setInfoMessage(final String message) {
// o_clusterOK synchronized
OLATResourceable ores = OresHelper.createOLATResourceableInstance(INFO_MSG, KEY);
coordinatorManager.getCoordinator().getSyncer().doInSync(ores, new SyncerExecutor() {
public void execute() {
PropertyManager pm = PropertyManager.getInstance();
Property p = pm.findProperty(null, null, null, "_o3_", INFO_MSG);
if (p == null) {
p = pm.createPropertyInstance(null, null, null, "_o3_", INFO_MSG, null, null, null, "");
pm.saveProperty(p);
}
p.setTextValue(message);
// set Message in RAM
InfoMessageManager.infoMessage = message;
pm.updateProperty(p);
}
});
// end syncerCallback
EventBus eb = coordinatorManager.getCoordinator().getEventBus();
MultiUserEvent mue = new MultiUserEvent(message);
eb.fireEventToListenersOf(mue, INFO_MESSAGE_ORES);
}
use of org.olat.core.util.coordinate.SyncerExecutor in project OpenOLAT by OpenOLAT.
the class EfficiencyStatementManager method updateEfficiencyStatements.
/**
* Create or update all efficiency statment lists for the given list of identities and this course
* This is called from only one thread, since the course is locked at editing (either CourseEdit or CourseDetails edit).
*
* @param ores The resource to load the course
* @param identities List of identities
* false: always create new one (be careful with this one!)
*/
public void updateEfficiencyStatements(final RepositoryEntry courseEntry, List<Identity> identities) {
if (identities.size() > 0) {
final ICourse course = CourseFactory.loadCourse(courseEntry);
log.audit("Updating efficiency statements for course::" + course.getResourceableId() + ", this might produce temporary heavy load on the CPU");
// preload cache to speed up things
AssessmentManager am = course.getCourseEnvironment().getAssessmentManager();
int count = 0;
for (Identity identity : identities) {
// o_clusterOK: by ld
OLATResourceable efficiencyStatementResourceable = am.createOLATResourceableForLocking(identity);
CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(efficiencyStatementResourceable, new SyncerExecutor() {
@Override
public void execute() {
// create temporary user course env
UserCourseEnvironment uce = AssessmentHelper.createInitAndUpdateUserCourseEnvironment(identity, course);
updateUserEfficiencyStatement(uce, courseEntry);
}
});
if (Thread.interrupted()) {
break;
}
if (++count % 10 == 0) {
DBFactory.getInstance().commitAndCloseSession();
}
}
}
}
use of org.olat.core.util.coordinate.SyncerExecutor in project OpenOLAT by OpenOLAT.
the class UserCourseInformationsManagerImpl method updateUserCourseInformations.
/**
* Update (or create if not exists) the course informations for a user
* @param userCourseEnv
* @return
*/
@Override
public void updateUserCourseInformations(final OLATResource courseResource, final Identity identity) {
int updatedRows = lowLevelUpdate(courseResource, identity);
// to make it quick
dbInstance.commit();
if (updatedRows == 0) {
OLATResourceable lockRes = OresHelper.createOLATResourceableInstance("CourseLaunchDate::Identity", identity.getKey());
CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(lockRes, new SyncerExecutor() {
@Override
public void execute() {
try {
int retryUpdatedRows = lowLevelUpdate(courseResource, identity);
if (retryUpdatedRows == 0) {
UserCourseInfosImpl infos = new UserCourseInfosImpl();
infos.setIdentity(identity);
infos.setCreationDate(new Date());
infos.setInitialLaunch(new Date());
infos.setLastModified(new Date());
infos.setRecentLaunch(new Date());
infos.setVisit(1);
infos.setResource(courseResource);
dbInstance.getCurrentEntityManager().persist(infos);
}
} catch (Exception e) {
log.error("Cannot update course informations for: " + identity + " from " + identity, e);
}
}
});
}
}
use of org.olat.core.util.coordinate.SyncerExecutor in project openolat by klemens.
the class CoordinatorTest method testDoInSyncPerformance.
@Test
public void testDoInSyncPerformance() {
final OLATResourceable ores = OresHelper.createOLATResourceableInstance(UUID.randomUUID().toString(), new Long("123989456"));
OLATResource r = CoreSpringFactory.getImpl(OLATResourceManager.class).findOrPersistResourceable(ores);
int maxLoop = 500;
final RepositoryEntry re = repositoryService.create("test", "perfTest", "testPerf", "perfTest description", r);
// create security group
repositoryService.update(re);
DBFactory.getInstance().commitAndCloseSession();
// 1. Do job without doInSync
log.info("testDoInSyncPerformance: start test with doInSync");
long startTimeWithoutSync = System.currentTimeMillis();
for (int i = 0; i < maxLoop; i++) {
doTestPerformanceJob(re);
DBFactory.getInstance().closeSession();
}
long endTimeWithoutSync = System.currentTimeMillis();
// 2. Do job with doInSync
log.info("testDoInSyncPerformance: start test with doInSync");
long startTimeDoInSync = System.currentTimeMillis();
for (int i = 0; i < maxLoop; i++) {
CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(ores, new SyncerExecutor() {
public void execute() {
doTestPerformanceJob(re);
}
});
// end syncerCallback
DBFactory.getInstance().closeSession();
}
long endTimeDoInSync = System.currentTimeMillis();
// Compare time
long timeWithoutSync = endTimeWithoutSync - startTimeWithoutSync;
float perJobWithoutSync = (float) timeWithoutSync / maxLoop;
log.info("testDoInSyncPerformance timeWithoutSync=" + timeWithoutSync + " ms for loop with " + maxLoop + " iterations");
log.info("testDoInSyncPerformance perJobWithoutSync=" + perJobWithoutSync + " ms");
long timeWithDoInSync = endTimeDoInSync - startTimeDoInSync;
float perJobWithDoInSync = (float) timeWithDoInSync / maxLoop;
log.info("testDoInSyncPerformance timeWithDoInSync=" + timeWithDoInSync + " ms for loop with " + maxLoop + " iterations");
log.info("testDoInSyncPerformance perJobWithDoInSync=" + perJobWithDoInSync + " ms");
long timeDiffLoop = timeWithDoInSync - timeWithoutSync;
float timeDiffPerCall = perJobWithDoInSync - perJobWithoutSync;
log.info("testDoInSyncPerformance diffLoop=" + timeDiffLoop + " ms for loop with " + maxLoop + " iterations");
log.info("testDoInSyncPerformance diffPerCall=" + timeDiffPerCall + " ms");
}
use of org.olat.core.util.coordinate.SyncerExecutor in project openolat by klemens.
the class NewCachePersistingAssessmentManager method saveNodeAttempts.
/**
* @see org.olat.course.assessment.AssessmentManager#saveNodeAttempts(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity, org.olat.core.id.Identity,
* java.lang.Integer)
*/
public void saveNodeAttempts(final CourseNode courseNode, final Identity identity, final Identity assessedIdentity, final Integer attempts) {
// A note on updating the EfficiencyStatement:
// In the equivalent method incrementNodeAttempts() in this class, the following code is executed:
// // Update users efficiency statement
// EfficiencyStatementManager esm = EfficiencyStatementManager.getInstance();
// esm.updateUserEfficiencyStatement(userCourseEnv);
// One would expect that saveNodeAttempts would also have to update the EfficiencyStatement - or
// the caller of this method would have to make sure that this happens in the same transaction.
// While this is not explicitly so, implicitly it is: currently the only user this method is
// the AssessmentEditController - which as the 2nd last method calls into saveScoreEvaluation
// - which in turn does update the EfficiencyStatement - at which point we're happy and everything works fine.
// But it seems like this mechanism is a bit unobvious and might well be worth some refactoring...
ICourse course = CourseFactory.loadCourse(ores);
final CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager();
CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(createOLATResourceableForLocking(assessedIdentity), new SyncerExecutor() {
public void execute() {
Property attemptsProperty = cpm.findCourseNodeProperty(courseNode, assessedIdentity, null, ATTEMPTS);
if (attemptsProperty == null) {
attemptsProperty = cpm.createCourseNodePropertyInstance(courseNode, assessedIdentity, null, ATTEMPTS, null, new Long(attempts.intValue()), null, null);
cpm.saveProperty(attemptsProperty);
} else {
attemptsProperty.setLongValue(new Long(attempts.intValue()));
cpm.updateProperty(attemptsProperty);
}
// add to cache
putPropertyIntoCache(assessedIdentity, attemptsProperty);
}
});
// node log
UserNodeAuditManager am = course.getCourseEnvironment().getAuditManager();
am.appendToUserNodeLog(courseNode, identity, assessedIdentity, ATTEMPTS + " set to: " + String.valueOf(attempts));
// notify about changes
AssessmentChangedEvent ace = new AssessmentChangedEvent(AssessmentChangedEvent.TYPE_ATTEMPTS_CHANGED, assessedIdentity);
CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(ace, course);
// user activity logging
ThreadLocalUserActivityLogger.log(AssessmentLoggingAction.ASSESSMENT_ATTEMPTS_UPDATED, getClass(), LoggingResourceable.wrap(assessedIdentity), LoggingResourceable.wrapNonOlatResource(StringResourceableType.qtiAttempts, "", String.valueOf(attempts)));
}
Aggregations