private void setDiscreteIfDiff(final T newValue) { T oldVal = discreteState.get(); while (!discreteState.compareAndSet(oldVal, newValue)) { oldVal = discreteState.get(); } if (!Objects.equals(oldVal, newValue)) discrete.offer(newValue); }
/** * @return A structural Pattern Matcher for this Adapter that allows matching on Queue / Topic types */ default Either<Queue<T>, Topic<T>> matches() { return fold(q -> Either.left(q), topic -> Either.right(topic)); }
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(); }
/** * Create a Pattern Matcher on cyclops2-react adapter type (note this will only fold * on known types within the cyclops2-react library) * * <pre> * {@code * Adapter<Integer> adapter = QueueFactories.<Integer>unboundedQueue() * .build(); * * String result = Xors.adapter(adapter) .visit(queue->"we have a queue",topic->"we have a topic"); * * //"we have a queue" * } * </pre> * * @param adapter Adapter to fold on * @return Structural pattern matcher for Adapter types. */ public static <T> Either<Queue<T>, Topic<T>> adapter(final Adapter<T> adapter) { return adapter.matches(); }
/** * Synchronously publish data to the Adapter specified by the provided Key, blocking the current thread * * @param key for registered cylops-react async.Adapter * @param publisher Reactive Streams publisher to push data onto this pipe */ public void publishTo(final K key, final Publisher<V> publisher) { registered.get(key).fromStream(Spouts.from(publisher)); }
/** * Create a Pattern Matcher on cyclops2-react adapter type (note this will only fold * on known types within the cyclops2-react library) * * <pre> * {@code * Adapter<Integer> adapter = QueueFactories.<Integer>unboundedQueue() * .build(); * * String result = Xors.adapter(adapter) .visit(queue->"we have a queue",topic->"we have a topic"); * * //"we have a queue" * } * </pre> * * @param adapter Adapter to fold on * @return Structural pattern matcher for Adapter types. */ public static <T> Either<Queue<T>, Topic<T>> adapter(final Adapter<T> adapter) { return adapter.matches(); }
@Override public ReactiveSeq<U> stream() { return (ReactiveSeq<U>)adapter.stream(sub); } };
default ReactiveSeq<T> publishTo(Adapter<T>... adapters){ return peek(e->{ for(Adapter<T> next: adapters){ next.offer(e); } }); } default ReactiveSeq<T> publishTo(Signal<T>... signals){
/** * @return A structural Pattern Matcher for this Adapter that allows matching on Queue / Topic types */ default Either<Queue<T>, Topic<T>> matches() { return fold(q -> Either.left(q), topic -> Either.right(topic)); }
/** * 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(); }
/** * Set the current value of this signal * * @param newValue Replacement value * @return newValue */ public T set(final T newValue) { if(continuous!=null) continuous.offer(newValue); setDiscreteIfDiff(newValue); return newValue; }
/** * Close the Adapter identified by the provided Key if it exists * * @param key : Adapter identifier */ public void close(final String key) { Optional.ofNullable(registered.get(key)) .ifPresent(a -> a.close()); }
/** * 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(); }
private void setDiscreteIfDiff(final T newValue) { T oldVal = discreteState.get(); while (!discreteState.compareAndSet(oldVal, newValue)) { oldVal = discreteState.get(); } if (!Objects.equals(oldVal, newValue)) discrete.offer(newValue); }
/** * 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); }
default ReactiveSeq<T> publishTo(Adapter<T>... adapters){ return peek(e->{ for(Adapter<T> next: adapters){ next.offer(e); } }); } default ReactiveSeq<T> publishTo(Signal<T>... signals){
/** * 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()); }