RailsEventStore hat sich in der Ruby on Rails Community als zuverlässiges Werkzeug für die Event-Sourcing-Implementierung etabliert. Die stetige Weiterentwicklung der Bibliothek zielt dabei nicht nur auf Stabilität, sondern auch auf die Optimierung der Performance und Entwicklerfreundlichkeit ab. Ein spannendes Beispiel dafür ist das Feature des Batch Mappers, dessen Entstehungsgeschichte exemplarisch zeigt, wie reale Anwenderbedürfnisse zur Erweiterung eines Frameworks führen können und welche Vorteile dies für die gesamte Community bringt. Der Ursprung des Batch Mappers hängt eng mit einem konkreten Performance-Problem zusammen, das ein Anwender namens Bert in seinem Projekt mit RailsEventStore erlebte. Sein Event Store enthielt eine große Menge an verschlüsselten Ereignisdaten.
RailsEventStore bot mit dem EncryptionMapper zwar eine Möglichkeit zur automatischen Verschlüsselung und Entschlüsselung von Domain-Events, doch genau diese Einfachheit führte in Berts Fall zu erheblichen Performance-Einbußen. Die Ursache lag darin, wie der Verschlüsselungsprozess organisiert war: Für jede einzelne Event-Instanz wurde der Schlüssel aus einer externen Schlüsselverwaltungssoftware (KMS) abgefragt, was bei einer großen Menge an Events eine enorme Anzahl an Netzwerkaufrufen bedeutete. Dieses Problem fiel nicht nur in der Praxis von Bert auf, sondern thematisiert einen häufigen Engpass bei der Arbeit mit verschlüsselten Daten in Event Stores. Es geht dabei um den Balanceakt zwischen Sicherheit, Performance und Skalierbarkeit. Einerseits sind lokale Zwischenspeicherungen von Schlüsseln problematisch, da sie den Schutz sensibler Daten gefährden könnten.
Andererseits führt jede externe Abfrage zu einem deutlichen Flaschenhals, wenn viele Events zu verarbeiten sind. Bert schlug daraufhin in einem Pull Request (PR) eine neue Implementierung vor, welche das Konzept der Batch-Verarbeitung von Events in den Mapper einführt. Statt jeden Event einzeln zu bearbeiten, sollten diese in Gruppen verarbeitet werden. Das bedeutete, dass vor der Transformation der Events gemeinsam alle benötigten Schlüssel aus dem KMS auf einmal abgefragt werden konnten. Ein solcher „Batch Mapper“ reduziert die Anzahl der Zugriffe auf das externe System drastisch und beschleunigt dadurch die Verarbeitung enorm.
Das RailsEventStore-Team nahm Bert’s Vorschlag als Ausgangspunkt für eine intensive Prüfung und Erweiterung auf. In diesem Prozess setzten sie auch Mutant-Tests ein, eine spezielle Form automatisierter Tests, um die Robustheit und Qualität des neuen Codes sicherzustellen. Daraus entstand eine optimierte Batch-Mapping-Funktionalität, die als experimentelles Feature implementiert wurde. Damit ist das neue API zwar noch nicht final stabil, ermöglicht jedoch frühe Tests in produktiven Umgebungen und liefert wertvolles Feedback zur weiteren Entwicklung. Die technische Umsetzung des Batch Mappers basiert auf einem simplen, aber wirkungsvollen Prinzip: RailsEventStore liest Events sowieso in Batches aus der Datenbank.
Das war schon immer so, nur wurden diese in der Mapper-Schicht wieder einzeln verarbeitet. Wenn man jedoch direkt die Batterien, also Gruppen von Events, übernimmt und diese gemeinsam transformiert, lassen sich Operationen viel effizienter gestalten. Aktuelle Mapper in RailsEventStore besitzen die Methoden record_to_event und event_to_record, welche einzelne Datenbankeinträge beziehungsweise Events in die jeweils andere Form umwandeln. Die neue Schnittstelle erweitert dies um records_to_events und events_to_records und akzeptiert somit Gruppen von Events auf einmal. Das ermöglicht Mappern, die die Batch-Verarbeitung implementieren, ihre Logik auf diese Menge anzuwenden und speziell beim Zugriff auf externe Schlüssel-Repositorien deutlich weniger API-Aufrufe zu tätigen.
Trotz der Einführung des neuen Features wurde von den Entwicklern großer Wert auf Rückwärtskompatibilität gelegt. Viele Projekte nutzen RailsEventStore in umfangreichen und heterogenen Codebasen, deshalb sollen Updates nahtlos erfolgen können, ohne dass Entwickler ihren Code anpassen müssen. Um das zu erreichen, schirmt die Bibliothek Mapper, die nur Einzelverarbeitung unterstützen, intern mit der Klasse BatchMapper ab. Diese übernimmt das iterative Verarbeiten von einzelnen Events in Batches, sodass alle erwähnten Vorteile von der Framework-Seite ausgegeben werden, ohne dass die bestehende Implementierung geändert werden muss. Wenn ein Mapper hingegen bereits Batch-Verarbeitung unterstützt, wird dieser direkt verwendet.
Dadurch haben Entwickler die Freiheit, entweder die bestehende Einzelverarbeitungs-Logik beizubehalten oder vorhandene Mapper selbst um Batch-Funktionalität zu erweitern. Das Resultat aus dieser Flexibilität ist letztlich eine bessere Performance für alle Nutzer – vor allem bei Systemen mit sehr vielen Events und externen Schlüsselmanagementsystemen. Ein Beispiel verdeutlicht die Vorteile: Ein benutzerdefinierter EncryptionMapper überschreibt durch Batch-Verarbeitung die Methoden records_to_events und events_to_records, um vor der eigentlichen Konvertierung alle benötigten Schlüssel auf einmal aus dem KMS zu holen. Das reduziert einzelne Netzwerkaufrufe und hält gleichzeitig den Speicherbedarf niedrig, da nicht alle Schlüssel dauerhaft gecacht werden müssen. Ein solcher Ansatz bringt deutliche Zeitersparnis und verhindert, dass der Event Store bei zunehmendem Datenvolumen langsamer wird.
Die Relevanz dieses Features geht aber über das konkrete Verschlüsselungsproblem hinaus. Batch-Verarbeitung spiegelt einen grundlegenden Trend in der Softwareentwicklung wider, der auf Effizienz und Skalierbarkeit zielt. Besonders im Event Sourcing und Domain-Driven Design, wo große Mengen an Domain-Events die zentrale Rolle spielen, sind performante Mapper ein kritischer Faktor für die Gesamtsystem-Performance. Darüber hinaus eröffnet der Batch Mapper Raum für weitergreifende Optimierungen, wie beispielsweise komplexere Caching-Strategien, parallele Datenverarbeitung und bessere Integration mit externen Services. Auch für zukünftige Erweiterungen wie asynchrone Read-Model-Bildungen kann das Konzept von Batch-Verarbeitung einen wichtigen Beitrag leisten.
Ein weiterer Vorteil ist die verbesserte Testbarkeit. Da ganz Batches von Events verarbeitet werden, lassen sich Tests präziser und umfassender gestalten. Zusätzlich ermöglichen die neuen APIs differenziertere Fehlerbehandlungen und ermöglichen Optimierungen im Fehlerfall auf Batch-Ebene. Entwickler, die RailsEventStore bereits heute nutzen oder planen, die Bibliothek in ihren Projekten einzusetzen, sollten die experimentelle Batch-Mapper Funktion im Auge behalten. Das Feature ist zwar noch im stabilen Entwicklungsstadium, bietet aber einen klaren Mehrwert vor allem dann, wenn große Event-Mengen mit aufwändigen Operationen wie etwa Verschlüsselung oder Transformation verbunden sind.