io.datakernel.stream.StreamProducers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of async-streams Show documentation
Show all versions of async-streams Show documentation
Composable asynchronous/reactive streams with powerful data processing capabilities.
The newest version!
/*
* Copyright (C) 2015 SoftIndex LLC.
*
* Licensed 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 io.datakernel.stream;
import io.datakernel.async.*;
import io.datakernel.eventloop.Eventloop;
import java.util.Arrays;
import java.util.Iterator;
import static com.google.common.base.Preconditions.checkNotNull;
import static io.datakernel.async.AsyncIterators.asyncIteratorOfIterator;
public class StreamProducers {
private StreamProducers() {
}
/**
* Returns producer which doing nothing - not sending any data and not closing itself.
*
* @param eventloop event loop in which will run it
*/
public static StreamProducer idle(Eventloop eventloop) {
return new Idle<>(eventloop);
}
/**
* Returns producer which closes itself
*
* @param eventloop event loop in which will run it
* @param type of item for send
*/
public static StreamProducer closing(Eventloop eventloop) {
return new EndOfStream<>(eventloop);
}
public static StreamProducer closingWithError(Eventloop eventloop, Exception e) {
return new ClosingWithError<>(eventloop, e);
}
/**
* Creates producer which sends value and closes itself
*
* @param eventloop event loop in which will run it
* @param value value for sending
* @param type of value
*/
public static StreamProducer ofValue(Eventloop eventloop, final T value) {
return new OfValue<>(eventloop, value);
}
/**
* Creates producer which sends value and closes itself
*
* @param eventloop event loop in which will run it
* @param value value for sending
* @param close if producer is closed
* @param type of value
*/
public static StreamProducer ofValue(Eventloop eventloop, final T value, boolean close) {
return new OfValue<>(eventloop, value, close);
}
/**
* Returns new {@link OfIterator} which sends items from iterator
*
* @param eventloop event loop in which will run it
* @param iterator iterator with items for sending
* @param type of item
*/
public static StreamProducer ofIterator(Eventloop eventloop, Iterator iterator) {
return new OfIterator<>(eventloop, iterator);
}
/**
* Returns new {@link OfIterator} which sends items from {@code iterable}
*
* @param eventloop event loop in which will run it
* @param iterable iterable with items for sending
* @param type of item
*/
public static StreamProducer ofIterable(Eventloop eventloop, Iterable iterable) {
return new OfIterator<>(eventloop, iterable.iterator());
}
/**
* Represents asynchronously resolving producer.
*
* @param eventloop event loop in which will run it
* @param producerGetter getter with producer
* @param type of output data
*/
public static StreamProducer asynchronouslyResolving(final Eventloop eventloop, final AsyncGetter> producerGetter) {
final StreamForwarder forwarder = new StreamForwarder<>(eventloop);
eventloop.post(new Runnable() {
@Override
public void run() {
producerGetter.get(new ResultCallback>() {
@Override
public void onResult(StreamProducer actualProducer) {
actualProducer.streamTo(forwarder);
}
@Override
public void onException(Exception exception) {
new ClosingWithError(eventloop, exception).streamTo(forwarder);
}
});
}
});
return forwarder;
}
/**
* Returns {@link StreamProducerConcat} with producers from asyncIterator which will stream to this
*
* @param eventloop event loop in which will run it
* @param asyncIterator iterator with producers
* @param type of output data
*/
public static StreamProducer concat(Eventloop eventloop, AsyncIterator> asyncIterator) {
return new StreamProducerConcat<>(eventloop, asyncIterator);
}
/**
* Returns {@link StreamProducerConcat} with producers from AsyncIterable which will stream to this
*
* @param eventloop event loop in which will run it
* @param asyncIterator iterable with producers
* @param type of output data
*/
public static StreamProducer concat(Eventloop eventloop, AsyncIterable> asyncIterator) {
return concat(eventloop, asyncIterator.asyncIterator());
}
/**
* Returns {@link StreamProducerConcat} with producers from Iterator which will stream to this
*
* @param eventloop event loop in which will run it
* @param iterator iterator with producers
* @param type of output data
*/
public static StreamProducer concat(Eventloop eventloop, Iterator> iterator) {
return concat(eventloop, asyncIteratorOfIterator(iterator));
}
/**
* Returns {@link StreamProducerConcat} with producers from Iterable which will stream to this
*
* @param eventloop event loop in which will run it
* @param iterable iterator with producers
* @param type of output data
*/
public static StreamProducer concat(Eventloop eventloop, Iterable> iterable) {
return concat(eventloop, iterable.iterator());
}
@SafeVarargs
public static StreamProducer concat(Eventloop eventloop, StreamProducer... producers) {
return concat(eventloop, Arrays.asList(producers));
}
/**
* Represent a {@link AbstractStreamProducer} which once sends to consumer end of stream.
*
* @param
*/
public static class EndOfStream extends AbstractStreamProducer {
public EndOfStream(Eventloop eventloop) {
super(eventloop);
}
@Override
protected void onProducerStarted() {
sendEndOfStream();
}
}
/**
* Represent producer which sends specified exception to consumer.
*
* @param
*/
public static class ClosingWithError extends AbstractStreamProducer {
private final Exception exception;
public ClosingWithError(Eventloop eventloop, Exception exception) {
super(eventloop);
this.exception = exception;
}
@Override
protected void onProducerStarted() {
closeWithError(exception);
}
}
public static class Idle extends AbstractStreamProducer {
public Idle(Eventloop eventloop) {
super(eventloop);
}
}
/**
* Represents a {@link AbstractStreamProducer} which will send all values from iterator.
*
* @param type of output data
*/
public static class OfIterator extends AbstractStreamProducer {
private final Iterator iterator;
private boolean sendEndOfStream = true;
/**
* Creates a new instance of StreamProducerOfIterator
*
* @param eventloop event loop where producer will run
* @param iterator iterator with object which need to send
*/
public OfIterator(Eventloop eventloop, Iterator iterator) {
this(eventloop, iterator, true);
}
public OfIterator(Eventloop eventloop, Iterator iterator, boolean sendEndOfStream) {
super(eventloop);
this.iterator = checkNotNull(iterator);
this.sendEndOfStream = sendEndOfStream;
}
@Override
protected void doProduce() {
for (; ; ) {
if (!iterator.hasNext())
break;
if (status != READY)
return;
T item = iterator.next();
send(item);
}
if (sendEndOfStream)
sendEndOfStream();
}
@Override
protected void onProducerStarted() {
produce();
}
@Override
protected void onResumed() {
resumeProduce();
}
}
/**
* It is {@link AbstractStreamProducer} which sends specified single value to its consumer, followed by end-of-stream
*
* @param type of value for send
*/
public static class OfValue extends AbstractStreamProducer {
private final T value;
private final boolean sendEndOfStream;
/**
* Creates producer which sends value and closes itself
*
* @param eventloop event loop in which this producer will run
* @param value value for sending
*/
public OfValue(Eventloop eventloop, T value) {
this(eventloop, value, true);
}
/**
* Creates producer which sends value and optionally closes itself
*
* @param eventloop event loop in which this producer will run
* @param value value for sending
* @param sendEndOfStream if producer is closed
*/
public OfValue(Eventloop eventloop, T value, boolean sendEndOfStream) {
super(eventloop);
this.value = value;
this.sendEndOfStream = sendEndOfStream;
}
@Override
protected void onProducerStarted() {
send(value);
if (sendEndOfStream)
sendEndOfStream();
}
}
/**
* Represents {@link AbstractStreamTransformer_1_1}, which created with iterator with {@link AbstractStreamProducer}
* which will stream to this
*
* @param type of received data
*/
public static class StreamProducerConcat extends StreamProducerDecorator {
private final AsyncIterator> iterator;
private final StreamProducerSwitcher switcher;
public StreamProducerConcat(Eventloop eventloop, AsyncIterator> iterator) {
super(eventloop);
this.iterator = checkNotNull(iterator);
this.switcher = new StreamProducerSwitcher<>(eventloop);
decorate(switcher);
}
/**
* This method is called if consumer was changed for changing consumer status. It begins streaming
* from producers from iterator
*/
@Override
protected void onProducerStarted() {
doNext();
}
private void doNext() {
eventloop.post(new Runnable() {
@Override
public void run() {
iterator.next(new IteratorCallback>() {
@Override
public void onNext(StreamProducer actualProducer) {
switcher.switchProducerTo(new StreamProducerDecorator(eventloop, actualProducer) {
@Override
public void onEndOfStream() {
doNext();
}
});
}
@Override
public void onEnd() {
switcher.switchProducerTo(new EndOfStream(eventloop));
}
@Override
public void onException(Exception e) {
switcher.switchProducerTo(new ClosingWithError(eventloop, e));
}
});
}
});
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy