static <T> ReactiveSeq<T> schedule(final Stream<T> stream,final String cron,final ScheduledExecutorService exec) { ReactiveSubscriber<T> sub = reactiveSubscriber(); AtomicBoolean isOpen = new AtomicBoolean(true); Subscription[] s= {null}; sub.onSubscribe(new Subscription() { @Override public void request(long n) { s[0].request(n); } @Override public void cancel() { isOpen.set(false); } }); s[0] = ReactiveSeq.fromStream(stream) .takeWhile(e -> isOpen.get()) .schedule(cron, exec) .connect() .forEach(0, e -> sub.onNext(e),t->sub.onError(t),()->sub.onComplete()); return sub.reactiveStream(); }
static <T> ReactiveSeq<T> reactive(Consumer<? super Subscriber<T>> sub){ ReactiveSubscriber<T> reactive = new ReactiveSubscriber<T>(); sub.accept(reactive); return reactive.reactiveStream(); } static <T> ReactiveSeq<T> reactiveStream(Operator<T> s){
static ReactiveSeq<Integer> interval(String cron,ScheduledExecutorService exec) { ReactiveSubscriber<Integer> sub = reactiveSubscriber(); AtomicBoolean isOpen = new AtomicBoolean(true); Subscription[] s= {null}; sub.onSubscribe(new Subscription() { @Override public void request(long n) { s[0].request(n); } @Override public void cancel() { isOpen.set(false); } }); s[0] = ReactiveSeq.iterate(1, a -> a + 1) .takeWhile(e -> isOpen.get()) .schedule(cron, exec) .connect() .forEach(1, e -> sub.onNext(e)); return sub.reactiveStream(); } static ReactiveSeq<Integer> interval(final long millis,ScheduledExecutorService exec) {
@Test public void testFlatMapOrdering(){ ReactiveSubscriber<String> pushable = Spouts.reactiveSubscriber(); pushable.onComplete(); pushable.onNext("hello"); ReactiveSeq<String> stream = pushable.reactiveStream(); stream.map(s->s.length()) .flatMap(s-> IntStream.range(0,s).boxed()) .forEach(System.out::println); pushable.onNext("world"); }
/** @Test @Ignore public void limitPushTest(){ ReactiveSubscriber<String> pushable = ReactiveSeq.pushable(); ReactiveSeq<String> stream = pushable.stream(); ReactiveSeq<List<String>> res = stream.map(i->i+"-hello").limit(2) .collectSeq(CyclopsCollectors.toList()); pushable.onNext("hello1"); pushable.onNext("hello2"); pushable.onNext("hello3"); //LimitSpliterator only supports iteration assertThat(res.single().size(),equalTo(3)); } **/ @Test public void forEachWithErrorPush(){ ReactiveSubscriber<String> pushable = Spouts.reactiveSubscriber(); ReactiveSeq<String> stream = pushable.reactiveStream(); // pushable.onComplete(); stream.map(i->i+"-hello").limit(2) .forEach(System.out::println, s->System.out.println("Error" + s)); pushable.onNext("hello1"); pushable.onError(new RuntimeException()); } @Test @Ignore
@Test @Ignore public void blockToList(){ ReactiveSubscriber<String> pushable = Spouts.reactiveSubscriber(); ReactiveSeq<String> stream = pushable.reactiveStream(); new Thread(()->{active.set(false); pushable.onComplete();}).run(); stream.toList(); assertFalse(active.get()); }
@Test public void flatMapAsyncRS2(){ for(int k=0;k<1000;k++) { System.out.println("********0---------------------K " + k); ReactiveSubscriber<Integer> sub = Spouts.reactiveSubscriber(); Spouts.of(1, 2, 3).peek(System.out::println) .concatMap(i -> nextAsyncRS()) // .flatMapP(i->Spouts.of(1,2)) .subscribe(sub); List<Integer> res = sub.reactiveStream().collect(Collectors.toList()); System.out.println(res); assertThat(res.size(), equalTo(Arrays.asList(1, 2, 1, 2, 1, 2).size())); assertThat(res, hasItems(1, 2)); int one = 0; int two = 0; for (Integer next : res) { if (next == 1) { one++; } if (next == 2) { two++; } } assertThat(one, equalTo(3)); assertThat(two, equalTo(3)); } } @Test
@Test public void init(){ ReactiveSubscriber<Integer> sub = Spouts.reactiveSubscriber(); Flux.just(1,2,3).subscribe(sub); sub.reactiveStream().forEach(System.out::println); assertTrue(sub.isInitialized()); } }
/** * The recommended way to connect a Spout to a Publisher is via Spouts#from * Create an Subscriber for Observable style asynchronous push based Streams, * that implements backpressure internally via the reactive-streams spec. * * Subscribers signal demand via their subscription and publishers push data to subscribers * synchronously or asynchronously, never exceeding signalled demand * * @param <T> Stream data type * @return An async Stream Subscriber that supports efficient backpressure via reactive-streams */ static <T> ReactiveSubscriber<T> reactiveSubscriber(){ return new ReactiveSubscriber<T>(); }
@Test public void forEachWithError(){ ReactiveSubscriber<String> pushable = Spouts.reactiveSubscriber(); ReactiveSeq<String> stream = pushable.reactiveStream(); pushable.onNext("hello"); pushable.onComplete(); stream.map(s->s.length()) .flatMap(s-> IntStream.range(0,s).boxed()) .forEach(System.out::println,System.err::println); pushable.onNext("world"); }
static ReactiveSeq<Integer> interval(final long millis,ScheduledExecutorService exec) { ReactiveSubscriber<Integer> sub = reactiveSubscriber(); AtomicBoolean isOpen = new AtomicBoolean(true); Subscription[] s= {null}; sub.onSubscribe(new Subscription() { @Override public void request(long n) { s[0].request(n); } @Override public void cancel() { isOpen.set(false); } }); s[0] = ReactiveSeq.iterate(1, a -> a + 1) .takeWhile(e -> isOpen.get()) .scheduleFixedDelay(millis, exec) .connect() .forEach(1, e -> sub.onNext(e)); return sub.reactiveStream(); } static <T> ReactiveSeq<T> schedule(final Stream<T> stream,final String cron,final ScheduledExecutorService exec) {
@Test @Ignore public void block(){ ReactiveSubscriber<String> pushable = Spouts.reactiveSubscriber(); ReactiveSeq<String> stream = pushable.reactiveStream(); new Thread(()->{active.set(false); pushable.onComplete();}).run(); stream.forEach(System.out::println); assertFalse(active.get()); } @Test @Ignore
@Test public void flatMapAsyncRS2(){ for(int k=0;k<1000;k++) { System.out.println("********0---------------------K " + k); ReactiveSubscriber<Integer> sub = Spouts.reactiveSubscriber(); Spouts.of(1, 2, 3).peek(System.out::println) .concatMap(i -> nextAsyncRS()) // .flatMapP(i->Spouts.of(1,2)) .subscribe(sub); List<Integer> res = sub.reactiveStream().collect(Collectors.toList()); System.out.println(res); assertThat(res.size(), equalTo(Arrays.asList(1, 2, 1, 2, 1, 2).size())); assertThat(res, hasItems(1, 2)); int one = 0; int two = 0; for (Integer next : res) { if (next == 1) { one++; } if (next == 2) { two++; } } assertThat(one, equalTo(3)); assertThat(two, equalTo(3)); } } @Test
/** * The recommended way to connect a Spout to a Publisher is via Spouts#from * Create an Subscriber for Observable style asynchronous push based Streams, * that implements backpressure internally via the reactive-streams spec. * * Subscribers signal demand via their subscription and publishers push data to subscribers * synchronously or asynchronously, never exceeding signalled demand * * @param <T> Stream data type * @return An async Stream Subscriber that supports efficient backpressure via reactive-streams */ static <T> ReactiveSubscriber<T> reactiveSubscriber(){ return new ReactiveSubscriber<T>(); }
private ReactiveSeq<Integer> nextAsyncRS() { ReactiveSubscriber<Integer> sub = Spouts.reactiveSubscriber(); AtomicLong req = new AtomicLong(0); int id = start.incrementAndGet(); sub.onSubscribe(new Subscription() { @Override public void request(long n) { req.addAndGet(n); } @Override public void cancel() { } public String toString(){ return "subscription " + id; } }); new Thread(()->{ int sent=0; while(sent<2){ if(req.get()>0){ sub.onNext( ++sent); req.decrementAndGet(); } } sub.onComplete(); // Flux.just(1,2).forEachAsync(sub); }).start(); return sub.reactiveStream(); } private ReactiveSeq<Integer> nextAsync() {
@Test public void testFlatMap(){ ReactiveSubscriber<String> pushable = Spouts.reactiveSubscriber(); pushable.onNext("hello"); pushable.onComplete(); ReactiveSeq<String> stream = pushable.reactiveStream(); stream.map(s->s.length()) .flatMap(s-> IntStream.range(0,s).boxed()) .forEach(System.out::println); pushable.onNext("world"); } @Test
static ReactiveSeq<Integer> interval(String cron,ScheduledExecutorService exec) { ReactiveSubscriber<Integer> sub = reactiveSubscriber(); AtomicBoolean isOpen = new AtomicBoolean(true); Subscription[] s= {null}; sub.onSubscribe(new Subscription() { @Override public void request(long n) { s[0].request(n); } @Override public void cancel() { isOpen.set(false); } }); s[0] = ReactiveSeq.iterate(1, a -> a + 1) .takeWhile(e -> isOpen.get()) .schedule(cron, exec) .connect() .forEach(1, e -> sub.onNext(e)); return sub.reactiveStream(); } static ReactiveSeq<Integer> interval(final long millis,ScheduledExecutorService exec) {
@Test public void flatMapAsyncRS2(){ for(int k=0;k<1000;k++) { System.out.println("********0---------------------K " + k); ReactiveSubscriber<Integer> sub = Spouts.reactiveSubscriber(); Spouts.of(1, 2, 3).peek(System.out::println) .flatMap(i -> nextAsyncRS()) // .flatMapP(i->Spouts.of(1,2)) .subscribe(sub); List<Integer> res = sub.reactiveStream().collect(Collectors.toList()); System.out.println(res); assertThat(res.size(), equalTo(Arrays.asList(1, 2, 1, 2, 1, 2).size())); assertThat(res, hasItems(1, 2)); int one = 0; int two = 0; for (Integer next : res) { if (next == 1) { one++; } if (next == 2) { two++; } } assertThat(one, equalTo(3)); assertThat(two, equalTo(3)); } } @Test
static <T> ReactiveSeq<T> reactive(Consumer<? super Subscriber<T>> sub){ ReactiveSubscriber<T> reactive = new ReactiveSubscriber<T>(); sub.accept(reactive); return reactive.reactiveStream(); } static <T> ReactiveSeq<T> reactiveStream(Operator<T> s){