fix(events): suppress stream poll loop in test profile
Build & Test (NowChessSystems) TeamCity build failed
Build & Test (NowChessSystems) TeamCity build failed
CDI fires StartupEvent to all observer beans regardless of @InjectMock substitution, causing GameCreationStreamClient and GameCreationStreamListener to start their poll loops during @QuarkusTest even when mocked. Without Redis configured in account tests, this floods logs with NPE stack traces from the unconfigured RedisDataSource synthetic bean. - Switch @Startup/@PostConstruct to @Observes StartupEvent on both beans - Guard startup body with nowchess.game-creation-stream.enabled (default true) - Disable the flag in modules/account/src/test/resources/application.yml Mirrors the nowchess.coordinator.enabled pattern in InstanceHeartbeatService. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+13
-11
@@ -8,10 +8,11 @@ import de.nowchess.api.player.PlayerType
|
|||||||
import de.nowchess.api.event.{EventEnvelope, EventType}
|
import de.nowchess.api.event.{EventEnvelope, EventType}
|
||||||
import io.quarkus.redis.datasource.RedisDataSource
|
import io.quarkus.redis.datasource.RedisDataSource
|
||||||
import io.quarkus.redis.datasource.stream.{StreamMessage, XAddArgs, XGroupCreateArgs, XReadGroupArgs}
|
import io.quarkus.redis.datasource.stream.{StreamMessage, XAddArgs, XGroupCreateArgs, XReadGroupArgs}
|
||||||
import io.quarkus.runtime.Startup
|
import io.quarkus.runtime.StartupEvent
|
||||||
import jakarta.annotation.PostConstruct
|
|
||||||
import jakarta.enterprise.context.ApplicationScoped
|
import jakarta.enterprise.context.ApplicationScoped
|
||||||
|
import jakarta.enterprise.event.Observes
|
||||||
import jakarta.inject.Inject
|
import jakarta.inject.Inject
|
||||||
|
import org.eclipse.microprofile.config.inject.ConfigProperty
|
||||||
import org.eclipse.microprofile.context.ManagedExecutor
|
import org.eclipse.microprofile.context.ManagedExecutor
|
||||||
import org.jboss.logging.Logger
|
import org.jboss.logging.Logger
|
||||||
import scala.compiletime.uninitialized
|
import scala.compiletime.uninitialized
|
||||||
@@ -21,7 +22,6 @@ import java.time.Duration
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.util.concurrent.{CompletableFuture, ConcurrentHashMap, TimeUnit}
|
import java.util.concurrent.{CompletableFuture, ConcurrentHashMap, TimeUnit}
|
||||||
|
|
||||||
@Startup
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
class GameCreationStreamClient:
|
class GameCreationStreamClient:
|
||||||
|
|
||||||
@@ -30,6 +30,8 @@ class GameCreationStreamClient:
|
|||||||
@Inject var redisConfig: RedisConfig = uninitialized
|
@Inject var redisConfig: RedisConfig = uninitialized
|
||||||
@Inject var objectMapper: ObjectMapper = uninitialized
|
@Inject var objectMapper: ObjectMapper = uninitialized
|
||||||
@Inject var executor: ManagedExecutor = uninitialized
|
@Inject var executor: ManagedExecutor = uninitialized
|
||||||
|
@ConfigProperty(name = "nowchess.game-creation-stream.enabled", defaultValue = "true")
|
||||||
|
private var streamEnabled: Boolean = true
|
||||||
// scalafix:on DisableSyntax.var
|
// scalafix:on DisableSyntax.var
|
||||||
|
|
||||||
private val log = Logger.getLogger(classOf[GameCreationStreamClient])
|
private val log = Logger.getLogger(classOf[GameCreationStreamClient])
|
||||||
@@ -44,14 +46,14 @@ class GameCreationStreamClient:
|
|||||||
private def requestStream: String = s"${redisConfig.prefix}:game-creation"
|
private def requestStream: String = s"${redisConfig.prefix}:game-creation"
|
||||||
private def responseStream: String = s"${redisConfig.prefix}:game-creation-response"
|
private def responseStream: String = s"${redisConfig.prefix}:game-creation-response"
|
||||||
|
|
||||||
@PostConstruct
|
def start(@Observes _ev: StartupEvent): Unit =
|
||||||
def start(): Unit =
|
if streamEnabled then
|
||||||
createGroupIfAbsent()
|
createGroupIfAbsent()
|
||||||
executor.submit(
|
executor.submit(
|
||||||
new Runnable:
|
new Runnable:
|
||||||
def run(): Unit = pollLoop(),
|
def run(): Unit = pollLoop(),
|
||||||
)
|
)
|
||||||
log.infof("Game-creation response listener started (consumer=%s)", consumerId)
|
log.infof("Game-creation response listener started (consumer=%s)", consumerId)
|
||||||
|
|
||||||
def createGame(req: CoreCreateGameRequest): GameCreationResponseDto =
|
def createGame(req: CoreCreateGameRequest): GameCreationResponseDto =
|
||||||
val correlationId = UUID.randomUUID().toString
|
val correlationId = UUID.randomUUID().toString
|
||||||
|
|||||||
@@ -34,3 +34,5 @@ nowchess:
|
|||||||
secret: test-secret
|
secret: test-secret
|
||||||
auth:
|
auth:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
game-creation-stream:
|
||||||
|
enabled: false
|
||||||
|
|||||||
+13
-11
@@ -7,10 +7,11 @@ import de.nowchess.chess.config.RedisConfig
|
|||||||
import de.nowchess.chess.service.GameCreationService
|
import de.nowchess.chess.service.GameCreationService
|
||||||
import io.quarkus.redis.datasource.RedisDataSource
|
import io.quarkus.redis.datasource.RedisDataSource
|
||||||
import io.quarkus.redis.datasource.stream.{StreamMessage, XAddArgs, XGroupCreateArgs, XReadGroupArgs}
|
import io.quarkus.redis.datasource.stream.{StreamMessage, XAddArgs, XGroupCreateArgs, XReadGroupArgs}
|
||||||
import io.quarkus.runtime.Startup
|
import io.quarkus.runtime.StartupEvent
|
||||||
import jakarta.annotation.PostConstruct
|
|
||||||
import jakarta.enterprise.context.ApplicationScoped
|
import jakarta.enterprise.context.ApplicationScoped
|
||||||
|
import jakarta.enterprise.event.Observes
|
||||||
import jakarta.inject.Inject
|
import jakarta.inject.Inject
|
||||||
|
import org.eclipse.microprofile.config.inject.ConfigProperty
|
||||||
import org.eclipse.microprofile.context.ManagedExecutor
|
import org.eclipse.microprofile.context.ManagedExecutor
|
||||||
import org.jboss.logging.Logger
|
import org.jboss.logging.Logger
|
||||||
import scala.compiletime.uninitialized
|
import scala.compiletime.uninitialized
|
||||||
@@ -19,7 +20,6 @@ import scala.util.{Failure, Success, Try}
|
|||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@Startup
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
class GameCreationStreamListener:
|
class GameCreationStreamListener:
|
||||||
|
|
||||||
@@ -29,6 +29,8 @@ class GameCreationStreamListener:
|
|||||||
@Inject var creationService: GameCreationService = uninitialized
|
@Inject var creationService: GameCreationService = uninitialized
|
||||||
@Inject var executor: ManagedExecutor = uninitialized
|
@Inject var executor: ManagedExecutor = uninitialized
|
||||||
@Inject var redisConfig: RedisConfig = uninitialized
|
@Inject var redisConfig: RedisConfig = uninitialized
|
||||||
|
@ConfigProperty(name = "nowchess.game-creation-stream.enabled", defaultValue = "true")
|
||||||
|
private var streamEnabled: Boolean = true
|
||||||
// scalafix:on DisableSyntax.var
|
// scalafix:on DisableSyntax.var
|
||||||
|
|
||||||
private val log = Logger.getLogger(classOf[GameCreationStreamListener])
|
private val log = Logger.getLogger(classOf[GameCreationStreamListener])
|
||||||
@@ -41,14 +43,14 @@ class GameCreationStreamListener:
|
|||||||
private def responseStream: String = s"${redisConfig.prefix}:game-creation-response"
|
private def responseStream: String = s"${redisConfig.prefix}:game-creation-response"
|
||||||
private def dlqStream: String = s"${redisConfig.prefix}:dlq"
|
private def dlqStream: String = s"${redisConfig.prefix}:dlq"
|
||||||
|
|
||||||
@PostConstruct
|
def start(@Observes _ev: StartupEvent): Unit =
|
||||||
def start(): Unit =
|
if streamEnabled then
|
||||||
createGroupIfAbsent()
|
createGroupIfAbsent()
|
||||||
executor.submit(
|
executor.submit(
|
||||||
new Runnable:
|
new Runnable:
|
||||||
def run(): Unit = pollLoop(),
|
def run(): Unit = pollLoop(),
|
||||||
)
|
)
|
||||||
log.infof("Game-creation request listener started (consumer=%s)", consumerId)
|
log.infof("Game-creation request listener started (consumer=%s)", consumerId)
|
||||||
|
|
||||||
private def createGroupIfAbsent(): Unit =
|
private def createGroupIfAbsent(): Unit =
|
||||||
Try(
|
Try(
|
||||||
|
|||||||
Reference in New Issue
Block a user