public ReactiveSeq<T> changes(){ com.oath.cyclops.async.adapters.Queue<T> queue = QueueFactories.<T>unboundedNonBlockingQueue() .build(); Spliterator<T> copy = copy(); Continuation[] contRef ={null}; Signal<T> signal = new Signal<T>(null, queue); AtomicBoolean wip = new AtomicBoolean(false); Continuation cont = new Continuation(()->{ if(wip.compareAndSet(false,true)) { if(!copy.tryAdvance(signal::set)){ signal.close(); return Continuation.empty(); } wip.set(false); } return contRef[0]; }); contRef[0]= cont; queue.addContinuation(cont); return signal.getDiscrete().stream(); }
@Override public ReactiveSeq<U> stream() { return (ReactiveSeq<U>)adapter.stream(sub); } };
/** * Create a JDK 8 Stream from the supplied Adapter * * <pre> * {@code * Queue<Integer> q = QueueFactories.boundedNonBlockingQueue(1000); * Stream<Integer> stream = StreamSource.stream(q); * stream.forEach(System.out::println); * * //on a separate thread * q.offer(10); * } * </pre> * @param adapter Adapter to create a Steam from * @return Stream that will accept input from supplied adapter */ public static <T> Stream<T> stream(final Adapter<T> adapter) { return adapter.stream(); }
/** * Create a pushable {@link ReactiveSeq} * * <pre> * {@code * Signal<Integer> signal = Signal.queueBackedSignal(); ReactiveSeq<Integer> pushable = StreamSource.reactiveSeq(signal .getDiscrete()); signal.set(100); signal.close(); assertThat(pushable.collect(CyclopsCollectors.toList()), hasItem(100)); * } * </pre> * * @param adapter Adapter to create a Seq from * @return A Seq that will accept input from a supplied adapter */ public static <T> ReactiveSeq<T> reactiveSeq(final Adapter<T> adapter) { return adapter.stream(); }
/** * Subscribe synchronously to a pipe * * @param key for registered simple-react async.Adapter * @param subscriber Reactive Streams reactiveSubscriber for data on this pipe */ public void subscribeTo(final K key, final Subscriber<V> subscriber) { registered.get(key) .stream() .subscribe(subscriber); }
/** * Create a ReactiveSeq from the Adapter identified by the provided Key * * <pre> * {@code * Queue<String> q = new Queue<>(); pipes.register("data-queue", q); pipes.push("data-queue", "world"); //on a separate thread ReactiveSeq<String> stream = pipes.reactiveSeq("data-queue"); stream.forEach(System.out::println); //"world" * * } * </pre> * * * @param key : Adapter identifier * @return {@link ReactiveSeq} from selected Queue */ @SuppressWarnings({ "unchecked", "rawtypes" }) public Option<ReactiveSeq<V>> reactiveSeq(final K key) { return get(key).map(a -> a.stream()); }
/** * Generate a FutureStream from the data flowing into the prodiced Adapter * <pre> * {@code * * Topic<Integer> topic = new Topic<>(); * * new LazyReact(10,10).fromAdapter(topic) * .forEach(this::process); * * //on anther thread * topic.offer(100); * topic.offer(200); * * } * </pre> * * * @param adapter Adapter to construct FutureStream from * @return FutureStream */ public <U> FutureStream<U> fromAdapter(final Adapter<U> adapter) { final Subscription sub = new Subscription(); return new FutureStreamImpl(this,()->adapter.stream(sub)){ @Override public ReactiveSeq<U> stream() { return (ReactiveSeq<U>)adapter.stream(sub); } }; }
public Option<FutureStream<V>> futureStream(final K key, final LazyReact builder) { return get(key).map(a -> builder.fromStream(a.stream()));
/** * Extract one value from the selected pipe, if it exists * * @param key : Adapter identifier * @return Maybe containing next value from the Adapter identified by the provided key */ @SuppressWarnings({ "unchecked", "rawtypes" }) public Option<V> oneValue(final K key) { final ValueSubscriber<V> sub = ValueSubscriber.subscriber(); return get(key).peek(a -> a.stream() .subscribe(sub)) .flatMap(a -> sub.toMaybe()); }
/** * Extact one value from the selected pipe or an zero Maybe if it doesn't exist. Currently only Adapter's and not Publishers * are managed by Pipes so Publisher errors are not propagated (@see {@link Pipes#oneValue(Object)} or @see {@link Pipes#oneOrError(Object)} is better at the moment. * * <pre> * {@code * Queue<String> q = new Queue<>(); pipes.register("hello", q); pipes.push("hello", "world"); pipes.push("hello", "world2"); pipes.oneValueOrError("hello").getValue(); //Try["world"] * } * </pre> * * @param key : Adapter identifier * @return */ @Deprecated //errors aren't propagated across Adapters (at least without continuations) public Option<Try<V, Throwable>> oneValueOrError(final K key) { final ValueSubscriber<V> sub = ValueSubscriber.subscriber(); return get(key).peek(a -> a.stream() .subscribe(sub)) .map(a -> sub.toTry(Throwable.class)); }
public ReactiveSeq<T> changes(){ com.oath.cyclops.async.adapters.Queue<T> queue = QueueFactories.<T>unboundedNonBlockingQueue() .build(); Spliterator<T> copy = copy(); Continuation[] contRef ={null}; Signal<T> signal = new Signal<T>(null, queue); AtomicBoolean wip = new AtomicBoolean(false); Continuation cont = new Continuation(()->{ if(wip.compareAndSet(false,true)) { if(!copy.tryAdvance(signal::set)){ signal.close(); return Continuation.empty(); } wip.set(false); } return contRef[0]; }); contRef[0]= cont; queue.addContinuation(cont); return signal.getDiscrete().stream(); }
/** * Extact one value from the selected pipe or an zero Maybe if it doesn't exist. Currently only Adapter's and not Publishers * are managed by Pipes so Publisher errors are not propagated (@see {@link Pipes#oneValue(Object)} or @see {@link Pipes#oneOrError(Object)} is better at the moment. * * <pre> * {@code * Queue<String> q = new Queue<>(); pipes.register("hello", q); pipes.push("hello", "world"); pipes.push("hello", "world2"); pipes.oneValueOrError("hello",Throwable.class).getValue(); //Try["world"] * } * </pre> * * @param key * @param classes * @return */ @Deprecated //errors aren't propagated across Adapters (at least without continuations) public <X extends Throwable> Option<Try<V, X>> oneValueOrError(final K key, final Class<X>... classes) { final ValueSubscriber<V> sub = ValueSubscriber.subscriber(); return get(key).peek(a -> a.stream() .subscribe(sub)) .map(a -> sub.toTry(classes)); }
/** * Extact one value from the selected pipe or an error if it doesn't exist (NoSuchElementException). * * <pre> * {@code * * Queue<String> q = new Queue<>(); pipes.register("hello", q); pipes.push("hello", "world"); pipes.push("hello", "world2"); pipes.oneOrError("hello") .getValue() //"world" * } * </pre> * @param key : Adapter identifier * @return Xor containing lazy a NoSuchElementException an Adapter with the specified key does not exist, * or the next value from that Adapter */ public Either<Throwable, V> oneOrError(final K key) { final ValueSubscriber<V> sub = ValueSubscriber.subscriber(); return get(key).peek(a -> a.stream() .subscribe(sub)) .map(a -> sub.toEither()) .orElse(Either.left(new NoSuchElementException( "no adapter for key " + key))); }
return get(key).map(a -> a.stream() .limit(x) .to(ReactiveConvertableSequence::converter).listX())
get(key).peek(a -> a.stream() .subscribe(sub)) .map(a -> sub.toMaybe().fold(s -> {
final ValueSubscriber<V> sub = ValueSubscriber.subscriber(); final LazyImmutable<Boolean> requested = LazyImmutable.def(); final Option<Eval<Maybe<V>>> nested = get(key).peek(a -> a.stream() .subscribe(sub)) .map(a -> Eval.always(() -> {
final ValueSubscriber<V> sub = ValueSubscriber.subscriber(); final LazyImmutable<Boolean> requested = LazyImmutable.def(); return get(key).peek(a -> a.stream() .subscribe(sub)) .map(a -> Eval.always(() -> {