diff --git a/build.gradle.kts b/build.gradle.kts index 6f96aeb..c424bcd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -31,4 +31,8 @@ dependencies { implementation("org.jetbrains.exposed:exposed-jdbc:0.50.0") testImplementation(kotlin("test")) testImplementation(ktorLibs.server.testHost) + + //redis + implementation("redis.clients:jedis:5.1.2") + } \ No newline at end of file diff --git a/src/main/kotlin/com/oliver/kidio/backend/data/database/RedisFactory.kt b/src/main/kotlin/com/oliver/kidio/backend/data/database/RedisFactory.kt new file mode 100644 index 0000000..b32d0a1 --- /dev/null +++ b/src/main/kotlin/com/oliver/kidio/backend/data/database/RedisFactory.kt @@ -0,0 +1,28 @@ +package com.oliver.kidio.backend.data.database +import io.ktor.server.config.* +import redis.clients.jedis.JedisPool +import redis.clients.jedis.JedisPoolConfig + +object RedisFactory { + private var jedisPool: JedisPool? = null + + fun init(config: ApplicationConfig) { + val host = System.getenv("REDIS_HOST") + ?: config.propertyOrNull("storage.redisHost")?.getString() + ?: "localhost" + + val port = (System.getenv("REDIS_PORT") + ?: config.propertyOrNull("storage.redisPort")?.getString() + ?: "6379").toInt() + + val poolConfig = JedisPoolConfig().apply { + maxTotal = 32 + maxIdle = 8 + minIdle = 2 + } + jedisPool = JedisPool(poolConfig, host, port) + } + + fun getResource() = jedisPool?.resource + ?: throw IllegalStateException("Redis Verbindungspool ist nicht initzialisiert") +} diff --git a/src/main/kotlin/com/oliver/kidio/backend/domain/repository/KidioRepository.kt b/src/main/kotlin/com/oliver/kidio/backend/domain/repository/KidioRepository.kt index c5b9fe2..d0b1166 100644 --- a/src/main/kotlin/com/oliver/kidio/backend/domain/repository/KidioRepository.kt +++ b/src/main/kotlin/com/oliver/kidio/backend/domain/repository/KidioRepository.kt @@ -2,6 +2,7 @@ package com.oliver.kidio.backend.domain.repository import com.oliver.kidio.backend.Task import com.oliver.kidio.backend.data.database.DatabaseFactory +import com.oliver.kidio.backend.data.database.RedisFactory import com.oliver.kidio.backend.data.database.ScreentimeTable import com.oliver.kidio.backend.data.database.TasksTable import org.jetbrains.exposed.sql.* @@ -32,11 +33,35 @@ class ExposedKidioRepository : KidioRepository { .singleOrNull() } - override suspend fun getScreentime(userId: String): Int = DatabaseFactory.dbQuery { - ScreentimeTable.selectAll() - .where { ScreentimeTable.userId eq userId } - .map { it[ScreentimeTable.remainingSeconds] } - .singleOrNull() ?: 1800 + override suspend fun getScreentime(userId: String): Int { + var redisKey = "screentime:$userId" + + try { + RedisFactory.getResource().use { jedis -> + val cachedSeconds = jedis.get(redisKey) + if (cachedSeconds != null) { + println("DEBUG: Bildschirmzeit für $userId aus REDIS geladen: $cachedSeconds Sek") + return cachedSeconds.toInt() + } + } + } catch (e: Exception) { + println("WARNUNG: Konnte nicht aus Redis lesen (Postgres-Fallback genutzt): ${e.message}") + } + val dbSeconds = DatabaseFactory.dbQuery { + ScreentimeTable.selectAll() + .where { ScreentimeTable.userId eq userId } + .map { it[ScreentimeTable.remainingSeconds] } + .singleOrNull() ?: 1800 + } + try { + RedisFactory.getResource().use { jedis -> + jedis.setex(redisKey, 3600, dbSeconds.toString()) + println("DEBUG: Bildschirmzeit für $userId in REDIS gecacht.") + } + } catch (e: Exception) { + println("WARNUNG: Konnte Wert nicht in Redis speichern: ${e.message}") + } + return dbSeconds } override suspend fun updateScreentime(userId: String, seconds: Int): Unit = DatabaseFactory.dbQuery { diff --git a/src/main/kotlin/main.kt b/src/main/kotlin/main.kt index 5246a3c..3831b3c 100644 --- a/src/main/kotlin/main.kt +++ b/src/main/kotlin/main.kt @@ -1,5 +1,6 @@ import com.oliver.kidio.backend.plugins.configureRouting import com.oliver.kidio.backend.data.database.DatabaseFactory +import com.oliver.kidio.backend.data.database.RedisFactory import com.oliver.kidio.backend.domain.repository.ExposedKidioRepository import io.ktor.serialization.kotlinx.json.* import io.ktor.server.application.* @@ -8,6 +9,7 @@ import io.ktor.server.plugins.contentnegotiation.* fun Application.module() { // Datenbank initialisieren DatabaseFactory.init(environment.config) + RedisFactory.init(environment.config) // JSON aktivieren install(ContentNegotiation) {