perf: make student task navigation read-only

main
chenyuan 5 days ago
parent d9c5ad27e7
commit 298d26da81

@ -25,6 +25,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -36,7 +37,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -70,7 +70,15 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
private boolean trainingTaskClassConfigTableChecked = false; private boolean trainingTaskClassConfigTableChecked = false;
private volatile boolean defaultTasksInitialized = false; private volatile boolean defaultTasksInitialized = false;
private final Object defaultTasksInitializationLock = new Object(); private final Object defaultTasksInitializationLock = new Object();
private final Set<String> initializedStudentClassTaskIds = ConcurrentHashMap.newKeySet();
/**
* Seed built-in task definitions during application startup so that opening
* a student's navigation never performs the initialization write path.
*/
@PostConstruct
public void initializeDefaultTasksAtStartup() {
ensureDefaultTasks(null);
}
@Override @Override
public List<TrainingTask> list(String projectName, String taskName, Boolean enabledOnly) { public List<TrainingTask> list(String projectName, String taskName, Boolean enabledOnly) {
@ -315,7 +323,6 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
|| (requiresExplicitPublication(normalizedTaskKey) && publishedTaskKeys == null)) { || (requiresExplicitPublication(normalizedTaskKey) && publishedTaskKeys == null)) {
return null; return null;
} }
ensureStudentClassTasksInitialized(teachingClassId);
TrainingTaskClassConfig classTask = trainingTaskClassConfigMapper.selectByTeachingClassAndTaskKey(teachingClassId, normalizedTaskKey); TrainingTaskClassConfig classTask = trainingTaskClassConfigMapper.selectByTeachingClassAndTaskKey(teachingClassId, normalizedTaskKey);
if (classTask != null) { if (classTask != null) {
return Boolean.TRUE.equals(classTask.getEnabled()) ? toTask(classTask) : null; return Boolean.TRUE.equals(classTask.getEnabled()) ? toTask(classTask) : null;
@ -345,8 +352,7 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
.filter(task -> !requiresExplicitPublication(task.getTaskKey())) .filter(task -> !requiresExplicitPublication(task.getTaskKey()))
.collect(Collectors.toList()), enabledOnly); .collect(Collectors.toList()), enabledOnly);
} }
List<TrainingTaskClassConfig> classTasks = readStudentClassTasks(teachingClassId, defaults); List<TrainingTask> tasks = filterEnabled(readClassTasks(teachingClassId, defaults), enabledOnly);
List<TrainingTask> tasks = filterEnabled(toTasks(classTasks), enabledOnly);
Set<String> publishedTaskKeys = getPublishedTaskKeys(teachingClassId); Set<String> publishedTaskKeys = getPublishedTaskKeys(teachingClassId);
if (publishedTaskKeys == null) { if (publishedTaskKeys == null) {
return tasks.stream() return tasks.stream()
@ -487,23 +493,6 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
return new ArrayList<>(existingByKey.values()); return new ArrayList<>(existingByKey.values());
} }
private void ensureStudentClassTasksInitialized(String teachingClassId) {
if (StringUtils.isBlank(teachingClassId) || initializedStudentClassTaskIds.contains(teachingClassId)) {
return;
}
ensureClassTasksInitialized(teachingClassId, trainingTaskMapper.selectList(null, null, null), null);
initializedStudentClassTaskIds.add(teachingClassId);
}
private List<TrainingTaskClassConfig> readStudentClassTasks(String teachingClassId, List<TrainingTask> defaults) {
if (initializedStudentClassTaskIds.contains(teachingClassId)) {
return trainingTaskClassConfigMapper.selectListByTeachingClass(teachingClassId, null);
}
List<TrainingTaskClassConfig> classTasks = ensureClassTasksInitialized(teachingClassId, defaults, null);
initializedStudentClassTaskIds.add(teachingClassId);
return classTasks;
}
private void synchronizeClassTaskDefaults(TrainingTask previousTask, TrainingTask updatedTask) { private void synchronizeClassTaskDefaults(TrainingTask previousTask, TrainingTask updatedTask) {
if (schoolClassMapper == null || trainingTaskClassConfigMapper == null if (schoolClassMapper == null || trainingTaskClassConfigMapper == null
|| previousTask == null || updatedTask == null) { || previousTask == null || updatedTask == null) {

Loading…
Cancel
Save