package eventDemo.libs.event import eventDemo.libs.bus.Bus import io.github.oshai.kotlinlogging.withLoggingContext import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock /** * Handle the event to dispatch it to store, bus and projections builders */ class EventHandlerImpl, ID : AggregateId>( private val eventBus: Bus, private val eventStore: EventStore, private val versionBuilder: VersionBuilder, ) : EventHandler { private val locks: ConcurrentHashMap = ConcurrentHashMap() /** * Build Event then send it to the event store and bus. */ override fun handle( aggregateId: ID, buildEvent: (version: Int) -> E, ): E = withLoggingContext("aggregateId" to aggregateId.toString()) { locks // Get lock for the aggregate .computeIfAbsent(aggregateId) { ReentrantLock() } .withLock { // Build event with the version buildEvent(versionBuilder.buildNextVersion(aggregateId)) // then publish it to the event store .also { withLoggingContext("event" to it.toString()) { eventStore.publish(it) eventBus.publish(it) } } } } }