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")
|
||||
testImplementation(kotlin("test"))
|
||||
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.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,12 +33,36 @@ class ExposedKidioRepository : KidioRepository {
|
|||
.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()
|
||||
.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 {
|
||||
val rowsUpdated = ScreentimeTable.update({ ScreentimeTable.userId eq userId }) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue