Переглянути джерело

优化某个评测员提交任务

ting.yin 6 роки тому
батько
коміт
d75d0b21d3

+ 10 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/MarkGroup.java

@@ -60,6 +60,9 @@ public class MarkGroup implements Serializable {
 
     @Transient
     private long markerCount;
+    
+    @Transient
+    private int percent;
 
     public MarkGroup() {
         this.pk = new MarkGroupPK();
@@ -228,4 +231,11 @@ public class MarkGroup implements Serializable {
         this.currentCount = currentCount;
     }
 
+	public int getPercent() {
+		return percent;
+	}
+
+	public void setPercent(int percent) {
+		this.percent = percent;
+	}
 }

+ 13 - 2
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/TaskServiceImpl.java

@@ -6,6 +6,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
+import cn.com.qmth.stmms.biz.utils.MarkRedisUtil;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -313,7 +314,7 @@ public class TaskServiceImpl implements TaskService {
     @Override
     public void clearCurrent(Marker marker) {
         CurrentTaskUtil.clear(marker);
-    }
+    }
     
     public SpecialTagDTO [] getMarkSpecialTagList(Integer libraryId){
         SpecialTagDTO [] specialTags = null;
@@ -418,5 +419,15 @@ public class TaskServiceImpl implements TaskService {
             log.error("task submit faile", e);
             return false;
         }
-	}
+	}
+
+    /*
+     * 客户端非正常情况下退出系统时,对内存中的没有及时清除的任务进行处理
+     *
+     */
+    @Override
+    public void clearTaskMap(long cleanMapinterval) throws Exception{
+            CurrentTaskUtil.QuartzClearMap(cleanMapinterval);
+    }
+
 }

+ 3 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/TaskService.java

@@ -30,4 +30,7 @@ public interface TaskService {
 	Task build(Integer studentId);
 
 	boolean submitByStudent(Task task);
+
+    void clearTaskMap(long cleanMapinterval) throws Exception;
+
 }

+ 51 - 2
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/utils/CurrentTaskUtil.java

@@ -1,9 +1,12 @@
 package cn.com.qmth.stmms.biz.utils;
 
+import java.text.ParseException;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
 import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multiset;
 import com.google.common.collect.SetMultimap;
 
 import cn.com.qmth.stmms.biz.exam.model.Marker;
