1 Aktuelle Idee für die Kafka-Anbindung
2 =====================================
4 - *Beobachtung:* Alle schreibenden Anfragen für Nachrichten müssen erst
5 durch `ChatHomeService.getChatRoom(int, UUID)` den zuständigen
6 `ChatRoom` ermitteln, bevor sie die Nachricht schreiben können.
7 - D.h., das Locking, das während einem Rebalance nötig ist, kann
8 *vollständig* in `KafkaChatHomeService` umgesetzt werden.
9 - In `KafkaChatRoomService` muss *keinerlei* Kontrolle mehr erfolgen,
10 ob der `ChatRoom` tatsächlich gerade in die Zuständigkeit der Instanz
11 fällt, da die Anfragen *hier nie ankommen*, wenn die Instanz nicht
12 zuständig ist, da sie dann bereits in `getChatRoom(int, UUID)`
14 - Die in der Domain-Klasse `ChatRoom` definierte Logik, für die
15 Behandlung doppelter Nachrichten *ist vollständig valide*, da Anfragen
16 für einen bestimmten `ChatRoom` dort (bei korrekt implementiertem Locking
17 in `KafkaChatHomeService`) nur ankommen, wenn die Instanz *tatsächlich*
18 für den `ChatRoom` zuständig ist.
19 - D.h. insbesondere auch, dass die Antwort dort (also in dem `ChatRoom`)
20 erst ankommen, wenn dieser *vollständig geladen* ist, so dass die lokale
21 Kontrolle auf doppelte Nachrichten logisch gültig ist.
22 - *Anforderung:* Wenn ein Rebalance aktiv ist, wird die Instanz gelockt.
23 - Das Locking erfolg in `KafkaChatRoomService`, durch das alle Anfragen
24 durchgreifen müssen, so dass hier *zentral alle Aktionen* auf einzelnen
25 `ChatRoom`-Instanzen *unterbunden* werden können.
26 - *Vereinfachung:* Wenn `KafkaChatRoomService` gelockt ist, wird für alle
27 Zugriffe eine `ShardNotOwnedException` erzeugt.
28 - Dadurch wird das Zustands-Handling *extrem vereinfacht*, da Anfragen,
29 die *während* einem Rebalance auflaufen
30 - *Lade-Modus vs. Default-Modus:*
31 - Nur während des Lade-Modus *liest* die `KafkaChatRoomServcie`-Instanz
32 tatsächlich die Nachrichten aus den zugeordneten Partitionen.
33 - Im Default-Modus *schreibt* sie die Nachrichten nur in die Partitionen
34 und speichert sie lokal ab, sobald die *Bestätigung durch den `Producer`*
36 - D.h. insbesondere, dass der `KafkaConsumer` im Default-Modus für alle
37 zugeordneten Partitionen *pausiert* wird!
38 - Damit die Offset-Positon nicht unnötig zurückfällt, sollte ggf.
39 regelmäßig für alle zugeordneten Partitionen ein Seek auf die zuletzt
40 vom Producer bestätigt geschriebenen Offsets durchgeführt werden.
41 - *Beachte:_ Dies ist nicht nötig, wenn die Offsets eh in den lokal
42 gespeicherten Daten gehalten und aus diesen wiederhergestellt werden!
43 - *Umsetzungs-Details:*
44 - Da die in dem Interface `ConsumerRebalanceListener` definierten Methoden
45 in einem zeitkritischem Setting laufen, muss das eigentliche Laden der
46 `ChatRoom`-Zustände separat erfolgen, so dass die Kontrolle schnell an
47 den `KafkaConsumer` zurückgegeben werden kann.
48 - Dafür muss der `KafkaChatRoomService` in einen speziellen Lade-Modus
49 wechseln, der aktiv ist, bis die `ChatRoom`-Instanzen für alle durch
50 den Rebalance zugeteilten Partitionen aus dem Log wiederhergestellt
52 - Das Lock der `KafkaChatRoomService`-Instanz muss während dieser
53 gesmaten Phase aufrecht erhalten werden: Es wird erst gelöst, wenn
54 die Instanz in den normalen Modus zurückwechselt.
55 - D.h. insbesondere auch, dass während dieser ganzen Phase _alle_
56 Anfragen mit `ShardNotOwnedException` abgelehnt werden!
57 - Eine besondere Herausforderung sind *erneute* Rebalances, die
58 Auftreten, *während* der `KafkaChatRoomService` sich noch in einem
59 durch einen vorherigen Rebalance ausgelösten Lade-Modus befindet!