added some cleanup after exam finished

This commit is contained in:
anhefti 2022-03-23 12:31:56 +01:00
parent c53336f1d4
commit 9cc020712a
5 changed files with 63 additions and 0 deletions

View file

@ -15,6 +15,7 @@ import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ClientConnectionRecord;
@ -180,4 +181,10 @@ public interface ClientConnectionDAO extends
* @return Result refer to the relevant VDI pair connection if exists or to an error if not */
Result<ClientConnectionRecord> getVDIPairCompanion(Long examId, String clientName);
/** Deletes all client indicator value entries within the client_indicator table for a given exam.
*
* @param exam the Exam to delete all currently registered indicator value entries
* @return Result refer to the given Exam or to an error when happened. */
Result<Exam> deleteClientIndicatorValues(Exam exam);
}

View file

@ -32,6 +32,7 @@ import ch.ethz.seb.sebserver.gbl.api.API.BulkActionType;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.EntityDependency;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
@ -694,6 +695,33 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO {
});
}
@Override
@Transactional
public Result<Exam> deleteClientIndicatorValues(final Exam exam) {
return Result.tryCatch(() -> {
final List<Long> clientConnections = this.clientConnectionRecordMapper.selectIdsByExample()
.where(
ClientConnectionRecordDynamicSqlSupport.examId,
SqlBuilder.isEqualTo(exam.id))
.build()
.execute();
if (clientConnections == null || clientConnections.isEmpty()) {
return exam;
}
this.clientIndicatorRecordMapper.deleteByExample()
.where(
ClientIndicatorRecordDynamicSqlSupport.clientConnectionId,
SqlBuilder.isIn(clientConnections))
.build()
.execute();
return exam;
});
}
private Result<ClientConnectionRecord> recordById(final Long id) {
return Result.tryCatch(() -> {

View file

@ -182,6 +182,13 @@ public interface ExamSessionService {
* @return Result refer to the collection of connection tokens or to an error when happened. */
Result<Collection<String>> getActiveConnectionTokens(Long examId);
/** Called to notify that the given exam has just been finished.
* This cleanup all exam session caches for the given exam and also cleanup session based stores on the persistent.
*
* @param exam the Exam that has just been finished
* @return Result refer to the finished exam or to an error when happened. */
Result<Exam> notifyExamFinished(final Exam exam);
/** Use this to check if the current cached running exam is up to date
* and if not to flush the cache.
*

View file

@ -29,6 +29,7 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamProctoringRoomService;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientConnectionService;
@Service
@ -42,6 +43,7 @@ public class ExamSessionControlTask implements DisposableBean {
private final ExamUpdateHandler examUpdateHandler;
private final ExamProctoringRoomService examProcotringRoomService;
private final WebserviceInfo webserviceInfo;
private final ExamSessionService examSessionService;
private final Long examTimePrefix;
private final Long examTimeSuffix;
@ -54,6 +56,7 @@ public class ExamSessionControlTask implements DisposableBean {
final ExamUpdateHandler examUpdateHandler,
final ExamProctoringRoomService examProcotringRoomService,
final WebserviceInfo webserviceInfo,
final ExamSessionService examSessionService,
@Value("${sebserver.webservice.api.exam.time-prefix:3600000}") final Long examTimePrefix,
@Value("${sebserver.webservice.api.exam.time-suffix:3600000}") final Long examTimeSuffix,
@Value("${sebserver.webservice.api.exam.update-interval:1 * * * * *}") final String examTaskCron,
@ -63,6 +66,7 @@ public class ExamSessionControlTask implements DisposableBean {
this.sebClientConnectionService = sebClientConnectionService;
this.examUpdateHandler = examUpdateHandler;
this.webserviceInfo = webserviceInfo;
this.examSessionService = examSessionService;
this.examTimePrefix = examTimePrefix;
this.examTimeSuffix = examTimeSuffix;
this.examTaskCron = examTaskCron;
@ -185,6 +189,7 @@ public class ExamSessionControlTask implements DisposableBean {
.filter(exam -> exam.endTime != null && exam.endTime.plus(this.examTimeSuffix).isBefore(now))
.flatMap(exam -> Result.skipOnError(this.examUpdateHandler.setFinished(exam, updateId)))
.flatMap(exam -> Result.skipOnError(this.examProcotringRoomService.disposeRoomsForExam(exam)))
.flatMap(exam -> Result.skipOnError(this.examSessionService.notifyExamFinished(exam)))
.collect(Collectors.toMap(Exam::getId, Exam::getName));
if (!updated.isEmpty()) {

View file

@ -393,6 +393,22 @@ public class ExamSessionServiceImpl implements ExamSessionService {
.getActiveConnctionTokens(examId);
}
@Override
public Result<Exam> notifyExamFinished(final Exam exam) {
return Result.tryCatch(() -> {
if (!isExamRunning(exam.id)) {
this.flushCache(exam);
if (this.distributedSetup) {
this.clientConnectionDAO
.deleteClientIndicatorValues(exam)
.getOrThrow();
}
}
return exam;
});
}
@Override
public Result<Exam> updateExamCache(final Long examId) {