feat(redis): migrate from Redisson to Quarkus Redis client and update configuration
This commit is contained in:
@@ -72,7 +72,7 @@ dependencies {
|
||||
implementation("io.quarkus:quarkus-rest-client")
|
||||
implementation("io.quarkus:quarkus-rest-client-jackson")
|
||||
implementation("com.fasterxml.jackson.module:jackson-module-scala_3:${versions["JACKSON_SCALA"]!!}")
|
||||
implementation("org.redisson:redisson:${versions["REDISSON"]!!}")
|
||||
implementation("io.quarkus:quarkus-redis-client")
|
||||
implementation("io.fabric8:kubernetes-client:6.13.0")
|
||||
|
||||
testImplementation(platform("org.junit:junit-bom:${versions["JUNIT_BOM"]!!}"))
|
||||
|
||||
@@ -3,6 +3,8 @@ quarkus:
|
||||
name: nowchess-coordinator
|
||||
http:
|
||||
port: 8086
|
||||
redis:
|
||||
hosts: redis://${REDIS_HOST:localhost}:${REDIS_PORT:6379}
|
||||
grpc:
|
||||
server:
|
||||
port: 9086
|
||||
|
||||
@@ -4,29 +4,9 @@ import jakarta.enterprise.context.ApplicationScoped
|
||||
import jakarta.enterprise.inject.Produces
|
||||
import io.fabric8.kubernetes.client.KubernetesClientBuilder
|
||||
import io.fabric8.kubernetes.client.KubernetesClient
|
||||
import org.redisson.Redisson
|
||||
import org.redisson.api.RedissonClient
|
||||
import org.redisson.config.Config
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty
|
||||
import jakarta.inject.Inject
|
||||
import scala.compiletime.uninitialized
|
||||
|
||||
@ApplicationScoped
|
||||
class BeansProducer:
|
||||
@Inject
|
||||
@ConfigProperty(name = "nowchess.redis.host", defaultValue = "localhost")
|
||||
private var redisHost: String = uninitialized
|
||||
|
||||
@Inject
|
||||
@ConfigProperty(name = "nowchess.redis.port", defaultValue = "6379")
|
||||
private var redisPort: Int = uninitialized
|
||||
|
||||
@Produces
|
||||
@ApplicationScoped
|
||||
def redissonClient: RedissonClient =
|
||||
val config = Config()
|
||||
config.useSingleServer().setAddress(s"redis://$redisHost:$redisPort")
|
||||
Redisson.create(config)
|
||||
|
||||
@Produces
|
||||
@ApplicationScoped
|
||||
|
||||
+7
-9
@@ -2,7 +2,7 @@ package de.nowchess.coordinator.service
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped
|
||||
import jakarta.inject.Inject
|
||||
import org.redisson.api.RedissonClient
|
||||
import io.quarkus.redis.datasource.RedisDataSource
|
||||
import de.nowchess.coordinator.config.CoordinatorConfig
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import scala.jdk.CollectionConverters.*
|
||||
@@ -15,7 +15,7 @@ import de.nowchess.coordinator.grpc.CoreGrpcClient
|
||||
@ApplicationScoped
|
||||
class CacheEvictionManager:
|
||||
@Inject
|
||||
private var redissonClient: RedissonClient = uninitialized
|
||||
private var redis: RedisDataSource = uninitialized
|
||||
|
||||
@Inject
|
||||
private var config: CoordinatorConfig = uninitialized
|
||||
@@ -39,7 +39,7 @@ class CacheEvictionManager:
|
||||
log.info("Starting cache eviction scan")
|
||||
|
||||
val pattern = s"$redisPrefix:game:entry:*"
|
||||
val keys = redissonClient.getKeys.getKeysByPattern(pattern, 100)
|
||||
val keys = redis.key(classOf[String]).keys(pattern)
|
||||
|
||||
val now = System.currentTimeMillis()
|
||||
val idleThresholdMs = config.gameIdleThreshold.toMillis
|
||||
@@ -47,8 +47,7 @@ class CacheEvictionManager:
|
||||
var evictedCount = 0
|
||||
keys.asScala.foreach { key =>
|
||||
try
|
||||
val bucket = redissonClient.getBucket[String](key)
|
||||
val value = bucket.get()
|
||||
val value = redis.value(classOf[String]).get(key)
|
||||
if value != null then
|
||||
val gameId = key.stripPrefix(s"$redisPrefix:game:entry:")
|
||||
val lastUpdated = extractLastUpdatedTimestamp(value)
|
||||
@@ -57,7 +56,7 @@ class CacheEvictionManager:
|
||||
findInstanceWithGame(gameId).foreach { instance =>
|
||||
try
|
||||
coreGrpcClient.evictGames(instance.hostname, instance.grpcPort, List(gameId))
|
||||
bucket.delete()
|
||||
redis.key(classOf[String]).del(key)
|
||||
evictedCount += 1
|
||||
log.infof("Evicted idle game %s from %s", gameId, instance.instanceId)
|
||||
catch
|
||||
@@ -82,9 +81,8 @@ class CacheEvictionManager:
|
||||
private def findInstanceWithGame(gameId: String): Option[de.nowchess.coordinator.dto.InstanceMetadata] =
|
||||
try
|
||||
instanceRegistry.getAllInstances.find { instance =>
|
||||
val setKey = s"$redisPrefix:instance:${instance.instanceId}:games"
|
||||
val gameSet = redissonClient.getSet[String](setKey)
|
||||
gameSet.contains(gameId)
|
||||
val setKey = s"$redisPrefix:instance:${instance.instanceId}:games"
|
||||
redis.set(classOf[String]).sismember(setKey, gameId)
|
||||
}
|
||||
catch
|
||||
case ex: Exception =>
|
||||
|
||||
+6
-8
@@ -2,7 +2,7 @@ package de.nowchess.coordinator.service
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped
|
||||
import jakarta.inject.Inject
|
||||
import org.redisson.api.RedissonClient
|
||||
import io.quarkus.redis.datasource.RedisDataSource
|
||||
import scala.jdk.CollectionConverters.*
|
||||
import scala.compiletime.uninitialized
|
||||
import org.jboss.logging.Logger
|
||||
@@ -12,7 +12,7 @@ import de.nowchess.coordinator.grpc.CoreGrpcClient
|
||||
@ApplicationScoped
|
||||
class FailoverService:
|
||||
@Inject
|
||||
private var redissonClient: RedissonClient = uninitialized
|
||||
private var redis: RedisDataSource = uninitialized
|
||||
|
||||
@Inject
|
||||
private var instanceRegistry: InstanceRegistry = uninitialized
|
||||
@@ -50,9 +50,8 @@ class FailoverService:
|
||||
cleanupDeadInstance(instanceId)
|
||||
|
||||
private def getOrphanedGames(instanceId: String): List[String] =
|
||||
val setKey = s"$redisPrefix:instance:$instanceId:games"
|
||||
val gameSet = redissonClient.getSet[String](setKey)
|
||||
gameSet.readAll.asScala.toList
|
||||
val setKey = s"$redisPrefix:instance:$instanceId:games"
|
||||
redis.set(classOf[String]).smembers(setKey).asScala.toList
|
||||
|
||||
private def distributeGames(
|
||||
gameIds: List[String],
|
||||
@@ -87,7 +86,6 @@ class FailoverService:
|
||||
}
|
||||
|
||||
private def cleanupDeadInstance(instanceId: String): Unit =
|
||||
val setKey = s"$redisPrefix:instance:$instanceId:games"
|
||||
val gameSet = redissonClient.getSet[String](setKey)
|
||||
gameSet.delete()
|
||||
val setKey = s"$redisPrefix:instance:$instanceId:games"
|
||||
redis.key(classOf[String]).del(setKey)
|
||||
log.infof("Cleaned up games set for instance %s", instanceId)
|
||||
|
||||
+4
-6
@@ -5,7 +5,7 @@ import jakarta.inject.Inject
|
||||
import de.nowchess.coordinator.config.CoordinatorConfig
|
||||
import io.fabric8.kubernetes.client.KubernetesClient
|
||||
import io.fabric8.kubernetes.api.model.Pod
|
||||
import org.redisson.api.RedissonClient
|
||||
import io.quarkus.redis.datasource.RedisDataSource
|
||||
import scala.jdk.CollectionConverters.*
|
||||
import org.jboss.logging.Logger
|
||||
import scala.compiletime.uninitialized
|
||||
@@ -23,7 +23,7 @@ class HealthMonitor:
|
||||
private var instanceRegistry: InstanceRegistry = uninitialized
|
||||
|
||||
@Inject
|
||||
private var redissonClient: RedissonClient = uninitialized
|
||||
private var redis: RedisDataSource = uninitialized
|
||||
|
||||
private val log = Logger.getLogger(classOf[HealthMonitor])
|
||||
private var redisPrefix = "nowchess"
|
||||
@@ -47,10 +47,8 @@ class HealthMonitor:
|
||||
|
||||
private def checkRedisHeartbeat(instanceId: String): Boolean =
|
||||
try
|
||||
val key = s"$redisPrefix:instances:$instanceId"
|
||||
val bucket = redissonClient.getBucket[String](key)
|
||||
val ttl = bucket.remainTimeToLive()
|
||||
ttl > 0
|
||||
val key = s"$redisPrefix:instances:$instanceId"
|
||||
redis.key(classOf[String]).pttl(key) > 0
|
||||
catch
|
||||
case ex: Exception =>
|
||||
log.debugf(ex, "Redis heartbeat check failed for %s", instanceId)
|
||||
|
||||
+4
-5
@@ -2,7 +2,7 @@ package de.nowchess.coordinator.service
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped
|
||||
import jakarta.inject.Inject
|
||||
import org.redisson.api.RedissonClient
|
||||
import io.quarkus.redis.datasource.RedisDataSource
|
||||
import scala.jdk.CollectionConverters.*
|
||||
import scala.compiletime.uninitialized
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
@@ -12,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap
|
||||
@ApplicationScoped
|
||||
class InstanceRegistry:
|
||||
@Inject
|
||||
private var redissonClient: RedissonClient = uninitialized
|
||||
private var redis: RedisDataSource = uninitialized
|
||||
|
||||
private val mapper = ObjectMapper()
|
||||
private val instances = ConcurrentHashMap[String, InstanceMetadata]()
|
||||
@@ -28,9 +28,8 @@ class InstanceRegistry:
|
||||
instances.values.asScala.toList
|
||||
|
||||
def updateInstanceFromRedis(instanceId: String): Unit =
|
||||
val key = s"$redisPrefix:instances:$instanceId"
|
||||
val bucket = redissonClient.getBucket[String](key)
|
||||
val value = bucket.get()
|
||||
val key = s"$redisPrefix:instances:$instanceId"
|
||||
val value = redis.value(classOf[String]).get(key)
|
||||
if value != null then
|
||||
try
|
||||
val metadata = mapper.readValue(value, classOf[InstanceMetadata])
|
||||
|
||||
+6
-10
@@ -3,7 +3,7 @@ package de.nowchess.coordinator.service
|
||||
import jakarta.enterprise.context.ApplicationScoped
|
||||
import jakarta.inject.Inject
|
||||
import de.nowchess.coordinator.config.CoordinatorConfig
|
||||
import org.redisson.api.RedissonClient
|
||||
import io.quarkus.redis.datasource.RedisDataSource
|
||||
import org.jboss.logging.Logger
|
||||
import scala.compiletime.uninitialized
|
||||
import scala.concurrent.duration.*
|
||||
@@ -19,7 +19,7 @@ class LoadBalancer:
|
||||
private var instanceRegistry: InstanceRegistry = uninitialized
|
||||
|
||||
@Inject
|
||||
private var redissonClient: RedissonClient = uninitialized
|
||||
private var redis: RedisDataSource = uninitialized
|
||||
|
||||
@Inject
|
||||
private var coreGrpcClient: CoreGrpcClient = uninitialized
|
||||
@@ -107,9 +107,8 @@ class LoadBalancer:
|
||||
|
||||
private def getGamesToMove(instanceId: String, count: Int): List[String] =
|
||||
try
|
||||
val setKey = s"$redisPrefix:instance:$instanceId:games"
|
||||
val gameSet = redissonClient.getSet[String](setKey)
|
||||
gameSet.readAll.asScala.toList.take(count)
|
||||
val setKey = s"$redisPrefix:instance:$instanceId:games"
|
||||
redis.set(classOf[String]).smembers(setKey).asScala.toList.take(count)
|
||||
catch
|
||||
case ex: Exception =>
|
||||
log.debugf(ex, "Failed to get games for %s", instanceId)
|
||||
@@ -120,12 +119,9 @@ class LoadBalancer:
|
||||
val fromKey = s"$redisPrefix:instance:$fromInstanceId:games"
|
||||
val toKey = s"$redisPrefix:instance:$toInstanceId:games"
|
||||
|
||||
val fromSet = redissonClient.getSet[String](fromKey)
|
||||
val toSet = redissonClient.getSet[String](toKey)
|
||||
|
||||
gameIds.foreach { gameId =>
|
||||
fromSet.remove(gameId)
|
||||
toSet.add(gameId)
|
||||
redis.set(classOf[String]).srem(fromKey, gameId)
|
||||
redis.set(classOf[String]).sadd(toKey, gameId)
|
||||
}
|
||||
catch
|
||||
case ex: Exception =>
|
||||
|
||||
Reference in New Issue
Block a user