@@ -98,8 +101,7 @@ public class CurrentTaskUtil {
     /**
      * 清除某个评卷员已领取未给分的任务
      * 
-     * @param examId
-     * @param subjectCode
+     * @param marker
      */
     public static void clear(Marker marker) {
         String key = getKey(marker);
@@ -121,6 +123,50 @@ public class CurrentTaskUtil {
     private static String getKey(Marker marker) {
         return getKey(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
     }
+    public static void QuartzClearMap(long cleanMapinterval){
+        synchronized (CurrentTaskUtil.class) {
+            SetMultimap<String, TaskEntry> taskMap1 = HashMultimap.create();
+    		//System.out.println("任务池大小:"+taskMap.size());
+    		//System.out.println("间隔时间:"+cleanMapinterval);
+            if(taskMap != null && taskMap.size()>0){
+                Multiset<String> keysTemp = taskMap.keys();
+                Set <String> setKey = new HashSet<String>();
+                for(String key : keysTemp){
+                    setKey.add(key);
+                }
+                for(String key : setKey){
+                    Set<TaskEntry> set = taskMap.get(key);
+                    if (set != null) {
+                        for (TaskEntry obj : set) {
+                            if(getDateDifference(obj.timestamp)>=cleanMapinterval){//如果相隔20分钟,则该试卷的放入清空池中
+                                taskMap1.put(key, obj);
+                            }
+                        }
+                    }
+                }
+            }
+            for(Map.Entry<String, TaskEntry> taskEntry : taskMap1.entries()){
+                taskMap.remove(taskEntry.getKey(), taskEntry.getValue());
+            }
+            taskMap1.clear();
+        }
+    }
+    /**
+     * 获取当前时间戳
+     * @return
+     * @throws ParseException
+     */
+    public static  Long getDateString(){
+        return System.currentTimeMillis();
+    }
+    /**
+     * 时间戳相隔分钟
+     * @return
+     * @throws ParseException
+     */
+    public static Long getDateDifference(Long oldTime){
+        return  (getDateString() - oldTime) / (1000 * 60);
+    }
 }
 
 class TaskEntry {
@@ -129,9 +175,12 @@ class TaskEntry {
 
     int libraryId;
 
+    public long timestamp;
+
     public TaskEntry(int markerId, int libraryId) {
         this.markerId = markerId;
         this.libraryId = libraryId;
+        this.timestamp = System.currentTimeMillis();;
     }
 
     @Override

+ 29 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/utils/MarkRedisUtil.java

@@ -4,12 +4,17 @@ import org.springframework.data.redis.core.StringRedisTemplate;
 
 import cn.com.qmth.stmms.biz.exam.model.Marker;
 import cn.com.qmth.stmms.common.redis.RedisKeyBuilder;
+import org.springframework.data.redis.core.ZSetOperations;
+
+import java.util.Iterator;
+import java.util.Set;
 
 public class MarkRedisUtil {
 
     public static void addCurrentTask(StringRedisTemplate redisTemplate, Marker marker, int libraryId) {
         String key = getKey(marker);
         redisTemplate.opsForZSet().add(key, String.valueOf(libraryId), marker.getId());
+        redisTemplate.opsForZSet().add(RedisKeyBuilder.getCurrentTaskTimeKey(marker.getExamId(), marker.getSubjectCode(),marker.getNumber()),String.valueOf(libraryId),System.currentTimeMillis());
     }
 
     public static int countCurrentTask(StringRedisTemplate redisTemplate, int examId, String subjectCode, int number) {
@@ -28,6 +33,7 @@ public class MarkRedisUtil {
             int libraryId) {
         String key = RedisKeyBuilder.getCurrentTaskKey(examId, subjectCode, number);
         redisTemplate.opsForZSet().remove(key, String.valueOf(libraryId));
+        redisTemplate.opsForZSet().remove(RedisKeyBuilder.getCurrentTaskTimeKey(examId, subjectCode,number),String.valueOf(libraryId));
     }
 
     public static boolean isCurrentTask(StringRedisTemplate redisTemplate, int examId, String subjectCode, int number,
@@ -45,9 +51,32 @@ public class MarkRedisUtil {
     public static void clearCurrentTask(StringRedisTemplate redisTemplate, int examId, String subjectCode, int number) {
         String key = RedisKeyBuilder.getCurrentTaskKey(examId, subjectCode, number);
         redisTemplate.delete(key);
+        redisTemplate.delete(RedisKeyBuilder.getCurrentTaskTimeKey(examId, subjectCode,number));
     }
 
     private static String getKey(Marker marker) {
         return RedisKeyBuilder.getCurrentTaskKey(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
     }
+    public static void QuartzClearTask(StringRedisTemplate redisTemplate, long cleanMapinterval) {
+        Set<String> keys = redisTemplate.keys(RedisKeyBuilder.getCurrentTaskTimePrefix()+"*");
+        Iterator<String> iterators =keys.iterator();
+        while (iterators.hasNext()){
+            String key = iterators.next();
+            Set<ZSetOperations.TypedTuple<String>> rangeWithScores =
+                    redisTemplate.opsForZSet().rangeWithScores(key, 0  , -1);
+
+            Iterator<ZSetOperations.TypedTuple<String>> iterator = rangeWithScores.iterator();
+            while(iterator.hasNext()){
+                ZSetOperations.TypedTuple<String> next = iterator.next();
+                if ((System.currentTimeMillis() - next.getScore()) > cleanMapinterval * 1000 * 60) {
+
+                    redisTemplate.opsForZSet().remove(RedisKeyBuilder.getCurrentTaskKeyByTimeKey(key), next.getValue());
+
+                    redisTemplate.opsForZSet().remove(key, next.getValue());
+                }
+            }
+
+        }
+
+    }
 }

+ 25 - 0
stmms-common/src/main/java/cn/com/qmth/stmms/common/redis/RedisKeyBuilder.java

@@ -4,6 +4,7 @@ import java.text.MessageFormat;
 
 import cn.com.qmth.stmms.common.enums.LibraryType;
 import cn.com.qmth.stmms.common.enums.MarkStage;
+import org.apache.commons.lang.StringUtils;
 
 public class RedisKeyBuilder {
 
@@ -23,6 +24,8 @@ public class RedisKeyBuilder {
 
     private static final String BLOCK_MARKED_TASK_KEY = "block:marked:task:{0}";
 
+    private static final String MARK_CURRENT_TASK_TIME_KEY = "mark:current:time:key:{0}:{1}:{2}";
+
     /**
      * 已领取未给分的评卷任务
      * 
@@ -129,4 +132,26 @@ public class RedisKeyBuilder {
     public static String getBlockMarkedTaskKey(int blockId) {
         return MessageFormat.format(BLOCK_MARKED_TASK_KEY, String.valueOf(blockId));
     }
+    /**
+     * 已领取未给分的评卷任务的领取时间的Key
+     *
+     * @param examId
+     * @param subjectCode
+     * @return
+     */
+    public static String getCurrentTaskTimeKey(int examId, String subjectCode,int number) {
+        return MessageFormat.format(MARK_CURRENT_TASK_TIME_KEY, String.valueOf(examId), subjectCode,number);
+    }
+
+
+    public static String getCurrentTaskKeyByTimeKey(String TimeKey){
+        if(!StringUtils.isBlank(TimeKey)){
+            return  TimeKey.replace("mark:current:time:key", "mark:current");
+        }
+        return "";
+    }
+
+    public static String getCurrentTaskTimePrefix(){
+        return MARK_CURRENT_TASK_TIME_KEY;
+    }
 }

+ 2 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkGroupController.java

@@ -71,6 +71,8 @@ public class MarkGroupController extends BaseExamController {
                     group.getNumber()));
             group.setMarkerCount(markerService.countByExamAndSubjectAndGroup(examId, subjectCode, group.getNumber()));
             group.setCurrentCount(taskService.countCurrent(examId, subjectCode, group.getNumber()));
+            int percent = group.getLibraryCount() > 0 ? (int) (group.getMarkedCount() * 100.00 / group.getLibraryCount()) : 0;
+            group.setPercent(percent);
         }
         model.addAttribute("resultList", list);
         model.addAttribute("subject", subject);

+ 23 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/quartz/ScheduleRunner.java

@@ -0,0 +1,23 @@
+package cn.com.qmth.stmms.admin.quartz;
+
+import cn.com.qmth.stmms.biz.mark.service.Impl.TaskServiceImpl;
+import cn.com.qmth.stmms.biz.mark.service.TaskService;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ScheduleRunner {
+    
+    @Value("${jvm.cleanMapinterval}")
+    private long cleanMapinterval;
+	@Scheduled(cron = "${jvm.cleanMapTimer}")
+    public void schClearTaskMap() {
+	    TaskService taskServiceImpl = new TaskServiceImpl();
+		try {
+			taskServiceImpl.clearTaskMap(cleanMapinterval);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+    }
+}

+ 11 - 8
stmms-web/src/main/webapp/WEB-INF/spring-mvc.xml

@@ -1,14 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
-	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
-	xsi:schemaLocation="  
-        http://www.springframework.org/schema/beans  
-        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
-        http://www.springframework.org/schema/context  
+	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+	   xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
+	   xmlns:task="http://www.springframework.org/schema/task"
+	   xsi:schemaLocation="
+        http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+        http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd
-        http://www.springframework.org/schema/mvc 
-        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
+        http://www.springframework.org/schema/mvc
+        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
+        http://www.springframework.org/schema/task
+		 http://www.springframework.org/schema/task/spring-task-3.2.xsd">
         
 	<import resource="applicationContext.xml"/>
 	

+ 1 - 6
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/groupList.jsp

@@ -66,12 +66,7 @@
 				<td>${result.leftCount}</td>
 				<td>${result.currentCount}</td>
 				<td>
-					<c:if test="${result.libraryCount==0}">
-						0%
-					</c:if>
-					<c:if test="${result.libraryCount>0}">
-						<fmt:formatNumber type="PERCENT" value="${result.markedCount*1.0/result.libraryCount}"/>
-					</c:if>
+				  ${result.percent}%
 				</td>
 				<td>
 				    <c:if test="${web_user.schoolAdmin==true}">