Index: lams_common/src/java/org/lamsfoundation/lams/web/controller/AbstractTimeLimitWebsocketServer.java =================================================================== diff -u -r2bc8f0c2f65f02cb65aa7e90d0bbb612494a4588 -r307d08b374afefb264a041667fcbeaee2b58e44c --- lams_common/src/java/org/lamsfoundation/lams/web/controller/AbstractTimeLimitWebsocketServer.java (.../AbstractTimeLimitWebsocketServer.java) (revision 2bc8f0c2f65f02cb65aa7e90d0bbb612494a4588) +++ lams_common/src/java/org/lamsfoundation/lams/web/controller/AbstractTimeLimitWebsocketServer.java (.../AbstractTimeLimitWebsocketServer.java) (revision 307d08b374afefb264a041667fcbeaee2b58e44c) @@ -1,41 +1,34 @@ package org.lamsfoundation.lams.web.controller; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.usermanagement.User; +import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; +import org.lamsfoundation.lams.util.hibernate.HibernateSessionManager; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +import javax.websocket.CloseReason; +import javax.websocket.CloseReason.CloseCodes; +import javax.websocket.OnClose; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpointConfig; import java.io.IOException; import java.lang.reflect.Method; import java.time.Duration; import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import javax.websocket.CloseReason; -import javax.websocket.CloseReason.CloseCodes; -import javax.websocket.OnClose; -import javax.websocket.OnOpen; -import javax.websocket.Session; -import javax.websocket.server.ServerEndpointConfig; - -import org.apache.log4j.Logger; -import org.lamsfoundation.lams.usermanagement.User; -import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; -import org.lamsfoundation.lams.util.hibernate.HibernateSessionManager; -import org.lamsfoundation.lams.web.session.SessionManager; -import org.lamsfoundation.lams.web.util.AttributeNames; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.WebApplicationContextUtils; - -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; - /** * Controls activity time limits. Can be used in tools to set relative and absolute time limits for learners. * @@ -109,7 +102,9 @@ // do nothing as server is probably shutting down and we could not obtain Hibernate session } catch (Exception e) { // error caught, but carry on - log.error("Error in Assessment worker thread", e); + log.error("Error in time limit worker thread", e); + // extra details for debugging + e.printStackTrace(); } finally { HibernateSessionManager.closeSession(); } @@ -172,7 +167,7 @@ */ protected boolean processActivity(long toolContentId, Collection websockets) throws IOException { // if all learners left the activity, remove the obsolete mapping - if (websockets.isEmpty()) { + if (websockets == null || websockets.isEmpty()) { timeCaches.remove(toolContentId); return false; } @@ -185,7 +180,8 @@ } // get only currently active users, not all activity participants - Collection userIds = websockets.stream().filter(w -> w.getUserProperties() != null) + Collection userIds = websockets.stream() + .filter(w -> w.getUserProperties() != null && w.getUserProperties().get("userId") != null) .collect(Collectors.mapping(w -> (Integer) w.getUserProperties().get("userId"), Collectors.toSet())); // get activity data from DB TimeCache existingTimeSettings = getExistingTimeSettings(toolContentId, userIds); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningWebsocketServer.java =================================================================== diff -u -r78cd74a85c22416138e9dd68dfb7e246c29b4c35 -r307d08b374afefb264a041667fcbeaee2b58e44c --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningWebsocketServer.java (.../LearningWebsocketServer.java) (revision 78cd74a85c22416138e9dd68dfb7e246c29b4c35) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningWebsocketServer.java (.../LearningWebsocketServer.java) (revision 307d08b374afefb264a041667fcbeaee2b58e44c) @@ -52,8 +52,9 @@ return existingTimeSettings; } - existingTimeSettings.absoluteTimeLimit = assessment.getAbsoluteTimeLimit(); + existingTimeSettings.absoluteTimeLimitFinish = assessment.getAbsoluteTimeLimitFinish(); existingTimeSettings.relativeTimeLimit = assessment.getRelativeTimeLimit() * 60; + existingTimeSettings.absoluteTimeLimit = assessment.getAbsoluteTimeLimit() * 60; existingTimeSettings.timeLimitAdjustment = assessment.getTimeLimitAdjustments(); if (userIds != null) { @@ -86,6 +87,9 @@ return assessmentService.launchTimeLimit(toolContentId, userId); } + /** + * Fetches or creates a singleton of this websocket server. + */ public static LearningWebsocketServer getInstance() { LearningWebsocketServer result = (LearningWebsocketServer) AbstractTimeLimitWebsocketServer.getInstance( LearningWebsocketServer.class.getName()); @@ -96,9 +100,6 @@ return result; } - /** - * Fetches or creates a singleton of this websocket server. - */ public static Long getSecondsLeft(long toolContentId, int userId) { LearningWebsocketServer instance = LearningWebsocketServer.getInstance(); return AbstractTimeLimitWebsocketServer.getSecondsLeft(instance, toolContentId, userId, true);