feat: integrate Redis for screen time caching with fallback to PostgreSQL
This commit is contained in:
parent
1ae05f0c36
commit
11dae7a57c
|
|
@ -31,4 +31,8 @@ dependencies {
|
||||||
implementation("org.jetbrains.exposed:exposed-jdbc:0.50.0")
|
implementation("org.jetbrains.exposed:exposed-jdbc:0.50.0")
|
||||||
testImplementation(kotlin("test"))
|
testImplementation(kotlin("test"))
|
||||||
testImplementation(ktorLibs.server.testHost)
|
testImplementation(ktorLibs.server.testHost)
|
||||||
|
|
||||||
|
//redis
|
||||||
|
implementation("redis.clients:jedis:5.1.2")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -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")
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ package com.oliver.kidio.backend.domain.repository
|
||||||
|
|
||||||
import com.oliver.kidio.backend.Task
|
import com.oliver.kidio.backend.Task
|
||||||
import com.oliver.kidio.backend.data.database.DatabaseFactory
|
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.ScreentimeTable
|
||||||
import com.oliver.kidio.backend.data.database.TasksTable
|
import com.oliver.kidio.backend.data.database.TasksTable
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
|
|
@ -32,12 +33,36 @@ class ExposedKidioRepository : KidioRepository {
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getScreentime(userId: String): Int = DatabaseFactory.dbQuery {
|
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()
|
ScreentimeTable.selectAll()
|
||||||
.where { ScreentimeTable.userId eq userId }
|
.where { ScreentimeTable.userId eq userId }
|
||||||
.map { it[ScreentimeTable.remainingSeconds] }
|
.map { it[ScreentimeTable.remainingSeconds] }
|
||||||
.singleOrNull() ?: 1800
|
.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 {
|
override suspend fun updateScreentime(userId: String, seconds: Int): Unit = DatabaseFactory.dbQuery {
|
||||||
val rowsUpdated = ScreentimeTable.update({ ScreentimeTable.userId eq userId }) {
|
val rowsUpdated = ScreentimeTable.update({ ScreentimeTable.userId eq userId }) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import com.oliver.kidio.backend.plugins.configureRouting
|
import com.oliver.kidio.backend.plugins.configureRouting
|
||||||
import com.oliver.kidio.backend.data.database.DatabaseFactory
|
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 com.oliver.kidio.backend.domain.repository.ExposedKidioRepository
|
||||||
import io.ktor.serialization.kotlinx.json.*
|
import io.ktor.serialization.kotlinx.json.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
|
|
@ -8,6 +9,7 @@ import io.ktor.server.plugins.contentnegotiation.*
|
||||||
fun Application.module() {
|
fun Application.module() {
|
||||||
// Datenbank initialisieren
|
// Datenbank initialisieren
|
||||||
DatabaseFactory.init(environment.config)
|
DatabaseFactory.init(environment.config)
|
||||||
|
RedisFactory.init(environment.config)
|
||||||
|
|
||||||
// JSON aktivieren
|
// JSON aktivieren
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue