+ return Mono.create(sink ->
+ {
+ ProducerRecord<String, MessageTo> record =
+ new ProducerRecord<>(
+ tp.topic(),
+ tp.partition(),
+ timestamp.toEpochSecond(zoneOffset),
+ chatRoomId.toString(),
+ MessageTo.of(key.getUsername(), key.getMessageId(), text));
+
+ producer.send(record, ((metadata, exception) ->
+ {
+ if (metadata != null)
+ {
+ // On successful send
+ {
+ // Emit new message
+ Message message = new Message(key, metadata.offset(), timestamp, text);
+ kafkaChatRoomService.addMessage(message);
+ }
+
+ sink.success();
+ }
+ else
+ {
+ // On send-failure
+ sink.error(exception);
+ }
+ }));
+ });
+ }
+
+ /**
+ * {@code synchronized} ist nicht nötig, da Aufruf immer indirekt über
+ * {@link #persistMessage(Message.MessageKey, LocalDateTime, String)}
+ */
+ protected void addMessage(Message message) throws MessageMutationException
+ {
+ Message existingMessage = messages.get(message.getKey());
+
+ // TODO: Ist der Test nötig, oder wird das durch den Kontrollierten Wechsel
+ // der Strategie ggf. schon abgefangen? Weil: Wenn es nur um die Sorge geht,
+ // das eine Nachricht schon "durch den Nutzer" anders geschrieben wurde,
+ // fängt dies bereits der ChatRoom ab.
+ // Die Überprüfung hier war vor dem Hintergrund der Sorge hinzugefügt worden,
+ // dass die Nachricht wegen Verschluckern in Kafka / beim Strategiewechsel / ??
+ // doppelt aufschlägt...
+ if (existingMessage == null)
+ {
+ messages.put(message.getKey(), message);
+ }
+ else
+ {
+ if (!existingMessage.getMessageText().equals(message.getMessageText()))
+ {
+ throw new MessageMutationException(existingMessage, message.getMessageText());
+ }
+
+ // Warn and emit existing message
+ log.warn(
+ "Keeping existing message with {}@{} for {}",
+ existingMessage.getSerialNumber(),
+ existingMessage.getTimestamp(),
+ existingMessage.getKey());
+ }