/** * Generating a stream will register the Stream as a reactiveSubscriber to this topic. * It will be provided with an internal Queue as a mailbox. @see Topic.disconnect to disconnect from the topic * @return Stream of data */ @Override public ReactiveSeq<T> stream() { return connect(q -> q.stream()); }
/** * Add a single datapoint to this Queue * * @param data data to add * @return self */ @Override public boolean offer(final T data) { fromStream(Stream.of(data)); return true; }
.withTimeout(1); Topic<T> topic = new Topic<>(queue, QueueFactories.<T>boundedNonBlockingQueue(1000)); AtomicBoolean wip = new AtomicBoolean(false); source.subscribeAll(topic::offer, e -> topic.close(), () -> topic.close()); } finally { wip.set(false); .withTimeout(1); Topic<T> topic = new Topic<>(queue, QueueFactories.<T>boundedNonBlockingQueue(1000)); AtomicBoolean wip = new AtomicBoolean(false); Subscription s = source.subscribe(topic::offer, e -> topic.close(), () -> topic.close()); Continuation contRef[] = {null}; Continuation cont =
@Test public void broadcastThreads() throws InterruptedException { Topic<Integer> topic = ReactiveSeq.range(0,100_000) .broadcast(); Thread t= new Thread( ()-> { ReactiveSeq<Integer> stream2 = topic.stream(); assertThat(stream2.takeRight(1).singleOrElse(-1), equalTo(99_999)); }); t.start(); ReactiveSeq<Integer> stream1 = topic.stream(); assertThat(stream1.takeRight(1).singleOrElse(-1),equalTo(99_999)); t.join(); }
@Synchronized("lock") private <R> ReactiveSeq<R> connect(final Function<Queue<T>, ReactiveSeq<R>> streamCreator) { final Queue<T> queue = this.getNextQueue(); final ReactiveSeq<R> stream = streamCreator.apply(queue); this.streamToQueue = streamToQueue.put(stream, queue); return stream; }
default Topic<T> broadcast(){ Queue<T> queue = QueueFactories.<T>unboundedNonBlockingQueue() .build() .withTimeout(1); Topic<T> topic = new Topic<T>(queue,QueueFactories.<T>unboundedNonBlockingQueue()); AtomicBoolean wip = new AtomicBoolean(false); Spliterator<T> split = this.spliterator(); Continuation ref[] = {null}; Continuation cont = new Continuation(()->{ if(wip.compareAndSet(false,true)){ try { //use the first consuming thread to tell this Stream onto the Queue if(!split.tryAdvance(topic::offer)){ topic.close(); return Continuation.empty(); } }finally { wip.set(false); } } return ref[0]; }); ref[0]=cont; queue.addContinuation(cont); return topic; }
@Test public void broadcastThreads() throws InterruptedException { Topic<Integer> topic = Spouts.range(0,100_000) .broadcast(); Thread t= new Thread( ()-> { ReactiveSeq<Integer> stream2 = topic.stream(); assertThat(stream2.takeRight(1).singleOrElse(null), Matchers.equalTo(99_999)); }); Thread t2 = new Thread( ()->{ ReactiveSeq<Integer> stream1 = topic.stream(); assertThat(stream1.takeRight(1).singleOrElse(null), Matchers.equalTo(99_999)); }); t.start(); t2.start(); t.join(); t2.join(); }
@Synchronized("lock") private <R> ReactiveSeq<R> connect(final Function<Queue<T>, ReactiveSeq<R>> streamCreator) { final Queue<T> queue = this.getNextQueue(); final ReactiveSeq<R> stream = streamCreator.apply(queue); this.streamToQueue = streamToQueue.put(stream, queue); return stream; }
.withTimeout(1); Topic<T> topic = new Topic<>(queue, QueueFactories.<T>boundedNonBlockingQueue(1000)); AtomicBoolean wip = new AtomicBoolean(false); source.subscribeAll(topic::offer, e -> topic.close(), () -> topic.close()); } finally { wip.set(false); .withTimeout(1); Topic<T> topic = new Topic<>(queue, QueueFactories.<T>boundedNonBlockingQueue(1000)); AtomicBoolean wip = new AtomicBoolean(false); Subscription s = source.subscribe(topic::offer, e -> topic.close(), () -> topic.close()); Continuation contRef[] = {null}; Continuation cont =
@Test public void broadcastTest(){ Topic<Integer> topic = Spouts.of(1,2,3) .broadcast(); ReactiveSeq<Integer> stream1 = topic.stream(); ReactiveSeq<Integer> stream2 = topic.stream(); assertThat(stream1.toList(), Matchers.equalTo(Arrays.asList(1,2,3))); assertThat(stream2.toList(), Matchers.equalTo(Arrays.asList(1,2,3))); } @Test
public MultipleStreamSource(final Queue<T> q) { topic = new Topic( q); }
/** * Generating a streamCompletableFutures will register the Stream as a reactiveSubscriber to this topic. * It will be provided with an internal Queue as a mailbox. @see Topic.disconnect to disconnect from the topic * * @return Stream of CompletableFutures that can be used as input into a SimpleReact concurrent dataflow */ @Override public ReactiveSeq<CompletableFuture<T>> streamCompletableFutures() { return connect(q -> q.streamCompletableFutures()); }
/** * Add a single datapoint to this Queue * * @param data data to add * @return self */ @Override public boolean offer(final T data) { fromStream(Stream.of(data)); return true; }
default Topic<T> broadcast(){ Queue<T> queue = QueueFactories.<T>unboundedNonBlockingQueue() .build() .withTimeout(1); Topic<T> topic = new Topic<T>(queue,QueueFactories.<T>unboundedNonBlockingQueue()); AtomicBoolean wip = new AtomicBoolean(false); Spliterator<T> split = this.spliterator(); Continuation ref[] = {null}; Continuation cont = new Continuation(()->{ if(wip.compareAndSet(false,true)){ try { //use the first consuming thread to tell this Stream onto the Queue if(!split.tryAdvance(topic::offer)){ topic.close(); return Continuation.empty(); } }finally { wip.set(false); } } return ref[0]; }); ref[0]=cont; queue.addContinuation(cont); return topic; }
@Test public void broadcastTest(){ Topic<Integer> topic = ReactiveSeq.of(1,2,3) .broadcast(); ReactiveSeq<Integer> stream1 = topic.stream(); ReactiveSeq<Integer> stream2 = topic.stream(); assertThat(stream1.toList(),equalTo(Arrays.asList(1,2,3))); assertThat(stream2.stream().toList(),equalTo(Arrays.asList(1,2,3))); } @Test
@Override public ReactiveSeq<T> stream(final Continueable s) { return connect(q -> q.stream(s)); }
@Test public void broadcastTest(){ Topic<Integer> topic = of(1,2,3) .broadcast(); ReactiveSeq<Integer> stream1 = topic.stream(); ReactiveSeq<Integer> stream2 = topic.stream(); assertThat(stream1.toList(), Matchers.equalTo(Arrays.asList(1,2,3))); assertThat(stream2.stream().toList(), Matchers.equalTo(Arrays.asList(1,2,3))); } @Test
@Override public ReactiveSeq<T> stream(final Continueable s) { return connect(q -> q.stream(s)); }