Projection was now built on listener events

Create ProjectionBus and use it with listeners
add EventStream::getByVersion
This commit is contained in:
2025-04-14 23:39:56 +02:00
parent 908cc888ad
commit 8c1eabb9f5
22 changed files with 126 additions and 89 deletions
@@ -4,7 +4,14 @@ import eventDemo.business.event.GameEventBus
import eventDemo.business.event.event.GameEvent
import eventDemo.libs.bus.Bus
import eventDemo.libs.bus.BusInMemory
import java.util.UUID
class GameEventBusInMemory :
GameEventBus(),
Bus<GameEvent> by BusInMemory()
GameEventBus,
Bus<GameEvent> by BusInMemory(),
Comparable<GameEventBusInMemory> {
private val instanceId: UUID = UUID.randomUUID()
override fun compareTo(other: GameEventBusInMemory): Int =
compareValues(instanceId, other.instanceId)
}
@@ -1,8 +1,9 @@
package eventDemo.adapter.infrastructureLayer.event.projection
import eventDemo.business.entity.GameId
import eventDemo.business.event.GameEventHandler
import eventDemo.business.event.GameEventBus
import eventDemo.business.event.GameEventStore
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.business.event.projection.gameList.GameList
import eventDemo.business.event.projection.gameList.GameListRepository
import eventDemo.business.event.projection.gameList.apply
@@ -10,9 +11,13 @@ import eventDemo.business.event.projection.gameState.GameState
import eventDemo.libs.event.projection.ProjectionSnapshotRepositoryInMemory
import eventDemo.libs.event.projection.SnapshotConfig
/**
* Manages [projections][GameList], their building and publication in the [bus][GameProjectionBus].
*/
class GameListRepositoryInMemory(
eventStore: GameEventStore,
eventHandler: GameEventHandler,
projectionBus: GameProjectionBus,
eventBus: GameEventBus,
snapshotConfig: SnapshotConfig = SnapshotConfig(),
) : GameListRepository {
private val projectionsSnapshot =
@@ -24,8 +29,10 @@ class GameListRepositoryInMemory(
)
init {
eventHandler.registerProjectionBuilder { event ->
projectionsSnapshot.applyAndPutToCache(event)
eventBus.subscribe { event ->
projectionsSnapshot
.applyAndPutToCache(event)
.also { projectionBus.publish(it) }
}
}
@@ -0,0 +1,18 @@
package eventDemo.adapter.infrastructureLayer.event.projection
import eventDemo.business.entity.GameId
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.libs.bus.Bus
import eventDemo.libs.bus.BusInMemory
import eventDemo.libs.event.projection.Projection
import java.util.UUID
class GameProjectionBusInMemory :
GameProjectionBus,
Bus<Projection<GameId>> by BusInMemory(),
Comparable<GameProjectionBusInMemory> {
private val instanceId: UUID = UUID.randomUUID()
override fun compareTo(other: GameProjectionBusInMemory): Int =
compareValues(instanceId, other.instanceId)
}
@@ -1,18 +1,23 @@
package eventDemo.adapter.infrastructureLayer.event.projection
import eventDemo.business.entity.GameId
import eventDemo.business.event.GameEventHandler
import eventDemo.business.event.GameEventBus
import eventDemo.business.event.GameEventStore
import eventDemo.business.event.event.GameEvent
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.business.event.projection.gameState.apply
import eventDemo.libs.event.projection.ProjectionSnapshotRepositoryInMemory
import eventDemo.libs.event.projection.SnapshotConfig
/**
* Manages [projections][GameState], their building and publication in the [bus][GameProjectionBus].
*/
class GameStateRepositoryInMemory(
eventStore: GameEventStore,
eventHandler: GameEventHandler,
projectionBus: GameProjectionBus,
eventBus: GameEventBus,
snapshotConfig: SnapshotConfig = SnapshotConfig(),
) : GameStateRepository {
private val projectionsSnapshot =
@@ -24,8 +29,11 @@ class GameStateRepositoryInMemory(
)
init {
eventHandler.registerProjectionBuilder { event ->
projectionsSnapshot.applyAndPutToCache(event)
// On new event was received, build snapshot and publish it to the projection bus
eventBus.subscribe { event ->
projectionsSnapshot
.applyAndPutToCache(event)
.also { projectionBus.publish(it) }
}
}
@@ -3,7 +3,7 @@ package eventDemo.adapter.interfaceLayer
import eventDemo.business.command.GameCommandHandler
import eventDemo.business.entity.GameId
import eventDemo.business.entity.Player
import eventDemo.business.event.eventListener.PlayerNotificationEventListener
import eventDemo.business.event.projection.projectionListener.PlayerNotificationListener
import eventDemo.business.notification.Notification
import eventDemo.libs.fromFrameChannel
import eventDemo.libs.toObjectChannel
@@ -24,7 +24,7 @@ import java.util.UUID
@DelicateCoroutinesApi
fun Route.gameWebSocket(
playerNotificationListener: PlayerNotificationEventListener,
playerNotificationListener: PlayerNotificationListener,
commandHandler: GameCommandHandler,
) {
authenticate {
@@ -43,7 +43,7 @@ fun Route.gameWebSocket(
private fun DefaultWebSocketServerSession.runWebSocket(
gameId: GameId,
commandHandler: GameCommandHandler,
playerNotificationListener: PlayerNotificationEventListener,
playerNotificationListener: PlayerNotificationListener,
) {
val currentPlayer = call.getPlayer()
val outgoingFrameChannel: SendChannel<Notification> = fromFrameChannel(outgoing)