com.softwaremill.jox.CloseableChannel Maven / Gradle / Ivy
package com.softwaremill.jox;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* A channel which can be closed.
*
* A channel can be closed in two ways:
*
* - using {@link #done()} or {@link #doneOrClosed()}, indicating that no more elements will be sent
* - using {@link #error(Throwable)} or {@link #errorOrClosed(Throwable)}, indicating an error
*
*
* A channel can be closed only once. Subsequent calls to {@link #done()} or {@link #error(Throwable)} will throw
* {@link ChannelClosedException}, or return the original closing reason (when using {@link #doneOrClosed()} or {@link #errorOrClosed(Throwable)}).
*
* Closing the channel is thread-safe.
*/
public interface CloseableChannel {
/**
* Close the channel, indicating that no more elements will be sent.
*
* Any elements that are already buffered will be delivered. Any send operations that are in progress will complete
* normally, when a receiver arrives. Any pending receive operations will complete with a channel closed result.
*
* Subsequent {@link Sink#send(Object)} operations will throw {@link ChannelClosedException}.
*
* @throws ChannelClosedException When the channel is already closed.
*/
void done();
/**
* Close the channel, indicating that no more elements will be sent. Doesn't throw exceptions when the channel is
* closed, but returns a value.
*
* Any elements that are already buffered will be delivered. Any send operations that are in progress will complete
* normally, when a receiver arrives. Any pending receive operations will complete with a channel closed result.
*
* Subsequent {@link Sink#send(Object)} operations will throw {@link ChannelClosedException}.
*
* @return Either {@code null}, or {@link ChannelClosed}, when the channel is already closed.
*/
Object doneOrClosed();
//
/**
* Close the channel, indicating an error.
*
* Any elements that are already buffered won't be delivered. Any send or receive operations that are in progress
* will complete with a channel closed result.
*
* Subsequent {@link Sink#send(Object)} and {@link Source#receive()} operations will throw {@link ChannelClosedException}.
*
* @param reason The reason of the error. Not {@code null}.
* @throws ChannelClosedException When the channel is already closed.
*/
void error(Throwable reason);
/**
* Close the channel, indicating an error. Doesn't throw exceptions when the channel is closed, but returns a value.
*
* Any elements that are already buffered won't be delivered. Any send or receive operations that are in progress
* will complete with a channel closed result.
*
* Subsequent {@link Sink#send(Object)} and {@link Source#receive()} operations will throw {@link ChannelClosedException}.
*
* @return Either {@code null}, or {@link ChannelClosed}, when the channel is already closed.
*/
Object errorOrClosed(Throwable reason);
//
/**
* @return {@code true} if no more values can be sent to this channel; {@link Sink#send(Object)} will throw
* {@link ChannelClosedException} or return {@link ChannelClosed} (in the or-closed variant).
*
* When closed for send, receiving using {@link Source#receive()} might still be possible, if the channel is done,
* and not in an error. This can be verified using {@link #isClosedForReceive()}.
*/
default boolean isClosedForSend() {
return closedForSend() != null;
}
/**
* @return {@code true} if no more values can be received from this channel; {@link Source#receive()} will throw
* {@link ChannelClosedException} or return {@link ChannelClosed} (in the or-closed variant).
*
* When closed for receive, sending values is also not possible, {@link #isClosedForSend()} will return {@code true}.
*
* When {@code false}, values might be received from the channel, when calling
* {@link Source#receive()}, but it's not guaranteed that some values will be available. They might be received
* concurrently, or filtered out if the channel is created using {@link Source#collectAsView(Function)} or
* {@link Source#filterAsView(Predicate)}.
*/
default boolean isClosedForReceive() {
return closedForReceive() != null;
}
/**
* @return Non-{@code null} if no more values can be sent to this channel; {@link Sink#send(Object)} will throw
* {@link ChannelClosedException} or return {@link ChannelClosed} (in the or-closed variant).
*
* {@code null} if the channel is not closed, and values can be sent.
*
* When closed for send, receiving using {@link Source#receive()} might still be possible, if the channel is done,
* and not in an error. This can be verified using {@link #isClosedForReceive()}.
*/
ChannelClosed closedForSend();
/**
* @return Non-{@code null} if no more values can be received from this channel; {@link Source#receive()} will throw
* {@link ChannelClosedException} or return {@link ChannelClosed} (in the or-closed variant).
*
* {@code null} if the channel is not closed, and values can be received.
*
* When closed for receive, sending values is also not possible, {@link #isClosedForSend()} will return {@code true}.
*/
ChannelClosed closedForReceive();
}