fixed some bugs in bulk action and moodle load sync
This commit is contained in:
parent
de760b3714
commit
adce16bc7c
5 changed files with 59 additions and 11 deletions
|
@ -87,6 +87,7 @@ public class BulkActionServiceImpl implements BulkActionService {
|
||||||
@Override
|
@Override
|
||||||
public void collectDependencies(final BulkAction action) {
|
public void collectDependencies(final BulkAction action) {
|
||||||
checkProcessing(action);
|
checkProcessing(action);
|
||||||
|
updateDependencyTypes(action);
|
||||||
for (final BulkActionSupportDAO<?> sup : this.supporter.values()) {
|
for (final BulkActionSupportDAO<?> sup : this.supporter.values()) {
|
||||||
action.dependencies.addAll(sup.getDependencies(action));
|
action.dependencies.addAll(sup.getDependencies(action));
|
||||||
}
|
}
|
||||||
|
@ -107,6 +108,7 @@ public class BulkActionServiceImpl implements BulkActionService {
|
||||||
throw new IllegalArgumentException("No bulk action support for: " + action);
|
throw new IllegalArgumentException("No bulk action support for: " + action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateDependencyTypes(action);
|
||||||
collectDependencies(action);
|
collectDependencies(action);
|
||||||
|
|
||||||
if (!action.dependencies.isEmpty()) {
|
if (!action.dependencies.isEmpty()) {
|
||||||
|
@ -286,8 +288,15 @@ public class BulkActionServiceImpl implements BulkActionService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkProcessing(final BulkAction action) {
|
private void checkProcessing(final BulkAction action) {
|
||||||
|
if (action.alreadyProcessed) {
|
||||||
|
throw new IllegalStateException("Given BulkAction has already been processed. Use a new one");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDependencyTypes(final BulkAction action) {
|
||||||
// complete this.directDependancyMap if needed
|
// complete this.directDependancyMap if needed
|
||||||
if (action.includeDependencies != null) {
|
if (action.includeDependencies != null && !action.includeDependencies.isEmpty()) {
|
||||||
this.directDependancyMap.entrySet().stream()
|
this.directDependancyMap.entrySet().stream()
|
||||||
.forEach(entry -> {
|
.forEach(entry -> {
|
||||||
if (action.includeDependencies.contains(entry.getKey())) {
|
if (action.includeDependencies.contains(entry.getKey())) {
|
||||||
|
@ -295,9 +304,6 @@ public class BulkActionServiceImpl implements BulkActionService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (action.alreadyProcessed) {
|
|
||||||
throw new IllegalStateException("Given BulkAction has already been processed. Use a new one");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ResourceNotFoundException;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ResourceNotFoundException;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.TransactionHandler;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.TransactionHandler;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleCourseAccess;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleCourseAccess;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
@ -791,9 +792,7 @@ public class ExamDAOImpl implements ExamDAO {
|
||||||
// get and map quizzes
|
// get and map quizzes
|
||||||
final Map<String, QuizData> quizzes = this.lmsAPIService
|
final Map<String, QuizData> quizzes = this.lmsAPIService
|
||||||
.getLmsAPITemplate(lmsSetupId)
|
.getLmsAPITemplate(lmsSetupId)
|
||||||
.map(template -> (cached)
|
.map(template -> getQuizzesFromLMS(template, recordMapping.keySet(), cached))
|
||||||
? template.getQuizzesFromCache(recordMapping.keySet())
|
|
||||||
: template.getQuizzes(recordMapping.keySet()))
|
|
||||||
.getOrThrow()
|
.getOrThrow()
|
||||||
.stream()
|
.stream()
|
||||||
.flatMap(Result::skipOnError)
|
.flatMap(Result::skipOnError)
|
||||||
|
@ -814,6 +813,18 @@ public class ExamDAOImpl implements ExamDAO {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Collection<Result<QuizData>> getQuizzesFromLMS(final LmsAPITemplate template, final Set<String> ids,
|
||||||
|
final boolean cached) {
|
||||||
|
try {
|
||||||
|
return (cached)
|
||||||
|
? template.getQuizzesFromCache(ids)
|
||||||
|
: template.getQuizzes(ids);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Unexpected error while using LmsAPITemplate to get quizzes: ", e);
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private QuizData getQuizData(
|
private QuizData getQuizData(
|
||||||
final Map<String, QuizData> quizzes,
|
final Map<String, QuizData> quizzes,
|
||||||
final String externalId,
|
final String externalId,
|
||||||
|
|
|
@ -147,11 +147,23 @@ public interface LmsAPIService {
|
||||||
return new Page<>(0, 1, sortAttribute, Collections.emptyList());
|
return new Page<>(0, 1, sortAttribute, Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
final int start = (pageNumber - 1) * pageSize;
|
int start = (pageNumber - 1) * pageSize;
|
||||||
int end = start + pageSize;
|
int end = start + pageSize;
|
||||||
if (end > quizzes.size()) {
|
if (end > quizzes.size()) {
|
||||||
end = quizzes.size();
|
end = quizzes.size();
|
||||||
}
|
}
|
||||||
|
if (start >= end) {
|
||||||
|
start = end - pageSize;
|
||||||
|
if (start < 0) {
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Page<>(
|
||||||
|
(quizzes.size() <= pageSize) ? 1 : quizzes.size() / pageSize + 1,
|
||||||
|
start / pageSize + 1,
|
||||||
|
sortAttribute,
|
||||||
|
quizzes.subList(start, end));
|
||||||
|
}
|
||||||
|
|
||||||
return new Page<>(
|
return new Page<>(
|
||||||
(quizzes.size() <= pageSize) ? 1 : quizzes.size() / pageSize + 1,
|
(quizzes.size() <= pageSize) ? 1 : quizzes.size() / pageSize + 1,
|
||||||
|
|
|
@ -273,6 +273,7 @@ public class MoodleCourseAccess extends CourseAccess {
|
||||||
} else if (this.moodleCourseDataAsyncLoader.isLongRunningTask()) {
|
} else if (this.moodleCourseDataAsyncLoader.isLongRunningTask()) {
|
||||||
// on long running tasks if we have a different fromCutTime as before
|
// on long running tasks if we have a different fromCutTime as before
|
||||||
// kick off the lazy loading task immediately with the new time filter
|
// kick off the lazy loading task immediately with the new time filter
|
||||||
|
courseQuizData = this.moodleCourseDataAsyncLoader.getCachedCourseData();
|
||||||
if (fromCutTime > 0 && fromCutTime != this.moodleCourseDataAsyncLoader.getFromCutTime()) {
|
if (fromCutTime > 0 && fromCutTime != this.moodleCourseDataAsyncLoader.getFromCutTime()) {
|
||||||
this.moodleCourseDataAsyncLoader.setFromCutTime(fromCutTime);
|
this.moodleCourseDataAsyncLoader.setFromCutTime(fromCutTime);
|
||||||
this.moodleCourseDataAsyncLoader.loadAsync(restTemplate);
|
this.moodleCourseDataAsyncLoader.loadAsync(restTemplate);
|
||||||
|
@ -281,7 +282,7 @@ public class MoodleCourseAccess extends CourseAccess {
|
||||||
* Constants.MINUTE_IN_MILLIS) {
|
* Constants.MINUTE_IN_MILLIS) {
|
||||||
this.moodleCourseDataAsyncLoader.loadAsync(restTemplate);
|
this.moodleCourseDataAsyncLoader.loadAsync(restTemplate);
|
||||||
}
|
}
|
||||||
courseQuizData = this.moodleCourseDataAsyncLoader.getCachedCourseData();
|
|
||||||
} else {
|
} else {
|
||||||
// just run the task in sync
|
// just run the task in sync
|
||||||
if (fromCutTime >= 0) {
|
if (fromCutTime >= 0) {
|
||||||
|
|
|
@ -64,6 +64,7 @@ public class MoodleCourseDataAsyncLoader {
|
||||||
private final int pageSize;
|
private final int pageSize;
|
||||||
|
|
||||||
private final Set<CourseDataShort> cachedCourseData = new HashSet<>();
|
private final Set<CourseDataShort> cachedCourseData = new HashSet<>();
|
||||||
|
private final Set<String> newIds = new HashSet<>();
|
||||||
|
|
||||||
private String lmsSetup = Constants.EMPTY_NOTE;
|
private String lmsSetup = Constants.EMPTY_NOTE;
|
||||||
private long lastRunTime = 0;
|
private long lastRunTime = 0;
|
||||||
|
@ -132,7 +133,7 @@ public class MoodleCourseDataAsyncLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLongRunningTask() {
|
public boolean isLongRunningTask() {
|
||||||
return this.lastLoadTime > 30 * Constants.SECOND_IN_MILLIS;
|
return this.lastLoadTime > 3 * Constants.SECOND_IN_MILLIS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<CourseDataShort> loadSync(final MoodleAPIRestTemplate restTemplate) {
|
public Set<CourseDataShort> loadSync(final MoodleAPIRestTemplate restTemplate) {
|
||||||
|
@ -167,10 +168,12 @@ public class MoodleCourseDataAsyncLoader {
|
||||||
|
|
||||||
private Runnable loadAndCache(final MoodleAPIRestTemplate restTemplate) {
|
private Runnable loadAndCache(final MoodleAPIRestTemplate restTemplate) {
|
||||||
return () -> {
|
return () -> {
|
||||||
this.cachedCourseData.clear();
|
//this.cachedCourseData.clear();
|
||||||
|
this.newIds.clear();
|
||||||
final long startTime = Utils.getMillisecondsNow();
|
final long startTime = Utils.getMillisecondsNow();
|
||||||
|
|
||||||
loadAllQuizzes(restTemplate);
|
loadAllQuizzes(restTemplate);
|
||||||
|
syncCache();
|
||||||
|
|
||||||
this.lastLoadTime = Utils.getMillisecondsNow() - startTime;
|
this.lastLoadTime = Utils.getMillisecondsNow() - startTime;
|
||||||
this.running = false;
|
this.running = false;
|
||||||
|
@ -259,6 +262,7 @@ public class MoodleCourseDataAsyncLoader {
|
||||||
c);
|
c);
|
||||||
} else {
|
} else {
|
||||||
this.cachedCourseData.add(c);
|
this.cachedCourseData.add(c);
|
||||||
|
this.newIds.add(c.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -453,6 +457,20 @@ public class MoodleCourseDataAsyncLoader {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void syncCache() {
|
||||||
|
if (!this.cachedCourseData.isEmpty()) {
|
||||||
|
final Set<CourseDataShort> newData = this.cachedCourseData.stream()
|
||||||
|
.filter(data -> this.newIds.contains(data.id))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
synchronized (this.cachedCourseData) {
|
||||||
|
this.cachedCourseData.clear();
|
||||||
|
this.cachedCourseData.addAll(newData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.newIds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
static final class CoursePage {
|
static final class CoursePage {
|
||||||
final Collection<CourseKey> courseKeys;
|
final Collection<CourseKey> courseKeys;
|
||||||
|
|
Loading…
Reference in a new issue