use of com.oath.cyclops.async.adapters.Queue in project cyclops by aol.
the class EagerFutureStreamFunctions method combineLatest.
/**
* Zip two streams into one using a {@link BiFunction} to produce resulting.
* values. Uses the latest values from each rather than waiting for both.
*/
static <T1, T2, R> ReactiveSeq<R> combineLatest(final SimpleReactStream<T1> left, final SimpleReactStream<T2> right, final BiFunction<T1, T2, R> zipper) {
final Queue q = left.then(it -> new Val(Val.Pos.left, it)).merge(right.then(it -> new Val(Val.Pos.right, it))).toQueue();
final Iterator<Val> it = q.stream(left.getSubscription()).iterator();
class Zip implements Iterator<R> {
T1 lastLeft = null;
T2 lastRight = null;
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public R next() {
final Val v = it.next();
if (v.pos == Val.Pos.left)
lastLeft = (T1) v.val;
else
lastRight = (T2) v.val;
return zipper.apply(lastLeft, lastRight);
}
}
return ReactiveSeq.fromIterator(new Zip());
}
use of com.oath.cyclops.async.adapters.Queue in project cyclops by aol.
the class EagerFutureStreamFunctions method takeUntil.
static <T1, T2> ReactiveSeq<T1> takeUntil(final SimpleReactStream<T1> left, final SimpleReactStream<T2> right) {
final Queue q = left.then(it -> new Val(Val.Pos.left, it)).merge(right.then(it -> new Val(Val.Pos.right, it))).toQueue();
final Iterator<Val> it = q.stream(left.getSubscription()).iterator();
new Object();
class Zip implements Iterator<T1> {
Optional<T1> lastLeft = Optional.empty();
Optional<T2> lastRight = Optional.empty();
boolean closed = false;
@Override
public boolean hasNext() {
return !closed && it.hasNext();
}
@Override
public T1 next() {
final Val v = it.next();
if (v.pos == Val.Pos.left)
lastLeft = Optional.of((T1) v.val);
else
lastRight = Optional.of((T2) v.val);
if (!lastRight.isPresent() && lastLeft.isPresent())
return lastLeft.get();
else {
closed = true;
return (T1) Optional.empty();
}
}
}
return ReactiveSeq.fromIterable(() -> new Zip()).filter(next -> !(next instanceof Optional));
}
use of com.oath.cyclops.async.adapters.Queue in project cyclops by aol.
the class FutureStreamSynchronousPublisher method subscribe.
/* (non-Javadoc)
* @see org.reactivestreams.Publisher#forEachAsync(org.reactivestreams.Subscriber)
*/
@Override
default void subscribe(final Subscriber<? super T> s) {
try {
forwardErrors(t -> s.onError(t));
final Queue<T> queue = toQueue();
final Iterator<CompletableFuture<T>> it = queue.streamCompletableFutures().iterator();
final Subscription sub = new Subscription() {
volatile boolean complete = false;
volatile boolean cancelled = false;
final LinkedList<Long> requests = new LinkedList<Long>();
boolean active = false;
private void handleNext(final T data) {
if (!cancelled) {
s.onNext(data);
}
}
@Override
public void request(final long n) {
if (n < 1) {
s.onError(new IllegalArgumentException("3.9 While the Subscription is not cancelled, Subscription.request(long n) MUST throw a java.lang.IllegalArgumentException if the argument is <= 0."));
}
requests.add(n);
final List<CompletableFuture> results = new ArrayList<>();
if (active) {
return;
}
active = true;
try {
while (!cancelled && requests.size() > 0) {
final long n2 = requests.peek();
for (int i = 0; i < n2; i++) {
try {
if (it.hasNext()) {
handleNext(s, it, results);
} else {
handleComplete(results, s);
break;
}
} catch (final Throwable t) {
s.onError(t);
}
}
requests.pop();
}
} finally {
active = false;
}
}
private void handleComplete(final List<CompletableFuture> results, final Subscriber<? super T> s) {
if (!complete && !cancelled) {
complete = true;
if (results.size() > 0) {
CompletableFuture.allOf(results.stream().map(cf -> cf.exceptionally(e -> null)).collect(Collectors.toList()).toArray(new CompletableFuture[results.size()])).thenAccept(a -> callOnComplete(s)).exceptionally(e -> {
callOnComplete(s);
return null;
});
} else {
callOnComplete(s);
}
}
}
private void callOnComplete(final Subscriber<? super T> s) {
s.onComplete();
}
private void handleNext(final Subscriber<? super T> s, final Iterator<CompletableFuture<T>> it, final List<CompletableFuture> results) {
results.add(it.next().thenAccept(r -> {
s.onNext(r);
}).exceptionally(t -> {
s.onError(t);
return null;
}));
final List<CompletableFuture> newResults = results.stream().filter(cf -> cf.isDone()).collect(Collectors.toList());
results.removeAll(newResults);
}
@Override
public void cancel() {
cancelled = true;
forwardErrors(t -> {
});
queue.closeAndClear();
}
};
s.onSubscribe(sub);
} catch (final SimpleReactProcessingException e) {
}
}
use of com.oath.cyclops.async.adapters.Queue in project cyclops by aol.
the class LazySeqTest method shouldZipFiniteWithInfiniteSeq.
@Test
public void shouldZipFiniteWithInfiniteSeq() throws Exception {
ThreadPools.setUseCommon(false);
final ReactiveSeq<Integer> units = new LazyReact(ThreadPools.getCommonFreeThread()).iterate(1, n -> n + 1).limit(5);
// <-- MEMORY LEAK! - no auto-closing yet, so writes infinetely to it's async queue
final FutureStream<Integer> hundreds = new LazyReact(ThreadPools.getCommonFreeThread()).iterate(100, n -> n + 100);
final ReactiveSeq<String> zipped = units.zip(hundreds, (n, p) -> n + ": " + p);
assertThat(zipped.limit(5).join(), equalTo(of("1: 100", "2: 200", "3: 300", "4: 400", "5: 500").join()));
ThreadPools.setUseCommon(true);
}
use of com.oath.cyclops.async.adapters.Queue in project cyclops by aol.
the class LazySeqTest method shouldZipInfiniteWithFiniteSeq.
@Test
public void shouldZipInfiniteWithFiniteSeq() throws Exception {
ThreadPools.setUseCommon(false);
// <-- MEMORY LEAK!- no auto-closing yet, so writes infinetely to it's async queue
final FutureStream<Integer> units = new LazyReact(ThreadPools.getCommonFreeThread()).iterate(1, n -> n + 1);
final ReactiveSeq<Integer> hundreds = new LazyReact(ThreadPools.getCommonFreeThread()).iterate(100, n -> n + 100).limit(5);
final ReactiveSeq<String> zipped = units.zip(hundreds, (n, p) -> n + ": " + p);
assertThat(zipped.limit(5).join(), equalTo(of("1: 100", "2: 200", "3: 300", "4: 400", "5: 500").join()));
ThreadPools.setUseCommon(true);
}
Aggregations