/* * Copyright 2016 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.linecorp.armeria.common.stream; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import org.reactivestreams.Publisher; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; /** * A variant of <a href="http://www.reactive-streams.org/">Reactive Streams</a> {@link Publisher}, which allows * only one {@link Subscriber}. Unlike a usual {@link Publisher}, a {@link StreamMessage} can stream itself * only once. It has the following additional operations on top of what the Reactive Streams API provides: * <ul> * <li>{@link #isOpen()}</li> * <li>{@link #isEmpty()}</li> * <li>{@link #closeFuture()}</li> * <li>{@link #abort()}</li> * </ul> * * <h3>When is a {@link StreamMessage} open?</h3> * * <p>A {@link StreamMessage} is open since its instantiation until: * <ul> * <li>the {@link Subscriber} consumes all elements and {@link Subscriber#onComplete()} is invoked,</li> * <li>an error occurred and {@link Subscriber#onError(Throwable)} is invoked,</li> * <li>the {@link Subscription} has been cancelled or</li> * <li>{@link #abort()} has been requested.</li> * </ul> * * <h3>Getting notified when a {@link StreamMessage} is closed</h3> * * <p>Use {@link #closeFuture()} * * @param <T> the type of element signaled */ public interface StreamMessage<T> extends Publisher<T> { /** * Returns {@code true} if this publisher is not closed yet. */ boolean isOpen(); /** * Returns {@code true} if this stream has been closed and did not publish any elements. * Note that this method will not return {@code true} when the stream is open even if it has not * published anything so far, because it may publish something later. */ boolean isEmpty(); /** * Returns a {@link CompletableFuture} that completes when this publisher is complete, * either successfully or exceptionally. */ CompletableFuture<Void> closeFuture(); /** * Requests to start streaming data to the specified {@link Subscriber}. * * @throws IllegalStateException if there is a {@link Subscriber} who subscribed to this stream already */ @Override void subscribe(Subscriber<? super T> s); /** * Requests to start streaming data to the specified {@link Subscriber}, receiving pooled objects as is. * Ownership of all pooled objects is transferred to the {@link Subscriber}, which must release them when * finished. If you don't know what this means, use {@link StreamMessage#subscribe(Subscriber)}. * * @throws IllegalStateException if there is a {@link Subscriber} who subscribed to this stream already */ void subscribe(Subscriber<? super T> s, boolean withPooledObjects); /** * Requests to start streaming data, invoking the specified {@link Subscriber} from the specified * {@link Executor}. * * @throws IllegalStateException if there is a {@link Subscriber} who subscribed to this stream already */ void subscribe(Subscriber<? super T> s, Executor executor); /** * Requests to start streaming data, invoking the specified {@link Subscriber} from the specified * {@link Executor}, receiving pooled objects as is. Ownership of all pooled objects is transferred to the * {@link Subscriber}, which must release them when finished. If you don't know what this means, use * {@link StreamMessage#subscribe(Subscriber, Executor)}. * * @throws IllegalStateException if there is a {@link Subscriber} who subscribed to this stream already */ void subscribe(Subscriber<? super T> s, Executor executor, boolean withPooledObjects); /** * Cancels the {@link Subscription} if any and closes this publisher. */ void abort(); }