Ich experimentiere mit Event Sourcing mit Scala (ich bin neu in beiden Bereichen).Event Sourcing mit Scala und unveränderlichen Objekten: Ist es effizient?
Ich möchte alles so unveränderlich wie möglich halten, einschließlich der Aggregatwurzeln. Als Basis folge ich Greg Youngs Beispiel von ES und CQRS (https://github.com/gregoryyoung/m-r, implementiert in C#) und "übersetze" diesen Code in Scala.
Frage ist über das Objekt Regeneration von Ereignisspeichern:
Da mein Aggregat Wurzeln für jedes Ereignis von bestimmten Entität unveränderlich ist, neues Objekt erstellt wird. Um beispielsweise eine Entität mit 100 Ereignissen neu zu generieren, sollten 100 Instanzen dieser Entität erstellt werden und die letzte Instanz wird der Endstatus sein.
Ist es effizient oder zu viel Aufwand?
(Ich denke max Ereignisse zu regenerieren wird 100 sein, da ich Snapshots speichern werde).
Hier ist mein Code:
Ereignis Merkmal
trait Event {
}
Basisklasse für Aggregate
abstract class AggregateRoot {
...
// HERE ENTITY IS REGENERATED FROM EVENTS AND EACH TIME NEW INSTANCE IS CREATED FOR EACH ENTITY
def loadFromHistory(history: Seq[Event]): AggregateRoot = {
var aggregate = this
history.foreach(e => aggregate = applyChange(e, false))
aggregate
}
def applyChange(event: Event, isNew: Boolean): AggregateRoot
...
}
Produkt Aggregate
case class Product(id: Long, name: String, status: Int, uncommittedChanges: Seq[Event]) extends AggregateRoot {
def changeName(name: String): Product = {
applyChange(ProductNameChangedEvent(id = this.id, name = name))
}
def applyChange(event: Event, isNew: Boolean = true): Product = {
val changedProduct = event match {
case e: ProductCreatedEvent => applyChange(e)
case e: ProductNameChangedEvent => applyChange(e)
case _ => throw new Exception("No event applier")
}
// ALSO HERE I'M COPING ALL THE LOCAL (NEW) CHANGES (THAT ARE NOT STORED IN EVENT STORE YET)
if (isNew) changedProduct.copy(uncommittedChanges = uncommittedChanges :+ event) else changedProduct
}
def applyChange(event: ProductCreatedEvent): Product = {
this.copy(id = event.id, name = event.name)
}
def applyChange(event: ProductNameChangedEvent): Product = {
this.copy(id = event.id, name = event.name)
}
...
}
Jede Antwort hier wird zu allgemein und breit sein. Wie immer, benchmarken Sie Ihren Code, um zu sehen, ob der Aufwand zu hoch ist. Wenn dies der Fall ist, suchen Sie die Hotpfade und versuchen Sie, die Zuweisungen möglichst zu minimieren. –