Upload
kalin-maldzhanski
View
65
Download
1
Embed Size (px)
Citation preview
Reactive Mesh
Kalin Maldzhanski
FRP
• Functional: composed of functions (not statements)
• Reactive: react on events (not pulling events)
Why we like FRP
• Nice, readable and declarative
• No callback hell, no AsyncTask
• finally easy and clean async computations on Java (it would be lovely to have those by default in JDK 9, it is anyway late :)
…,but imagine smth like this
…http://techblog.netflix.com/2013/01/announcing-ribbon-tying-netflix-mid.html
…a wish…
• Responsive
• Elastic
• Resilient
• Message Driven
Responsive: The system responds in a timely manner if at all possible. Responsiveness is the cornerstone of usability and utility, but more than that, responsiveness means that problems may be detected quickly and dealt with effectively. Responsive systems focus on providing rapid and consistent response times, establishing reliable upper bounds so they deliver a consistent quality of service. This consistent behaviour in turn simplifies error handling, builds end user confidence, and encourages further interaction.
Resilient: The system stays responsive in the face of failure. This applies not only to highly-available, mission critical systems — any system that is not resilient will be unresponsive after a failure. Resilience is achieved by replication, containment, isolation and delegation. Failures are contained within each component, isolating components from each other and thereby ensuring that parts of the system can fail and recover without compromising the system as a whole. Recovery of each component is delegated to another (external) component and high-availability is ensured by replication where necessary. The client of a component is not burdened with handling its failures.
Elastic: The system stays responsive under varying workload. Reactive Systems can react to changes in the input rate by increasing or decreasing the resources allocated to service these inputs. This implies designs that have no contention points or central bottlenecks, resulting in the ability to shard or replicate components and distribute inputs among them. Reactive Systems support predictive, as well as Reactive, scaling algorithms by providing relevant live performance measures. They achieve elasticity in a cost-effective way on commodity hardware and software platforms.
Message Driven: Reactive Systems rely on asynchronous message-passing to establish a boundary between components that ensures loose coupling, isolation and location transparency. This boundary also provides the means to delegate failures as messages. Employing explicit message-passing enables load
… a problem to solve…
• Painless communication across async boundaries
• Non blocking -> Push Model -> Cool | OOM
• Backpressure
• Interoperability, Contracts, Rules
Players• RxJava 1.x
• Agera
• RxJava 2.x
• Reactor Core
• Akka Stream
• Reactive Streams
RxJava 1.x
• Observable
• Observer
• Subscription
• Subject
Agera
• Observable
• Updatable
• Supplier
• Repository (Observable, Supplier)
• UpdateDispatcher (Observable, Updatable)
RxJava 2.x
• Observable / Flowable
• Observer / Subscriber
• Disposable / Subscription
• Subject / FlowableProcessor
Reactor Core
• Flux
• Subscriber
• Subscription
• FluxProcessor
Akka Stream
• Source
• Sink
• Flow
• Graph
• Materializer
RxJava 2.x Specific
• Maybe -> try(optional(x))
• Single -> try(x)
• Completable -> try(Nothing)
Reactor Core Specific
• Mono -> try(optional(x))
Reactive Streams
• Publisher
• Subscriber
• Subscription
• Processor
Reactive Streamspublic interface Publisher<T> { void subscribe(Subscriber<? super T> s); }
public interface Subscriber<T> { void onSubscribe(Subscription s); void onNext(T t); void onError(Throwable t); void onComplete(); }
public interface Subscription { void request(long n); void cancel(); }
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> { }
Reactive Streams
Publisher Subscriber
Subscription
Subscription
request()
subscribe()
onNext() cancel()
onSubscribe( )
Reactive Streams vs RxJava 1.x
public interface Publisher<T> { void subscribe(Subscriber<? super T> s); }
public interface Subscriber<T> { void onSubscribe(Subscription s); void onNext(T t); void onError(Throwable t); void onComplete(); }
public interface Subscription { void request(long n); void cancel(); }
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> { }
public class Observable<T> { Subscription subscribe(Subscriber<? super T> s); }
public interface Subscriber<T> { void onNext(T t); void onError(Throwable t); void onCompleted(); }
public interface Subscription { boolean isUnsubscribed(); void unsubscribe(); }
public abstract class Subject<T, R> extends Observable<R> implements Observer<T> { }
RxJava 2.x vs RxJava 1.x
public interface Flowable<T> { void subscribe(Subscriber<? super T> s); }
public interface Subscriber<T> { void onSubscribe(Subscription s); void onNext(T t); void onError(Throwable t); void onComplete(); }
public interface Subscription { void request(long n); void cancel(); }
public interface FlowableProcessor<T, R> extends Subscriber<T>, Flowable<R> { }
public class Observable<T> { Subscription subscribe(Subscriber<? super T> s); }
public interface Subscriber<T> { void onNext(T t); void onError(Throwable t); void onCompleted(); }
public interface Subscription { boolean isUnsubscribed(); void unsubscribe(); }
public abstract class Subject<T, R> extends Observable<R> implements Observer<T> { }
more in here: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0
Reactive Streams vs Agera
public interface Publisher<T> { void subscribe(Subscriber<? super T> s); }
public interface Subscriber<T> { void onSubscribe(Subscription s); void onNext(T t); void onError(Throwable t); void onComplete(); }
public interface Subscription { void request(long n); void cancel(); }
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> { }
public interface Observable { void addUpdatable(@NonNull Updatable updatable); void removeUpdatable(@NonNull Updatable updatable) }
public interface Updatable { void update(); }
public interface Supplier<T> { T get(); }
public interface Repository<T> extends Observable, Supplier<T> {}
public interface UpdateDispatcher extends Observable, Updatable {}
Interoperability
RxJava 2.x
Reactor Core
Akka Stream
Reactive StreamsRxJava
1.x
Agera
RxJavaReactiveStreams
RxJava2Interop
RxAgera
Interoperability
public abstract class RxReactiveStreams { public static <T> Publisher<T> toPublisher(Observable<T> observable) public static <T> Observable<T> toObservable(final Publisher<T> publisher) public static <T> org.reactivestreams.Subscriber<T> toSubscriber(final rx.Subscriber<T> rxSubscriber) public static <T> Publisher<T> toPublisher(Completable completable) public static Completable toCompletable(Publisher<?> publisher) public static <T> Publisher<T> toPublisher(Single<T> single) public static <T> Single<T> toSingle(Publisher<T> publisher) }
Reactive Streams RxJava 1.x
https://github.com/ReactiveX/RxJavaReactiveStreams
Interoperability
public final class RxJavaInterop { public static <T> io.reactivex.Flowable<T> toV2Flowable(rx.Observable<T> source) public static <T> io.reactivex.Observable<T> toV2Observable(rx.Observable<T> source) public static <T> io.reactivex.Maybe<T> toV2Maybe(rx.Completable source) public static <T> io.reactivex.Maybe<T> toV2Maybe(rx.Single<T> source) public static <T> io.reactivex.Single<T> toV2Single(rx.Single<T> source) public static io.reactivex.Completable toV2Completable(rx.Completable source) public static <T> rx.Observable<T> toV1Observable(org.reactivestreams.Publisher<T> source) public static <T> rx.Observable<T> toV1Observable(io.reactivex.ObservableSource<T> source, io.reactivex.BackpressureStrategy strategy) public static <T> rx.Single<T> toV1Single(io.reactivex.SingleSource<T> source) public static rx.Completable toV1Completable(io.reactivex.CompletableSource source) public static <T> rx.Single<T> toV1Single(io.reactivex.MaybeSource<T> source) public static <T> rx.Completable toV1Completable(io.reactivex.MaybeSource<T> source) }
RxJava 2.x RxJava 1.x
https://github.com/akarnokd/RxJava2Interop
Interoperability
public final class RxAgeraConverter { public static rx.Observable<Object> toRxObservable(@NonNull Observable ageraObservable) public static Observable toAgeraObservable(@NonNull rx.Observable<?> rxObservable) public static UpdateDispatcher toAgeraUpdateDispatcher(@NonNull Subject<Object, ?> rxSubject) public static Subject<Object, Object> toRxSubject(@NonNull UpdateDispatcher ageraUpdateDispatcher) }
Agera RxJava 1.x
https://github.com/akarnokd/RxAgera
Interoperability
https://medium.com/@kvnwbbr/diving-into-akka-streams-2770b3aeabb0#.z7wyeqhkw
Streams one way
Streams another way
Akka Composition RunnableGraph.fromGraph( GraphDSL.create(builder -> { final SourceShape<Integer> A = builder.add(Source.single(0)); final UniformFanOutShape<Integer, Integer> B = builder.add(Broadcast.create(2)); final UniformFanInShape<Integer, Integer> C = builder.add(Merge.create(2)); final FlowShape<Integer, Integer> D = builder.add(Flow.of(Integer.class).map(i -> i + 1)); final UniformFanOutShape<Integer, Integer> E = builder.add(Balance.create(2)); final UniformFanInShape<Integer, Integer> F = builder.add(Merge.create(2)); final SinkShape<Integer> G = builder.add(Sink.foreach(System.out::println)); builder.from(F.out()).toInlet(C.in(0)); builder.from(A).toInlet(B.in()); builder.from(B.out(0)).toInlet(C.in(1)); builder.from(C.out()).toInlet(F.in(0)); builder.from(B.out(1)).via(D).toInlet(E.in()); builder.from(E.out(0)).toInlet(F.in(1)); builder.from(E.out(1)).to(G); return ClosedShape.getInstance(); }));
Simple Flow• RxJava 1.x Observable.range(1, 100).map(i -> i + 33) .subscribe(System.out::println);
• RxJava 2.x Flowable.range(1, 100).map(i -> i + 33) .subscribe(System.out::println);
• Reactor Core Flux.range(1, 100).map(i -> i + 33)
.subscribe(System.out::println);
• Akka Stream Source.range(1, 100).map(i -> i + 33)
.runForeach(System.out::println, materializer);
Create Source RxJava 1.x
Observable.just(8); Observable.from(new Integer[]{8}); Observable.fromCallable(...); Observable.fromEmitter(...); Observable.empty(); Observable.never(); Observable.error(new IllegalStateException("why 8")); Observable.create(subscriber -> { subscriber.onNext(8); subscriber.onCompleted(); });
Observable.just(8);
Create Source RxJava 2.x
Observable.just(8); Observable.fromArray(new Integer[]{8}); Observable.fromCallable(...); Observable.fromFuture(...); Observable.fromIterable(...); Observable.fromPublisher(...); Observable.empty(); Observable.never(); Observable.error( new IllegalStateException("why 8")); Observable.create(e -> { e.setCancellable(() -> cleanMe()); e.onNext(8); e.onComplete(); });
Flowable.just(8); Flowable.fromArray(new Integer[]{8}); Flowable.fromCallable(...); Flowable.fromFuture(...); Flowable.fromIterable(...); Flowable.fromPublisher(...); Flowable.empty(); Flowable.never(); Flowable.error( new IllegalStateException("why 8")); Flowable.create(e -> { e.setCancellable(() -> cleanMe()); e.onNext(8); e.onComplete(); }, FlowableEmitter.BackpressureMode.BUFFER);
Create Source Reactor
Flux.just(8); Flux.fromArray(new Integer[]{8}); Flux.from(publisher); Flux.fromIterable(...); Flux.fromStream() Flux.empty(); Flux.never(); Flux.error(new IllegalStateException("why 8")); Flux.create(e -> { e.setCancellation(() -> cleanMe()); e.next(8); e.complete(); }, FluxSink.OverflowStrategy.BUFFER);
Backpressure
• RxJava 1.x - knows, not all respect it
• RxJava 2.x Observables - doesn’t know
• RxJava 2.x Flowables - knows
• Reactor Core - knows
• Akka Stream - knows
https://github.com/ReactiveX/RxJava/wiki/Backpressure
Fusion
Fusion Why?
• many sequences are started from constant or quasi-constant sources such as just(), from(T[]), from(Iterable), fromCallable() which don't really need the thread-safety dance in a sequence of operators,
• some pairs of operators can share internal components such as Queues and
• some operators can tell if they consumed the value or dropped it, avoiding request(1) call overhead.
http://akarnokd.blogspot.be/2016/03/operator-fusion-part-1.html
Macro Fusion
• Replacing an operator with another operator
• Replacing an operator with a custom operator
• Replacing during subscription-time
• Replacing with the same operator but with modified parameters
Micro Fusion
• Conditional Subscriber
• Synchronous-fusion
• Asynchronous-fusion
Reactive-Streams-Commons Fusion Matrix
First \ Second CombineLatest- inner ConcatMap Distinct DistinctFuseable DistinctUntilChanged Filter FilterFuseable FlatMap FlatMap -
inner FlattenIterable Map MapFuseable Merge -inner ObserveOn Peek PeekFuseable Publish SkipWhile SubscribeOn Take TakeFuseable Using -
inner Zip - inner
Aggregate Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncAll Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncAny Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async Async
Array Unfuseable Sync SyncConditional
SyncConditional Conditional Sync
ConditionalSyncConditional Unfuseable Sync Sync Sync
ConditionalSyncConditional Sync Sync Conditional Sync
Conditional Sync Conditional Unfuseable SyncConditional
SyncConditional
SyncConditional Sync
AsyncProcessor Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async Async
Callable Scalar Async Async Async Unfuseable Async Async Scalar ScalarAsync
ScalarAsync Async Async Scalar
AsyncScalarAsync Unfuseable Async Async Unfuseable Scalar Async Async Async Scalar
AsyncCallableSubscribeOn Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Unfuseable Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncCollect Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncCombineLatest Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncCompletableFuture Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncCount Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async Async
Distinct Unfuseable SyncAsync
SyncAsyncConditional
SyncAsyncConditional
ConditionalSyncAsyncConditional
SyncAsyncConditional
Unfuseable SyncAsync
SyncAsync
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
SyncAsync Conditional
SyncAsyncConditional
SyncAsync Conditional Unfuseable
SyncAsyncConditional
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
DistinctFuseable Unfuseable SyncAsync
SyncAsyncConditional
SyncAsyncConditional
ConditionalSyncAsyncConditional
SyncAsyncConditional
Unfuseable SyncAsync
SyncAsync
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
SyncAsync Conditional
SyncAsyncConditional
SyncAsync Conditional Unfuseable
SyncAsyncConditional
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
DistinctUntilChanged Unfuseable Unfuseable Conditional Conditional Conditional Conditional Conditional Unfuseable Unfuseable Unfuseable Conditional Conditional Unfuseable Unfuseable Conditional Conditional Unfuseable Conditional Unfuseable Conditional Conditional Conditional UnfuseableElementAt Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncEmpty Scalar Unfuseable Unfuseable Unfuseable Unfuseable Unfuseable Unfuseable Scalar Scalar Scalar Unfuseable Unfuseable Scalar Scalar Unfuseable Unfuseable Unfuseable Unfuseable Scalar Unfuseable Unfuseable Unfuseable Scalar
Filter Unfuseable SyncAsync
SyncAsyncConditional
SyncAsyncConditional
ConditionalSyncAsyncConditional
SyncAsyncConditional
Unfuseable SyncAsync
SyncAsync
SyncAsyncConditional
SyncAsyncConditional
SyncAsync Unfuseable Conditional
SyncAsyncConditional
SyncAsync Conditional Unfuseable
SyncAsyncConditional
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
FilterFuseable Unfuseable SyncAsync
SyncAsyncConditional
SyncAsyncConditional
ConditionalSyncAsyncConditional
SyncAsyncConditional
Unfuseable SyncAsync
SyncAsync
SyncAsyncConditional
SyncAsyncConditional
SyncAsync Unfuseable Conditional
SyncAsyncConditional
SyncAsync Conditional Unfuseable
SyncAsyncConditional
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
FlattenIterable Unfuseable Sync Sync Sync Unfuseable Sync Sync Unfuseable Sync Sync Sync Sync Sync Sync Unfuseable Sync Sync Unfuseable Unfuseable Sync Sync Sync SyncFuture Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncGenerate Unfuseable Sync Sync Sync Unfuseable Sync Sync Unfuseable Sync Sync Sync Sync Sync Unfuseable Unfuseable Sync Sync Unfuseable Unfuseable Sync Sync Sync SyncGroupBy Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncGroupBy - inner Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncHasElements Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async Async
Iterable Unfuseable Sync SyncConditional
SyncConditional Conditional Sync
ConditionalSyncConditional Unfuseable Sync Sync Sync
ConditionalSyncConditional Sync Sync Conditional Sync
Conditional Sync Conditional Unfuseable SyncConditional
SyncConditional
SyncConditional Sync
Just Scalar Sync Sync Sync Unfuseable Sync Sync Scalar ScalarSync
ScalarSync Sync Sync Scalar
SyncScalarSync Unfuseable Sync Sync Unfuseable Scalar Sync Sync Sync Scalar
Sync
Map Unfuseable SyncAsync
SyncAsyncConditional
SyncAsyncConditional
ConditionalSyncAsyncConditional
SyncAsyncConditional
Unfuseable SyncAsync
SyncAsync
SyncAsyncConditional
SyncAsyncConditional
SyncAsync Unfuseable Conditional
SyncAsyncConditional
SyncAsync Conditional Unfuseable
SyncAsyncConditional
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
MapFuseable Unfuseable SyncAsync
SyncAsyncConditional
SyncAsyncConditional
ConditionalSyncAsyncConditional
SyncAsyncConditional
Unfuseable SyncAsync
SyncAsync
SyncAsyncConditional
SyncAsyncConditional
SyncAsync Unfuseable Conditional
SyncAsyncConditional
SyncAsync Conditional Unfuseable
SyncAsyncConditional
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
ObserveOn Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncPeek Unfuseable Unfuseable Conditional Conditional Conditional Conditional Conditional Unfuseable Unfuseable Unfuseable Conditional Conditional Unfuseable Unfuseable Conditional Conditional Unfuseable Conditional Unfuseable Conditional Conditional Conditional Unfuseable
PeekFuseable Unfuseable SyncAsync
SyncAsyncConditional
SyncAsyncConditional
ConditionalSyncAsyncConditional
SyncAsyncConditional
Unfuseable SyncAsync
SyncAsync
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
SyncAsync Conditional
SyncAsyncConditional
SyncAsync Conditional Unfuseable
SyncAsyncConditional
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
Publish Unfuseable SyncAsync
SyncAsync
SyncAsync Unfuseable Sync
AsyncSyncAsync Unfuseable Sync
AsyncSyncAsync
SyncAsync
SyncAsync
SyncAsync
SyncAsync Unfuseable Sync
AsyncSyncAsync Unfuseable Unfuseable Sync
AsyncSyncAsync
SyncAsync
SyncAsync
Range Unfuseable Sync SyncConditional
SyncConditional Conditional Sync
ConditionalSyncConditional Unfuseable Sync Sync Sync
ConditionalSyncConditional Sync Sync Conditional Sync
Conditional Sync Conditional Unfuseable SyncConditional
SyncConditional
SyncConditional Sync
Reduce Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncReplayProcessor Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncSingle Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncSkipWhile Unfuseable Unfuseable Conditional Conditional Conditional Conditional Conditional Unfuseable Unfuseable Unfuseable Conditional Conditional Unfuseable Unfuseable Conditional Conditional Unfuseable Conditional Unfuseable Conditional Conditional Conditional Unfuseable
Stream Unfuseable Sync SyncConditional
SyncConditional Conditional Sync
ConditionalSyncConditional Unfuseable Sync Sync Sync
ConditionalSyncConditional Sync Sync Conditional Sync
Conditional Sync Conditional Unfuseable SyncConditional
SyncConditional
SyncConditional Sync
StreamCollector Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncSubscribeOn Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncSubscribeOnValue Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async Async
Take Unfuseable SyncAsync
SyncAsyncConditional
SyncAsyncConditional
ConditionalSyncAsyncConditional
SyncAsyncConditional
Unfuseable SyncAsync
SyncAsync
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
SyncAsync Conditional
SyncAsyncConditional
SyncAsync Conditional Unfuseable
SyncAsyncConditional
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
TakeFuseable Unfuseable SyncAsync
SyncAsyncConditional
SyncAsyncConditional
ConditionalSyncAsyncConditional
SyncAsyncConditional
Unfuseable SyncAsync
SyncAsync
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
SyncAsync Conditional
SyncAsyncConditional
SyncAsync Conditional Unfuseable
SyncAsyncConditional
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
TakeLast Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncTakeLastOne Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncUnicastProcessor Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async Async
Using Unfuseable SyncAsync
SyncAsyncConditional
SyncAsyncConditional
ConditionalSyncAsyncConditional
SyncAsyncConditional
Unfuseable SyncAsync
SyncAsync
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
SyncAsync Conditional
SyncAsyncConditional
SyncAsync Conditional Unfuseable
SyncAsyncConditional
SyncAsyncConditional
SyncAsyncConditional
SyncAsync
Window - inner Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async AsyncWindowBatch - inner Unfuseable Async Async Async Unfuseable Async Async Unfuseable Async Async Async Async Async Async Unfuseable Async Async Unfuseable Unfuseable Async Async Async Async
Reactive-Streams-Commons Fusion Matrix https://rawgit.com/reactor/reactive-streams-commons/master/f...
1 of 1 23/10/16 12:27
https://rawgit.com/reactor/reactive-streams-commons/master/fusion-matrix.html
The beginning https://channel9.msdn.com/Shows/Going+Deep/Expert-to-Expert-Brian-Beckman-and-Erik-Meijer-Inside-the-NET-Reactive-Framework-Rx
RxJava https://github.com/ReactiveX/RxJava
Agera
https://github.com/google/agera
Reactor Core https://github.com/reactor/reactor-core
Akka Stream
https://github.com/akka/akka/tree/master/akka-stream
Reactive Streams Specification for the JVM http://www.reactive-streams.org/ https://github.com/reactive-streams/reactive-streams-jvm
Official modules for the Reactor project
https://github.com/reactor/reactor-addons
Utilities for use with rxjava https://github.com/davidmoten/rxjava-extras
A joint research effort for building highly optimized Reactive-Streams compliant operators.
https://github.com/reactor/reactive-streams-commons
Adapter between RxJava and ReactiveStreams https://github.com/ReactiveX/RxJavaReactiveStreams
Library to convert between RxJava 1.x and 2.x reactive types.
https://github.com/akarnokd/RxJava2Interop
Extra sources, operators and components and ports of many 1.x companion libraries for RxJava 2.x. https://github.com/akarnokd/RxJava2Extensions
Convert between RxJava and Agera reactive base types
https://github.com/akarnokd/RxAgera
“Go with the Flow(able).”