Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
plugins {
kotlin("multiplatform") version "1.8.0" apply false
kotlin("js") version "1.7.20" apply false
kotlin("jvm") version "1.5.31" apply false
kotlin("plugin.serialization") version "1.5.31" apply false
kotlin("jvm") version "2.3.10" apply false
kotlin("plugin.serialization") version "2.3.10" apply false
}
100 changes: 48 additions & 52 deletions core/build.gradle
Original file line number Diff line number Diff line change
@@ -1,45 +1,32 @@
Properties liquibaseProperties = new Properties()
liquibaseProperties.load(new FileInputStream(
file("src/main/resources/db/database.properties").exists() ? file("src/main/resources/db/database.properties") : file("src/main/resources/db/database.properties.sample")))


buildscript {
ext {
springBootVersion = '2.7.17'
liquibaseVersion = '2.0.4'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
classpath("org.liquibase:liquibase-gradle-plugin:${liquibaseVersion}")
classpath 'org.liquibase:liquibase-core:4.31.1'
}
}

apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'org.liquibase.gradle'

plugins {
id 'org.jetbrains.kotlin.jvm' version '2.3.10'
id 'org.jetbrains.kotlin.plugin.spring' version '2.3.10'
id 'org.springframework.boot' version '4.0.3'
id 'io.spring.dependency-management' version '1.1.7'
id 'org.liquibase.gradle' version '3.1.0'
}

group = 'ee.urgas'
version = '1'
sourceCompatibility = 11
compileKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
jvmTarget = "11"

