
io.baratine.stream.ResultStream Maven / Gradle / Ivy
Show all versions of api Show documentation
/*
* Copyright (c) 1998-2015 Caucho Technology -- all rights reserved
*
* This file is part of Baratine(TM)(TM)
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Baratine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Baratine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Baratine; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package io.baratine.stream;
import java.io.Serializable;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Level;
import io.baratine.service.Cancel;
import io.baratine.service.Result;
import io.baratine.stream.ResultStreamImpl.ResultAsync;
/**
* Interface {@code ResultStream} is used as a sink for returning an unbounded
* sequence of values from a service method.
*
* The interface is used as a parameter in implementation of a method
* corresponding to a service interface method returning
* {@code ResultStreamBuilder}.
*
* e.g.
*
*
* public interface MyService {
* ResultStreamBuilder<String> results();
* }
*
* @io.baratine.core.Service("public://pod/service")
* public class MyServiceImpl implements MyService {
* public void results(ResultStream<String> stream) {
* stream.accept("Hello");
* stream.accept("World");
*
* stream.complete();
* }
*
* @Override
* public void ResultStreamBuilder<String> results() {
* throw new UnsupportedOperationException();
* }
* }
*
*
*
*
* Sending a new value can be accomplished with passing it to method {@code accept}.
*
* After the last value is submitted the service needs to call method {@code complete}
* to signal the {@code ResultStream} that last value has been submitted}
*
* The client obtaining the results from the corresponding {@code ResultStreamBuilder}
* may choose to cancel further results. When {@code ResultStream} is cancelled
* its cancelled state is set to true and method {@code onCancell(CancelHandle)}
* is called. Method {@code isCancelled()} can be used to test if the stream
* was cancelled to avoid sending values to a cancelled stream.
*
*
*
* @see io.baratine.stream.ResultStreamBuilder
*/
@FunctionalInterface
public interface ResultStream extends Consumer, Serializable
{
public static final int CREDIT_MAX = 1 << 24;
/**
* Method {@code start()} performs initial operations on preparing
* an instance of {@code ResultStream} to accepting values. This method is
* called internally by Baratine.
*/
default void start() {}
/**
* Supplies next value into the client's {@code ResultStreamBuilder}
* @param value
*/
@Override
default void accept(T value)
{
handle(value, null, false);
}
/**
* Completes sending the values to the client and signals to the client
* that no more values is expected.
*/
default void ok()
{
handle(null, null, true);
}
/**
* Signals a failure to the client passing exception.
* @param exn
*/
default void fail(Throwable exn)
{
handle(null, exn, false);
}
void handle(T value, Throwable exn, boolean isEnd);
/**
* Uses a {@code Supplier} to generate set of values and calls
* method {@code complete()} on itself.
*
* A first null value returned by the {@code get()} method of the {@code Supplier}
* completes accept() loop and calls complete() on the instance of {@code ResultStream}.
*
* @param supplier supplies value to be accepted by the instance of {@code ResultStream}
*/
default void generate(Supplier supplier)
{
T value;
while (! isCancelled() && (value = supplier.get()) != null) {
accept(value);
}
ok();
}
//
// cancel methods
//
/**
* Tests if the instance of {@code ResultStream} was cancelled.
*
* @return true if cancelled, false otherwise.
*/
default boolean isCancelled()
{
return false;
}
/**
* A callback method that is called when the {@code ResultStream} is cancelled.
*
* @param cancel
*/
default void onCancel(Cancel cancel)
{
throw new UnsupportedOperationException(getClass().getName());
}
//
// flow methods
//
/*
default int getCredit()
{
return CREDIT_MAX;
}
default void onCreditAvailable(Runnable task)
{
task.run();
}
*/
default Result of(BiConsumer> consumer)
{
return Result.of(x->consumer.accept(x,this), exn->fail(exn));
}
/**
* @return
*/
default boolean isFuture()
{
return false;
}
default void acceptFuture(ResultStream result,
Iterable values,
boolean isComplete)
{
for (U value : values) {
result.accept(value);
}
if (isComplete) {
result.ok();
}
}
default ResultStream flush()
{
return this;
}
default ResultStream> createJoin()
{
return this;
}
default ResultStream createFork(ResultStream