refactore: Renamed `ChatroomFactory` to `ChatHomeService` -- Move
[demos/kafka/chat] / src / main / java / de / juplo / kafka / chat / backend / domain / Chatroom.java
index c05fda0..2261e02 100644 (file)
@@ -1,7 +1,6 @@
 package de.juplo.kafka.chat.backend.domain;
 
 import lombok.Getter;
-import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
@@ -11,7 +10,6 @@ import java.time.LocalDateTime;
 import java.util.*;
 
 
-@RequiredArgsConstructor
 @Slf4j
 public class Chatroom
 {
@@ -19,8 +17,23 @@ public class Chatroom
   private final UUID id;
   @Getter
   private final String name;
-  private final PersistenceStrategy persistence;
-  private final Sinks.Many<Message> sink = Sinks.many().multicast().onBackpressureBuffer();
+  private final ChatroomService chatroomService;
+  private final int bufferSize;
+  private Sinks.Many<Message> sink;
+
+  public Chatroom(
+      UUID id,
+      String name,
+      ChatroomService chatroomService,
+      int bufferSize)
+  {
+    this.id = id;
+    this.name = name;
+    this.chatroomService = chatroomService;
+    this.bufferSize = bufferSize;
+    this.sink = createSink();
+  }
+
 
   synchronized public Mono<Message> addMessage(
       Long id,
@@ -28,24 +41,47 @@ public class Chatroom
       String user,
       String text)
   {
-    return persistence
+    return chatroomService
         .persistMessage(Message.MessageKey.of(user, id), timestamp, text)
-        .doOnNext(message -> sink.tryEmitNext(message).orThrow());
+        .doOnNext(message ->
+        {
+          Sinks.EmitResult result = sink.tryEmitNext(message);
+          if (result.isFailure())
+          {
+            log.warn("Emitting of message failed with {} for {}", result.name(), message);
+          }
+        });
   }
 
 
   public Mono<Message> getMessage(String username, Long messageId)
   {
-    return persistence.getMessage(Message.MessageKey.of(username, messageId));
+    Message.MessageKey key = Message.MessageKey.of(username, messageId);
+    return chatroomService.getMessage(key);
+  }
+
+  synchronized public Flux<Message> listen()
+  {
+    return sink
+        .asFlux()
+        .doOnCancel(() -> sink = createSink()); // Sink hast to be recreated on auto-cancel!
   }
 
-  public Flux<Message> listen()
+  public Flux<Message> getMessages()
   {
-    return sink.asFlux();
+    return getMessages(0, Long.MAX_VALUE);
   }
 
   public Flux<Message> getMessages(long first, long last)
   {
-    return persistence.getMessages(first, last);
+    return chatroomService.getMessages(first, last);
+  }
+
+  private Sinks.Many<Message> createSink()
+  {
+    return Sinks
+        .many()
+        .multicast()
+        .onBackpressureBuffer(bufferSize);
   }
 }