java {
toolchain {
languageVersion = JavaLanguageVersion.of(25)
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
jvmTarget = "11"

kotlin {
compilerOptions {
freeCompilerArgs.addAll '-Xjsr305=strict', '-Xannotation-default-target=param-property'
}
}

Expand All @@ -54,54 +41,57 @@ test {
dependencies {

// Spring Boot
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webmvc'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-cache'
// restTemplate:
implementation 'org.springframework.boot:spring-boot-starter-restclient'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.boot:spring-boot-starter-validation'

// Cache
implementation 'com.github.ben-manes.caffeine:caffeine:3.0.1'
implementation 'com.github.ben-manes.caffeine:caffeine'

// Logging
implementation 'io.github.microutils:kotlin-logging:1.7.10'
implementation 'io.github.oshai:kotlin-logging:8.0.01'

// Database
implementation 'org.jetbrains.exposed:exposed-core:0.48.0'
implementation 'org.jetbrains.exposed:exposed-java-time:0.48.0'
implementation 'org.jetbrains.exposed:exposed-dao:0.48.0'
implementation 'org.jetbrains.exposed:exposed-jodatime:0.48.0'
implementation 'org.jetbrains.exposed:exposed-jdbc:0.48.0'
implementation 'org.jetbrains.exposed:exposed-json:0.48.0'

implementation 'com.zaxxer:HikariCP:3.4.5'
implementation 'org.postgresql:postgresql:42.6.0'
implementation 'org.liquibase:liquibase-core:3.6.3'
liquibaseRuntime 'org.liquibase:liquibase-core:3.6.3'
liquibaseRuntime 'org.postgresql:postgresql:42.6.0'
implementation("org.jetbrains.exposed:exposed-core:1.1.0")
implementation("org.jetbrains.exposed:exposed-jdbc:1.1.0")
implementation("org.jetbrains.exposed:exposed-dao:1.1.0")
implementation("org.jetbrains.exposed:exposed-jodatime:1.1.0")
implementation("org.jetbrains.exposed:exposed-json:1.1.0")


implementation 'org.postgresql:postgresql'
implementation 'org.liquibase:liquibase-core:4.31.1'
liquibaseRuntime 'org.liquibase:liquibase-core:4.31.1'
liquibaseRuntime 'org.postgresql:postgresql'
liquibaseRuntime 'info.picocli:picocli:4.7.6'
liquibaseRuntime 'org.apache.commons:commons-lang3:3.20.0'
liquibaseRuntime files('src/main/resources')

// Kotlin support
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
implementation 'tools.jackson.module:jackson-module-kotlin'
implementation 'org.jetbrains.kotlin:kotlin-reflect'

// Testing
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
testImplementation 'org.liquibase:liquibase-core:3.7.0'

// Asciidoc
implementation 'org.asciidoctor:asciidoctorj:2.4.3'
implementation 'org.asciidoctor:asciidoctorj:3.0.1'

// Markdown (CommonMark with GFM extensions)
implementation 'org.commonmark:commonmark:0.24.0'
implementation 'org.commonmark:commonmark-ext-gfm-tables:0.24.0'
implementation 'org.commonmark:commonmark-ext-gfm-strikethrough:0.24.0'

// Jsoup for Asciidoctor HTML output customisation
implementation 'org.jsoup:jsoup:1.13.1'
implementation 'org.jsoup:jsoup:1.22.1'

// StoredFile type detection
implementation 'org.apache.tika:tika-core:1.25'
implementation 'org.apache.tika:tika-core:3.2.3'

// Source code similarity
implementation 'me.xdrop:fuzzywuzzy:1.2.0'
Expand All @@ -113,11 +103,17 @@ dependencies {
implementation project(":tsl")
}

Properties liquibaseProperties = new Properties()
liquibaseProperties.load(new FileInputStream(
file("src/main/resources/db/database.properties").exists()
? file("src/main/resources/db/database.properties")
: file("src/main/resources/db/database.properties.sample")))


liquibase {
activities {
main {
changeLogFile 'src/main/resources/db/changelog.xml'
changelogFile 'db/changelog.xml'
url liquibaseProperties.url
username liquibaseProperties.username
password liquibaseProperties.password
Expand Down
1 change: 0 additions & 1 deletion core/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@

kotlinVersion=1.8.22
org.gradle.warning.mode=all
42 changes: 18 additions & 24 deletions core/src/main/kotlin/core/aas/AutoGradeScheduler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package core.aas

import core.db.*
import core.exception.InvalidRequestException
import mu.KotlinLogging
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.deleteWhere
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
import io.github.oshai.kotlinlogging.KotlinLogging
import org.jetbrains.exposed.v1.core.eq
import org.jetbrains.exposed.v1.jdbc.deleteWhere
import org.jetbrains.exposed.v1.jdbc.transactions.transaction
import org.jetbrains.exposed.v1.jdbc.update
import org.springframework.context.ApplicationListener
import org.springframework.context.event.ContextRefreshedEvent
import org.springframework.scheduling.annotation.Scheduled
Expand Down Expand Up @@ -60,11 +60,7 @@ class AutoGradeScheduler : ApplicationListener<ContextRefreshedEvent> {
}


suspend fun submitAndAwait(
autoExerciseId: Long,
submission: String,
priority: PriorityLevel
): AutoAssessment {
suspend fun submitAndAwait(autoExerciseId: Long, submission: String, priority: PriorityLevel): AutoAssessment {

val autoExercise = getAutoExerciseDetails(autoExerciseId)
val request = autoExercise.mapToExecutorRequest(submission)
Expand All @@ -83,25 +79,23 @@ class AutoGradeScheduler : ApplicationListener<ContextRefreshedEvent> {


@Synchronized
fun deleteExecutor(executorId: Long, force: Boolean) {
return transaction {
fun deleteExecutor(executorId: Long, force: Boolean): Unit = transaction {

// The load of the all the (priority) queues in the executor map of this executor.
val load = executors[executorId]?.values?.sumOf { it.size() } ?: 0
// The load of the all the (priority) queues in the executor map of this executor.
val load = executors[executorId]?.values?.sumOf { it.size() } ?: 0

// If not force removal and there is any load, deny removal
if (!force && load > 0) {
throw InvalidRequestException("Executor load != 0 (is $load). Set 'force'=true for forced removal.")
}
// If not force removal and there is any load, deny removal
if (!force && load > 0) {
throw InvalidRequestException("Executor load != 0 (is $load). Set 'force'=true for forced removal.")
}

ExecutorContainerImage.deleteWhere { ExecutorContainerImage.executor eq executorId }
Executor.deleteWhere { Executor.id eq executorId }
ExecutorContainerImage.deleteWhere { ExecutorContainerImage.executor eq executorId }
Executor.deleteWhere { Executor.id eq executorId }

executors[executorId]?.forEach { it.value.killScheduler() }
executors.remove(executorId)
executors[executorId]?.forEach { it.value.killScheduler() }
executors.remove(executorId)

log.info { "Executor '$executorId' deleted" }
}
log.info { "Executor '$executorId' deleted" }
}

@Synchronized
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/kotlin/core/aas/AutoGradeStatusObserver.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package core.aas

import kotlinx.coroutines.Job
import mu.KotlinLogging
import io.github.oshai.kotlinlogging.KotlinLogging
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Service
import java.util.concurrent.ConcurrentHashMap
Expand Down
11 changes: 5 additions & 6 deletions core/src/main/kotlin/core/aas/FunctionScheduler.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
package core.aas

import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.onClosed
import kotlinx.coroutines.channels.onFailure
import mu.KotlinLogging
import java.util.*
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.reflect.KFunction

private val log = KotlinLogging.logger {}

/**
*
Expand All @@ -29,6 +25,8 @@ private val log = KotlinLogging.logger {}
*
*/
class FunctionScheduler<T>(private val function: KFunction<T>) {
private val log = KotlinLogging.logger {}

private val jobs = ConcurrentLinkedQueue<EzJob<T>>()
private val closed = AtomicBoolean(false)

Expand Down Expand Up @@ -62,6 +60,7 @@ class FunctionScheduler<T>(private val function: KFunction<T>) {
* @param arguments to be passed to [function]
* @return [function] output
*/
@OptIn(DelicateCoroutinesApi::class)
suspend fun scheduleAndAwait(vararg arguments: Any?): T {
val job = synchronized(this) {
if (closed.get()) throw ExecutorException("Scheduler is killed")
Expand Down
Loading
Loading