From 3177be1bf0283a8b940a3ab94e5bcf27d744a5cc Mon Sep 17 00:00:00 2001 From: Seil0 Date: Sun, 27 Oct 2019 13:51:08 +0100 Subject: [PATCH] use a FixedThreadPool to execute the timetable updates closes #9 --- build.gradle | 2 +- .../mosad/thecitadelofricks/APIController.kt | 1 - .../controller/CacheController.kt | 63 +++++++++---------- .../controller/StatusController.kt | 3 +- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/build.gradle b/build.gradle index 03447cb..b329eb4 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ repositories { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.1" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2" implementation 'org.jsoup:jsoup:1.12.1' implementation 'org.springframework.boot:spring-boot-starter-web' diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/APIController.kt b/src/main/kotlin/org/mosad/thecitadelofricks/APIController.kt index f4de91e..a39c94b 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/APIController.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/APIController.kt @@ -39,7 +39,6 @@ import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController import java.time.LocalDateTime import java.util.* -import kotlin.collections.ArrayList @RestController class APIController { diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt b/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt index 6ebfc86..681e427 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt @@ -33,7 +33,9 @@ import org.mosad.thecitadelofricks.hsoparser.TimetableParser import org.slf4j.Logger import org.slf4j.LoggerFactory import java.util.* +import java.util.concurrent.Executors import kotlin.collections.ArrayList +import kotlin.collections.HashSet import kotlin.concurrent.scheduleAtFixedRate class CacheController { @@ -153,12 +155,8 @@ class CacheController { */ private fun asyncUpdateCourseList() = GlobalScope.launch { CourseListParser().getCourseLinks(courseListURL)?.let { - courseList = - CourseList( - CourseMeta( - System.currentTimeMillis() / 1000, - it.size - ), it + courseList = CourseList( + CourseMeta(System.currentTimeMillis() / 1000, it.size), it ) } @@ -175,13 +173,9 @@ class CacheController { // only update if we get valid data if (mensaCurrentWeek != null && mensaNextWeek != null) { - mensaMenu = - MensaMenu( - MensaMeta( - System.currentTimeMillis() / 1000, - mensaName - ), mensaCurrentWeek, mensaNextWeek - ) + mensaMenu = MensaMenu( + MensaMeta(System.currentTimeMillis() / 1000, mensaName), mensaCurrentWeek, mensaNextWeek + ) } logger.info("updated mensamenu successful at ${Date(mensaMenu.meta.updateTime * 1000)}") @@ -190,14 +184,27 @@ class CacheController { /** * this function updates all existing timetables * during the update process the old data will be returned for a API request + * a FixedThreadPool is used to make parallel requests for faster updates */ private fun asyncUpdateTimetables() = GlobalScope.launch { - timetableList.forEach { timetableCourse -> - val updateURL = timetableCourse.meta.link - timetableCourse.timetable = TimetableParser().getTimeTable(updateURL) - timetableCourse.meta.updateTime = System.currentTimeMillis() / 1000 + logger.info("updating ${timetableList.size} timetables ...") + + // create a new ThreadPool with 5 threads + val executor = Executors.newFixedThreadPool(5) + + try { + timetableList.forEach { timetableCourse -> + executor.execute { + timetableCourse.timetable = TimetableParser().getTimeTable(timetableCourse.meta.link) + timetableCourse.meta.updateTime = System.currentTimeMillis() / 1000 + } + + } + } catch (ex: Exception) { + logger.error("error while updating the timetables", ex) + } finally { + executor.shutdown() } - logger.info("updated ${timetableList.size} timetables successful!") } /** @@ -208,13 +215,9 @@ class CacheController { // get all courses on startup val jobCourseUpdate = GlobalScope.async { CourseListParser().getCourseLinks(courseListURL)?.let { - courseList = - CourseList( - CourseMeta( - System.currentTimeMillis() / 1000, - it.size - ), it - ) + courseList = CourseList( + CourseMeta(System.currentTimeMillis() / 1000, it.size), it + ) } } @@ -225,13 +228,9 @@ class CacheController { // only update if we get valid data if (mensaCurrentWeek != null && mensaNextWeek != null) { - mensaMenu = - MensaMenu( - MensaMeta( - System.currentTimeMillis() / 1000, - mensaName - ), mensaCurrentWeek, mensaNextWeek - ) + mensaMenu = MensaMenu( + MensaMeta(System.currentTimeMillis() / 1000, mensaName), mensaCurrentWeek, mensaNextWeek + ) } } diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/controller/StatusController.kt b/src/main/kotlin/org/mosad/thecitadelofricks/controller/StatusController.kt index 60dfb7a..5446c7d 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/controller/StatusController.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/controller/StatusController.kt @@ -59,7 +59,8 @@ class StatusController { when (timetableRequests.stream().filter { x -> x.courseName == courseName }.findAny().orElse(null)) { null -> timetableRequests.add(TimetableCounter(courseName, 0)) } - timetableRequests.stream().filter { x ->x.courseName == courseName }.findFirst().ifPresent { x -> x.requests++ } + timetableRequests.stream().filter { x -> x.courseName == courseName }.findFirst() + .ifPresent { x -> x.requests++ } // TODO Java 11 // timetableRequests.stream().filter { it.courseName == courseName }.findFirst().ifPresentOrElse({