feat(coordinator): add configurable coordinator settings and enhance WebSocket connection handling
Build & Test (NowChessSystems) TeamCity build failed

This commit is contained in:
2026-04-26 22:33:16 +02:00
parent 64d5afa4d1
commit 6b59e68e04
27 changed files with 873 additions and 617 deletions
+3
View File
@@ -63,12 +63,15 @@ dependencies {
implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
implementation("io.quarkus:quarkus-rest")
implementation("io.quarkus:quarkus-rest-jackson")
implementation("io.quarkus:quarkus-grpc")
implementation("io.quarkus:quarkus-arc")
implementation("io.quarkus:quarkus-config-yaml")
implementation("io.quarkus:quarkus-smallrye-health")
implementation("io.quarkus:quarkus-smallrye-openapi")
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.fabric8:kubernetes-client:6.13.0")
@@ -0,0 +1,27 @@
{
"reflection": [
{ "type": "scala.Tuple1[]" },
{ "type": "scala.Tuple2[]" },
{ "type": "scala.Tuple3[]" },
{ "type": "scala.Tuple4[]" },
{ "type": "scala.Tuple5[]" },
{ "type": "scala.Tuple6[]" },
{ "type": "scala.Tuple7[]" },
{ "type": "scala.Tuple8[]" },
{ "type": "scala.Tuple9[]" },
{ "type": "scala.Tuple10[]" },
{ "type": "scala.Tuple11[]" },
{ "type": "scala.Tuple12[]" },
{ "type": "scala.Tuple13[]" },
{ "type": "scala.Tuple14[]" },
{ "type": "scala.Tuple15[]" },
{ "type": "scala.Tuple16[]" },
{ "type": "scala.Tuple17[]" },
{ "type": "scala.Tuple18[]" },
{ "type": "scala.Tuple19[]" },
{ "type": "scala.Tuple20[]" },
{ "type": "scala.Tuple21[]" },
{ "type": "scala.Tuple22[]" },
{ "type": "com.fasterxml.jackson.module.scala.introspect.PropertyDescriptor[]" }
]
}
@@ -1,10 +1,22 @@
quarkus:
application.name: nowchess-coordinator
http.port: 8086
grpc.server.port: 9086
config.yaml.enabled: true
rest-client.connection-timeout: 5000
rest-client.read-timeout: 10000
application:
name: nowchess-coordinator
http:
port: 8086
grpc:
server:
port: 9086
rest-client:
connection-timeout: 5000
read-timeout: 10000
smallrye-openapi:
info-title: NowChess Coordinator Service
info-version: 1.0.0
info-description: Coordination endpoints for instance health, balancing, failover, and scaling
path: /openapi
swagger-ui:
always-include: true
path: /swagger-ui
nowchess:
redis:
@@ -18,7 +30,7 @@ nowchess:
rebalance-interval: 30s
rebalance-min-interval: 60s
heartbeat-ttl: 5s
stream-heartbeat-interval: 200ms
stream-heartbeat-interval: PT0.2S
cache-eviction-interval: 10m
game-idle-threshold: 45m
auto-scale-enabled: false
@@ -34,6 +46,5 @@ nowchess:
# dev profile
"%dev":
quarkus:
log.level: DEBUG
log.category:
"de.nowchess": DEBUG
log:
level: DEBUG
@@ -5,51 +5,51 @@ import io.smallrye.config.WithName
import java.time.Duration
@ConfigMapping(prefix = "nowchess.coordinator")
class CoordinatorConfig:
trait CoordinatorConfig:
@WithName("max-games-per-core")
def maxGamesPerCore: Int = ???
def maxGamesPerCore: Int
@WithName("max-deviation-percent")
def maxDeviationPercent: Int = ???
def maxDeviationPercent: Int
@WithName("rebalance-interval")
def rebalanceInterval: Duration = ???
def rebalanceInterval: Duration
@WithName("rebalance-min-interval")
def rebalanceMinInterval: Duration = ???
def rebalanceMinInterval: Duration
@WithName("heartbeat-ttl")
def heartbeatTtl: Duration = ???
def heartbeatTtl: Duration
@WithName("stream-heartbeat-interval")
def streamHeartbeatInterval: Duration = ???
def streamHeartbeatInterval: Duration
@WithName("cache-eviction-interval")
def cacheEvictionInterval: Duration = ???
def cacheEvictionInterval: Duration
@WithName("game-idle-threshold")
def gameIdleThreshold: Duration = ???
def gameIdleThreshold: Duration
@WithName("auto-scale-enabled")
def autoScaleEnabled: Boolean = ???
def autoScaleEnabled: Boolean
@WithName("scale-up-threshold")
def scaleUpThreshold: Double = ???
def scaleUpThreshold: Double
@WithName("scale-down-threshold")
def scaleDownThreshold: Double = ???
def scaleDownThreshold: Double
@WithName("scale-min-replicas")
def scaleMinReplicas: Int = ???
def scaleMinReplicas: Int
@WithName("scale-max-replicas")
def scaleMaxReplicas: Int = ???
def scaleMaxReplicas: Int
@WithName("k8s-namespace")
def k8sNamespace: String = ???
def k8sNamespace: String
@WithName("k8s-rollout-name")
def k8sRolloutName: String = ???
def k8sRolloutName: String
@WithName("k8s-rollout-label-selector")
def k8sRolloutLabelSelector: String = ???
def k8sRolloutLabelSelector: String
@@ -0,0 +1,18 @@
package de.nowchess.coordinator.config
import com.fasterxml.jackson.core.Version
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import io.quarkus.jackson.ObjectMapperCustomizer
import jakarta.inject.Singleton
@Singleton
class JacksonConfig extends ObjectMapperCustomizer:
def customize(mapper: ObjectMapper): Unit =
mapper.registerModule(new DefaultScalaModule() {
override def version(): Version =
// scalafix:off DisableSyntax.null
new Version(2, 21, 1, null, "com.fasterxml.jackson.module", "jackson-module-scala")
// scalafix:on DisableSyntax.null
})
@@ -0,0 +1,14 @@
package de.nowchess.coordinator.config
import de.nowchess.coordinator.dto.InstanceMetadata
import de.nowchess.coordinator.resource.MetricsDto
import io.quarkus.runtime.annotations.RegisterForReflection
@RegisterForReflection(
targets = Array(
classOf[InstanceMetadata],
classOf[MetricsDto],
),
)
class NativeReflectionConfig