Skip to content
Snippets Groups Projects
Commit 67df36cc authored by srosse's avatar srosse
Browse files

Merge remote-tracking branch 'origin/OpenOLAT_15.0'

parents d391cf6f 052b78ee
No related branches found
No related tags found
No related merge requests found
......@@ -95,6 +95,17 @@ public interface QTI21Service {
public URI createAssessmentTestUri(File resourceDirectory);
/**
* Ensure the assessment test is cached and not expired by
* the max. idle configuration. The goal is to maintain the
* object in cache despite it to be strong reference by the
* run controller.
*
* @param resourceDirectory The directory where is the package
*/
public void touchCachedResolveAssessmentTest(File resourceDirectory);
/**
* Load the assessmentTest based on the imsmanifest.xml found in the resource
* directory. Return null if the imsmanifest.xml is not found. The assessmentTest
......
......@@ -329,6 +329,14 @@ public class QTI21ServiceImpl implements QTI21Service, UserDataDeletable, Initia
return testSessionDao.hasActiveTestSession(testEntry);
}
@Override
public void touchCachedResolveAssessmentTest(File resourceDirectory) {
URI assessmentObjectSystemId = createAssessmentTestUri(resourceDirectory);
if(assessmentObjectSystemId != null) {
assessmentTestsCache.get(resourceDirectory);
}
}
@Override
public ResolvedAssessmentTest loadAndResolveAssessmentTest(File resourceDirectory, boolean replace, boolean debugInfo) {
URI assessmentObjectSystemId = createAssessmentTestUri(resourceDirectory);
......@@ -416,7 +424,7 @@ public class QTI21ServiceImpl implements QTI21Service, UserDataDeletable, Initia
public URI createAssessmentTestUri(final File resourceDirectory) {
final String key = resourceDirectory.getAbsolutePath();
try {
return resourceToTestURI.computeIfAbsent(key, (directoryAbsolutPath) -> {
return resourceToTestURI.computeIfAbsent(key, directoryAbsolutPath -> {
File manifestPath = new File(resourceDirectory, "imsmanifest.xml");
QTI21ContentPackage cp = new QTI21ContentPackage(manifestPath.toPath());
try {
......
......@@ -178,6 +178,7 @@ public class AssessmentTestDisplayController extends BasicController implements
private DialogBoxController confirmSuspendDialog;
private CandidateEvent lastEvent;
private Date touchTimestamp;
private Date currentRequestTimestamp;
private AssessmentTestSession candidateSession;
private ResolvedAssessmentTest resolvedAssessmentTest;
......@@ -255,6 +256,7 @@ public class AssessmentTestDisplayController extends BasicController implements
FileResourceManager frm = FileResourceManager.getInstance();
fUnzippedDirRoot = frm.unzipFileResource(testEntry.getOlatResource());
resolvedAssessmentTest = qtiService.loadAndResolveAssessmentTest(fUnzippedDirRoot, false, false);
touchTimestamp = ureq.getRequestTimestamp();
if(resolvedAssessmentTest == null || resolvedAssessmentTest.getRootNodeLookup().extractIfSuccessful() == null) {
mainVC = createVelocityContainer("error");
} else {
......@@ -630,6 +632,28 @@ public class AssessmentTestDisplayController extends BasicController implements
return sessionDeleted;
}
/**
* This method maintains the assessment test in cache during
* a test session. This controller doesn't need the cache, the
* test is strong referenced but at the end of the test, score
* evaluation of the course, rendering of the assessment result
* can need the cache again. For very large tests, it can be a
* performance issue.
*
* @param ureq The user request
*/
private void touchResolvedAssessmentTest(UserRequest ureq) {
try {
Date timestamp = ureq.getRequestTimestamp();
if(touchTimestamp == null || (timestamp.getTime() > touchTimestamp.getTime() + 300000l)) {
touchTimestamp = timestamp;
qtiService.touchCachedResolveAssessmentTest(fUnzippedDirRoot);
}
} catch (Exception e) {
logError("", e);
}
}
private boolean timeLimitBarrier(UserRequest ureq) {
Long assessmentTestMaxTimeLimits = getAssessmentTestMaxTimeLimit();
if(assessmentTestMaxTimeLimits != null) {
......@@ -796,6 +820,8 @@ public class AssessmentTestDisplayController extends BasicController implements
restartTest(ureq);
break;
}
touchResolvedAssessmentTest(ureq);
}
private void restartTest(UserRequest ureq) {
......
......@@ -11,7 +11,7 @@ adobeconnect.module.enabled.for.groups=Gruppen
adobeconnect.module.provider=Provider
adobeconnect.title=Adobe Connect
check=Serververbindung testen
confirm.delete.meeting=Wollen Sie wirklich den Meeting "{0}" l\u00F6schen?
confirm.delete.meeting=Wollen Sie wirklich das Meeting "{0}" l\u00F6schen?
confirm.delete.meeting.title=Meeting "{0}" l\u00F6schen
connection.failed=Login fehlgeschlagen.
connection.successful=Login erfolgreich\!
......@@ -86,6 +86,6 @@ option.single.meeting=Verteilte Meetings
option.single.meeting.single=Erstellt nur ein Meeting Raum pro Kursbaustein oder Gruppe
option.single.meeting.perdate=Erstellt ein Meeting Raum pro Datum
table.header.permanent=Dauernd
warning.no.access=Sie k\u00F6nnen noch nicht den Meeting beitreten.
warning.no.access=Sie k\u00F6nnen noch nicht dem Meeting beitreten.
warning.no.meeting=Das Meeting wurde gel\u00F6scht.
warning.not.registered.shared.documents=Nur die Personen die sich an den Meeting angemeldet haben d\u00FCrfen die Dokumenten ansehen.
......@@ -187,7 +187,7 @@ view.template=Raumvorlage "{0}"
warning.at.least.one.meeting=Sie m\u00FCssen mindestens ein Meeting w\u00E4hlen.
warning.meeting.permission.denied=Sie haben nicht die Berechtigung den Meeting beizutreten.
warning.meeting.started=Sie k\u00F6nnen ein gestartetes Meeting nicht mehr bearbeiten.
warning.no.access=Sie k\u00F6nnen noch nicht den Meeting beitreten.
warning.no.access=Sie k\u00F6nnen noch nicht dem Meeting beitreten.
warning.no.meeting=Das Meeting wurde gel\u00F6scht.
warning.template.in.use=Die Raumvorlage kann nicht gel\u00F6scht werden da sie nocht benutzt wird. L\u00F6schschen Sie zuerst die entsprechenden Online-Termine oder deaktivieren Sie die Raumvorlage.
wizard.dates.title=Datum
......
......@@ -63,6 +63,24 @@
<expiration max-idle="180000" interval="15000" />
</local-cache>
<local-cache name="QTIWorks@assessmentTests" simple-cache="true" statistics="true" statistics-available="true">
<locking isolation="READ_COMMITTED" concurrency-level="1000" acquire-timeout="15000" striping="false" />
<transaction mode="NONE" auto-commit="true" />
<memory>
<object size="200" strategy="REMOVE" />
</memory>
<expiration max-idle="900000" interval="15000" />
</local-cache>
<local-cache name="QTIWorks@xsltStylesheets" simple-cache="true" statistics="true" statistics-available="true">
<locking isolation="READ_COMMITTED" concurrency-level="1000" acquire-timeout="15000" striping="false" />
<transaction mode="NONE" auto-commit="true" />
<memory>
<object size="200" strategy="REMOVE" />
</memory>
<expiration max-idle="1800000" interval="15000" />
</local-cache>
<local-cache name="WebDAVManager@webdav" simple-cache="true" statistics="true" statistics-available="true">
<locking isolation="READ_COMMITTED" concurrency-level="1000" acquire-timeout="15000" striping="false" />
<transaction mode="NONE" auto-commit="true" />
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment