Interface StreamMessage<T>

Type Parameters:
T - the type of element signaled
All Superinterfaces:
org.reactivestreams.Publisher<T>
All Known Subinterfaces:
HttpMessage, HttpRequest, HttpRequestWriter, HttpResponse, HttpResponseWriter
All Known Implementing Classes:
DefaultStreamMessage, DeferredStreamMessage, EmptyFixedStreamMessage, FilteredHttpRequest, FilteredHttpResponse, FilteredStreamMessage, OneElementFixedStreamMessage, PublisherBasedStreamMessage, RegularFixedStreamMessage, StreamMessageWrapper, ThreeElementFixedStreamMessage, TwoElementFixedStreamMessage

public interface StreamMessage<T> extends org.reactivestreams.Publisher<T>
A variant of Reactive Streams Publisher, which allows only one Subscriber. Unlike a usual Publisher, a StreamMessage can stream itself only once. It has the following additional operations on top of what the Reactive Streams API provides:

When is a StreamMessage fully consumed?

A StreamMessage is complete (or 'fully consumed') when:

  • the Subscriber consumes all elements and Subscriber.onComplete() is invoked,
  • an error occurred and Subscriber.onError(Throwable) is invoked,
  • the Subscription has been cancelled or
  • abort() has been requested.

When fully consumed, the CompletableFuture returned by whenComplete() will complete, which you may find useful because Subscriber does not notify you when a stream is cancelled.

Publication and Consumption of pooled HttpData objects

StreamMessage will discard the publication request of a pooled HttpData silently and release it automatically when the publication is attempted after the stream is closed.

For pooled HttpData, StreamMessage will convert them into its unpooled version that never leak, so that the Subscriber does not need to worry about leaks.

If a Subscriber does not want a StreamMessage to make a copy of a pooled HttpData, specify SubscriptionOption.WITH_POOLED_OBJECTS when you subscribe. Note that the Subscriber is responsible for releasing the objects given with Subscriber.onNext(Object).

Subscriber.onError(Throwable) is invoked when any exception is raised except the CancelledSubscriptionException which is caused by Subscription.cancel(). If you want your Subscriber get notified by Subscriber.onError(Throwable) when Subscription.cancel() is called, specify SubscriptionOption.NOTIFY_CANCELLATION when you subscribe.

  • Method Details

    • of

      static <T> StreamMessage<T> of()
      Creates a new StreamMessage that will publish no objects, just a close event.
    • of

      static <T> StreamMessage<T> of(T obj)
      Creates a new StreamMessage that will publish the single obj.
    • of

      static <T> StreamMessage<T> of(T obj1, T obj2)
      Creates a new StreamMessage that will publish the two obj1 and obj2.
    • of

      static <T> StreamMessage<T> of(T obj1, T obj2, T obj3)
      Creates a new StreamMessage that will publish the three obj1, obj2 and obj3.
    • of

      @SafeVarargs static <T> StreamMessage<T> of(T... objs)
      Creates a new StreamMessage that will publish the given objs.
    • of

      static <T> StreamMessage<T> of(org.reactivestreams.Publisher<? extends T> publisher)
      Creates a new StreamMessage from the specified Publisher.
    • of

      static StreamMessage<HttpData> of(File file)
      Creates a new StreamMessage that streams the specified File. The default buffer size(8192) is used to create a buffer used to read data from the File. Therefore, the returned StreamMessage will emit HttpDatas chunked to size less than or equal to 8192.
    • of

      static StreamMessage<HttpData> of(Path path)
      Creates a new StreamMessage that streams the specified Path. The default buffer size(8192) is used to create a buffer used to read data from the Path. Therefore, the returned StreamMessage will emit HttpDatas chunked to size less than or equal to 8192.
    • of

      static StreamMessage<HttpData> of(Path path, int bufferSize)
      Creates a new StreamMessage that streams the specified Path. The specified bufferSize is used to create a buffer used to read data from the Path. Therefore, the returned StreamMessage will emit HttpDatas chunked to size less than or equal to bufferSize.
      Parameters:
      path - the path of the file
      bufferSize - the maximum allowed size of the HttpData buffers
    • of

      static StreamMessage<HttpData> of(Path path, ByteBufAllocator alloc, int bufferSize)
      Creates a new StreamMessage that streams the specified Path. The specified bufferSize is used to create a buffer used to read data from the Path. Therefore, the returned StreamMessage will emit HttpDatas chunked to size less than or equal to bufferSize.
      Parameters:
      path - the path of the file
      alloc - the ByteBufAllocator which will allocate the content buffer
      bufferSize - the maximum allowed size of the HttpData buffers
    • of

      static StreamMessage<HttpData> of(Path path, ExecutorService executor, ByteBufAllocator alloc, int bufferSize)
      Creates a new StreamMessage that streams the specified Path. The specified bufferSize is used to create a buffer used to read data from the Path. Therefore, the returned StreamMessage will emit HttpDatas chunked to size less than or equal to bufferSize.
      Parameters:
      path - the path of the file
      executor - the ExecutorService which performs blocking IO read
      alloc - the ByteBufAllocator which will allocate the content buffer
      bufferSize - the maximum allowed size of the HttpData buffers
    • concat

      @SafeVarargs static <T> StreamMessage<T> concat(org.reactivestreams.Publisher<? extends T>... publishers)
      Returns a concatenated StreamMessage which relays items of the specified array of Publishers in order, non-overlappingly, one after the other finishes.
    • concat

      static <T> StreamMessage<T> concat(Iterable<? extends org.reactivestreams.Publisher<? extends T>> publishers)
      Returns a concatenated StreamMessage which relays items of the specified Publishers in order, non-overlappingly, one after the other finishes.
    • concat

      static <T> StreamMessage<T> concat(org.reactivestreams.Publisher<? extends org.reactivestreams.Publisher<? extends T>> publishers)
      Returns a concatenated StreamMessage which relays items of the specified Publisher of Publishers in order, non-overlappingly, one after the other finishes.
    • aborted

      static <T> StreamMessage<T> aborted(Throwable cause)
      Returns an aborted StreamMessage that terminates with the specified Throwable via Subscriber.onError(Throwable) immediately after being subscribed to.
    • isOpen

      boolean isOpen()
      Returns true if this stream is not closed yet. Note that a stream may not be complete even if it's closed; a stream is complete when it's fully consumed by a Subscriber.
    • isEmpty

      boolean isEmpty()
      Returns true if this stream has been closed and did not publish any elements. Note that this method will not return true when the stream is open even if it has not published anything so far, because it may publish something later.
    • demand

      long demand()
      Returns the current demand of this stream.
    • isComplete

      default boolean isComplete()
      Returns true if this stream is complete, either successfully or exceptionally, including cancellation and abortion.

      A StreamMessage is complete (or 'fully consumed') when:

      • the Subscriber consumes all elements and Subscriber.onComplete() is invoked,
      • an error occurred and Subscriber.onError(Throwable) is invoked,
      • the Subscription has been cancelled or
      • abort() has been requested.
    • whenComplete

      CompletableFuture<Void> whenComplete()
      Returns a CompletableFuture that completes when this stream is complete, either successfully or exceptionally, including cancellation and abortion.

      A StreamMessage is complete (or 'fully consumed') when:

      • the Subscriber consumes all elements and Subscriber.onComplete() is invoked,
      • an error occurred and Subscriber.onError(Throwable) is invoked,
      • the Subscription has been cancelled or
      • abort() has been requested.
    • subscribe

      default void subscribe(org.reactivestreams.Subscriber<? super T> subscriber)
      Requests to start streaming data to the specified Subscriber. If there is a problem subscribing, Subscriber.onError(Throwable) will be invoked with one of the following exceptions:
      Specified by:
      subscribe in interface org.reactivestreams.Publisher<T>
    • subscribe

      default void subscribe(org.reactivestreams.Subscriber<? super T> subscriber, SubscriptionOption... options)
      Requests to start streaming data to the specified Subscriber. If there is a problem subscribing, Subscriber.onError(Throwable) will be invoked with one of the following exceptions:
      Parameters:
      options - SubscriptionOptions to subscribe with
    • subscribe

      default void subscribe(org.reactivestreams.Subscriber<? super T> subscriber, EventExecutor executor)
      Requests to start streaming data to the specified Subscriber. If there is a problem subscribing, Subscriber.onError(Throwable) will be invoked with one of the following exceptions:
      Parameters:
      executor - the executor to subscribe
    • subscribe

      void subscribe(org.reactivestreams.Subscriber<? super T> subscriber, EventExecutor executor, SubscriptionOption... options)
      Requests to start streaming data to the specified Subscriber. If there is a problem subscribing, Subscriber.onError(Throwable) will be invoked with one of the following exceptions:
      Parameters:
      executor - the executor to subscribe
      options - SubscriptionOptions to subscribe with
    • toDuplicator

      default StreamMessageDuplicator<T> toDuplicator()
      Returns a new StreamMessageDuplicator that duplicates this StreamMessage into one or more StreamMessages, which publish the same elements. Note that you cannot subscribe to this StreamMessage anymore after you call this method. To subscribe, call StreamMessageDuplicator.duplicate() from the returned StreamMessageDuplicator.
    • toDuplicator

      default StreamMessageDuplicator<T> toDuplicator(EventExecutor executor)
      Returns a new StreamMessageDuplicator that duplicates this StreamMessage into one or more StreamMessages, which publish the same elements. Note that you cannot subscribe to this StreamMessage anymore after you call this method. To subscribe, call StreamMessageDuplicator.duplicate() from the returned StreamMessageDuplicator.
      Parameters:
      executor - the executor to duplicate
    • defaultSubscriberExecutor

      default EventExecutor defaultSubscriberExecutor()
      Returns the default EventExecutor which will be used when a user subscribes using subscribe(Subscriber), subscribe(Subscriber, SubscriptionOption...).

      Please note that if this method is called multiple times, the returned EventExecutors can be different depending on this StreamMessage implementation.

    • abort

      void abort()
      Closes this stream with AbortedStreamException and prevents further subscription. A Subscriber that attempts to subscribe to an aborted stream will be notified with an AbortedStreamException via Subscriber.onError(Throwable). Calling this method on a closed or aborted stream has no effect.
    • abort

      void abort(Throwable cause)
      Closes this stream with the specified Throwable and prevents further subscription. A Subscriber that attempts to subscribe to an aborted stream will be notified with the specified Throwable via Subscriber.onError(Throwable). Calling this method on a closed or aborted stream has no effect.
    • collect

      default CompletableFuture<List<T>> collect()
      Collects the elements published by this StreamMessage. The returned CompletableFuture will be notified when the elements are fully consumed.

      Note that if this StreamMessage was subscribed by other Subscriber already, the returned CompletableFuture will be completed with an IllegalStateException.

      
       StreamMessage<Integer> stream = StreamMessage.of(1, 2, 3);
       CompletableFuture<List<Integer>> collected = stream.collect();
       assert collected.join().equals(List.of(1, 2, 3));
       
    • collect

      default CompletableFuture<List<T>> collect(SubscriptionOption... options)
      Collects the elements published by this StreamMessage with the specified SubscriptionOptions. The returned CompletableFuture will be notified when the elements are fully consumed.

      Note that if this StreamMessage was subscribed by other Subscriber already, the returned CompletableFuture will be completed with an IllegalStateException.

    • collect

      default CompletableFuture<List<T>> collect(EventExecutor executor, SubscriptionOption... options)
      Collects the elements published by this StreamMessage with the specified EventExecutor and SubscriptionOptions. The returned CompletableFuture will be notified when the elements are fully consumed.

      Note that if this StreamMessage was subscribed by other Subscriber already, the returned CompletableFuture will be completed with an IllegalStateException.

    • filter

      default StreamMessage<T> filter(Predicate<? super T> predicate)
      Filters values emitted by this StreamMessage. If the Predicate test succeeds, the value is emitted. If the Predicate test fails, the value is ignored and a request of 1 is made to upstream.

      For example:

      
       StreamMessage<Integer> source = StreamMessage.of(1, 2, 3, 4, 5);
       StreamMessage<Integer> even = source.filter(x -> x % 2 == 0);
       
    • map

      default <U> StreamMessage<U> map(Function<? super T,​? extends U> function)
      Transforms values emitted by this StreamMessage by applying the specified Function. As per Reactive Streams Specification 2.13, the specified Function should not return a null value.

      For example:

      
       StreamMessage<Integer> source = StreamMessage.of(1, 2, 3, 4, 5);
       StreamMessage<Boolean> isEven = source.map(x -> x % 2 == 0);
       
    • mapError

      default StreamMessage<T> mapError(Function<? super Throwable,​? extends Throwable> function)
      Transforms an error emitted by this StreamMessage by applying the specified Function. As per Reactive Streams Specification 2.13, the specified Function should not return a null value.

      For example:

      
       StreamMessage streamMessage = StreamMessage.aborted(new IllegalStateException("Something went wrong.");
       StreamMessage transformed = streamMessage.mapError(ex -> {
           if (ex instanceof IllegalStateException) {
               return new MyDomainException(ex);
           } else {
               return ex;
           }
       });
       
    • recoverAndResume

      default StreamMessage<T> recoverAndResume(Function<? super Throwable,​? extends StreamMessage<T>> function)
      Recovers a failed StreamMessage and resumes by subscribing to a returned fallback StreamMessage when any error occurs.

      Example:

      
       DefaultStreamMessage<Integer> stream = new DefaultStreamMessage<>();
       stream.write(1);
       stream.write(2);
       stream.close(new IllegalStateException("Oops..."));
       StreamMessage<Integer> resumed = stream.recoverAndResume(cause -> StreamMessage.of(3, 4));
      
       assert resumed.collect().join().equals(List.of(1, 2, 3, 4));