io.vertx.core.streams.ReadStream Maven / Gradle / Ivy
/*
* Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*/
package io.vertx.core.streams;
import io.vertx.codegen.annotations.Fluent;
import io.vertx.codegen.annotations.GenIgnore;
import io.vertx.codegen.annotations.Nullable;
import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.impl.future.PromiseInternal;
import io.vertx.core.streams.impl.PipeImpl;
import java.util.function.BiConsumer;
/**
* Represents a stream of items that can be read from.
*
* Any class that implements this interface can be used by a {@link Pipe} to pipe data from it
* to a {@link WriteStream}.
*
*
Streaming mode
* The stream is either in flowing or fetch mode.
*
* Initially the stream is in flowing mode.
* - When the stream is in flowing mode, elements are delivered to the {@code handler}.
* - When the stream is in fetch mode, only the number of requested elements will be delivered to the {@code handler}.
*
* The mode can be changed with the {@link #pause()}, {@link #resume()} and {@link #fetch} methods:
*
* - Calling {@link #resume()} sets the flowing mode
* - Calling {@link #pause()} sets the fetch mode and resets the demand to {@code 0}
* - Calling {@link #fetch(long)} requests a specific amount of elements and adds it to the actual demand
*
*
* @author Tim Fox
*/
@VertxGen(concrete = false)
public interface ReadStream extends StreamBase {
/**
* Set an exception handler on the read stream.
*
* @param handler the exception handler
* @return a reference to this, so the API can be used fluently
*/
ReadStream exceptionHandler(@Nullable Handler handler);
/**
* Set a data handler. As data is read, the handler will be called with the data.
*
* @return a reference to this, so the API can be used fluently
*/
@Fluent
ReadStream handler(@Nullable Handler handler);
/**
* Pause the {@code ReadStream}, it sets the buffer in {@code fetch} mode and clears the actual demand.
*
* While it's paused, no data will be sent to the data {@code handler}.
*
* @return a reference to this, so the API can be used fluently
*/
@Fluent
ReadStream pause();
/**
* Resume reading, and sets the buffer in {@code flowing} mode.
*
* If the {@code ReadStream} has been paused, reading will recommence on it.
*
* @return a reference to this, so the API can be used fluently
*/
@Fluent
ReadStream resume();
/**
* Fetch the specified {@code amount} of elements. If the {@code ReadStream} has been paused, reading will
* recommence with the specified {@code amount} of items, otherwise the specified {@code amount} will
* be added to the current stream demand.
*
* @return a reference to this, so the API can be used fluently
*/
@Fluent
ReadStream fetch(long amount);
/**
* Set an end handler. Once the stream has ended, and there is no more data to be read, this handler will be called.
*
* @return a reference to this, so the API can be used fluently
*/
@Fluent
ReadStream endHandler(@Nullable Handler endHandler);
/**
* Pause this stream and return a {@link Pipe} to transfer the elements of this stream to a destination {@link WriteStream}.
*
* The stream will be resumed when the pipe will be wired to a {@code WriteStream}.
*
* @return a pipe
*/
default Pipe pipe() {
pause();
return new PipeImpl<>(this);
}
/**
* Same as {@link #pipeTo(WriteStream, Handler)} but returns a {@code Future} of the asynchronous result
*/
default Future pipeTo(WriteStream dst) {
Promise promise = Promise.promise();
new PipeImpl<>(this).to(dst, promise);
return promise.future();
}
/**
* Pipe this {@code ReadStream} to the {@code WriteStream}.
*
* Elements emitted by this stream will be written to the write stream until this stream ends or fails.
*
* Once this stream has ended or failed, the write stream will be ended and the {@code handler} will be
* called with the result.
*
* @param dst the destination write stream
*/
default void pipeTo(WriteStream dst, Handler> handler) {
new PipeImpl<>(this).to(dst, handler);
}
/**
* Apply a {@code collector} to this stream, the obtained result is returned as a future.
*
* Handlers of this stream are affected by this operation.
*
* @return a future notified with result produced by the {@code collector} applied to this stream
*/
@GenIgnore
default Future collect(java.util.stream.Collector collector) {
PromiseInternal promise = (PromiseInternal) Promise.promise();
A cumulation = collector.supplier().get();
BiConsumer accumulator = collector.accumulator();
handler(elt -> accumulator.accept(cumulation, elt));
endHandler(v -> {
R result = collector.finisher().apply(cumulation);
promise.tryComplete(result);
});
exceptionHandler(promise::tryFail);
return promise.future();
}
}